#include<bits/stdc++.h>
using namespace std;
using ll = long long;

/// --- Dinic Libary {{{ ///
// solve max flow

struct Dinic {
  struct Edge {
    int from, to; ll cap, rev;
    int To(int i) { return from == i ? to : from; }
    ll& Cap(int i) { return from == i ? cap : rev; }
    ll& Rev(int i) { return from == i ? rev : cap; }
  };

  int n;
  vector< Edge > edges;
  vector< vector< int > > g;
  ll inf;
  Dinic(int n, ll inf = 1e18): n(n), g(n), inf(inf) {}

  void addEdge(int a, int b, ll cap, int i = -1, bool undirected = false) {
    if(i == -1) i = edges.size();
    edges.resize(max(i + 1, (int) edges.size()));
    edges[i] = (Edge) {a, b, cap, undirected ? cap : 0};
    g[a].emplace_back(i);
    g[b].emplace_back(i);
  }

  ll solve(int s, int t) {
    vector<int> level(n);
    ll flow = 0;
    while(bfs(s, level), level[t] > 0) {
      ll newflow = dfs(s, t, inf, level);
      if(newflow == 0) break;
      flow += newflow;
      if(flow >= inf) return inf;
    }
    return flow;
  }

  private:
  void bfs(int s, vector<int> & level) {
    fill(begin(level), end(level), -1);
    queue<int> q;
    q.emplace(s);
    level[s] = 0;
    while(q.size()) {
      int i = q.front(); q.pop();
      for(int idx : g[i]) {
        Edge edge = edges[idx];
        if(level[edge.To(i)] == -1 && edge.Cap(i) > 0) {
          level[edge.To(i)] = level[i] + 1;
          q.push(edge.To(i));
        }
      }
    }
  }

  ll dfs(int i, int t, ll flow, vector<int> const & level) {
    if(i == t) return flow;
    for(int idx : g[i]) {
      Edge &edge = edges[idx];
      if(edge.Cap(i) > 0 && level[edge.To(i)] > level[i]) {
        ll newflow = dfs(edge.To(i), t, min(flow, edge.Cap(i)), level);
        if(newflow == 0) continue;
        edge.Cap(i) -= newflow;
        edge.Rev(i) += newflow;
        return newflow;
      }
    }
    return 0;
  }
};

/// ---}}} ///

/// --- Max Flow with FordFulkerson Library {{{ ///

// Ford-Fulkerson
// O(FV)
struct Ford {
  struct Edge {
    int from, to; ll cap, rev;
    int To(int i) { return from == i ? to : from; }
    ll& Cap(int i) { return from == i ? cap : rev; }
    ll& Rev(int i) { return from == i ? rev : cap; }
  };
  int n;
  vector< Edge > edges;
  vector< vector< int > > g;
  ll inf;
  Ford(int n, ll inf = 1e18): n(n), g(n), inf(inf) {}

  void addEdge(int a, int b, ll cap, int i = -1, bool undirected = false) {
    if(i == -1) i = edges.size();
    edges.resize(max(i + 1, (int) edges.size()));
    edges[i] = (Edge) {a, b, cap, undirected ? cap : 0};
    g[a].emplace_back(i);
    g[b].emplace_back(i);
  }

  ll solve(int s, int t) {
    ll flow = 0;
    while(1) {
      vector<int> used(n, 0);
      ll x = dfs(used, s, t, inf);
      if(x == 0) break;
      flow += x;
      if(flow >= inf) return inf;
    }
    return flow;
  }

  private:
  ll dfs(vector<int> &used, int i, int t, ll x) {
    if(i == t) return x;
    used[i] = 1;
    for(int idx : g[i]) if(!used[edges[idx].To(i)] && edges[idx].Cap(i) > 0) {
      Edge &edge = edges[idx];
      ll d = dfs(used, edge.To(i), t, min(x, edge.Cap(i)));
      if(d == 0) continue; ////
      edge.Cap(i) -= d;
      edge.Rev(i) += d;
      return d;
    }
    return 0;
  }
};

/// ---}}} ///

// const int N = 2e6;
// Ford flow(N, 1e18);

#define REP(i, n) for(int i = 0; i < n; i++)

const ll inf = 1e18;

int main() {
  int h, w; cin >> h >> w;
  int n=h+w+2;
  Dinic ecasd(n, inf);
  Ford qina(n, inf);
  int s, t;
  REP(y, h) {
    string str; cin >> str;
    REP(x, w) {
      switch(str[x]) {
        case 'o':
          ecasd.addEdge(y, h + x, 1, -1, true);
          qina.addEdge(y, h + x, 1, -1, true);
          break;
        case 'S':
          s = y;
          ecasd.addEdge(y, h + x, inf, -1, true);
          qina.addEdge(y, h + x, inf, -1, true);
          break;
        case 'T':
          t = y;
          ecasd.addEdge(y, h + x, inf, -1, true);
          qina.addEdge(y, h + x, inf, -1, true);
          break;
        default:
        case '.':
          break;
      }
    }
  }
  if(s == t) {
    cout << -1 << endl;
    return 0;
  }
  ll res0 = ecasd.solve(s, t);
  ll res1 = qina.solve(s, t);
  if(res0 == inf) res0 = -1;
  if(res1 == inf) res1 = -1;
  assert(res0 == res1);
  cout << res0 << endl;
}



Measured memory_bytes: 1124