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

#define int long long
#define rep(i,l,r) for(int i=(int)(l);i<(int)(r);i++)
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)x.size())
template<class T>bool chmax(T &a,T b){if(a<b){a=b;return 1;}return 0;}
template<class T>bool chmin(T &a,T b){if(a>b){a=b;return 1;}return 0;}

typedef vector<int> vi;
typedef vector<vi> vvi;

/*{
  }*/

const int inf = 1LL<<60;

struct edge{
  int to, rev, cap;
  edge(int t, int r, int c) : to(t), rev(r), cap(c){}
};

vector<edge> es[10010];
bool vis[10010];

void add_edge(int from, int to, int cap){
  es[from].emplace_back(to, sz(es[to]), cap);
  es[to].emplace_back(from, sz(es[from])-1, cap);
}

int dfs(int v, int t, int f){
  if(v == t) return f;
  vis[v] = true;
  for(auto &e : es[v]){
    if(vis[e.to] or e.cap <= 0) continue;
    int d = dfs(e.to, t, min(f, e.cap));
    if(d > 0){
      e.cap -= d;
      es[e.to][e.rev].cap += d;
      return d;
    }
  }
  return 0;
}

int max_flow(int s, int t){
  int flow = 0;
  while(1){
    memset(vis, false, sizeof(vis));
    int f = dfs(s, t, inf);
    if(f == 0) return flow;
    flow += f;
  }
}

signed main(){
  int H, W;
  cin >> H >> W;

  vector<string> s(H);
  rep(i, 0, H) cin >> s[i];

  int S = 0, T = 1;
  auto node_y = [&](int y){ return 2+y; };
  auto node_x = [&](int x){ return 2+H+x; };

  rep(i, 0, H) rep(j, 0, W){
    if(s[i][j] == 'S'){
      add_edge(S, node_y(i), inf);
      add_edge(S, node_x(j), inf);
    }else if(s[i][j] == 'T'){
      add_edge(T, node_y(i), inf);
      add_edge(T, node_x(j), inf);
    }else if(s[i][j] == 'o'){
      add_edge(node_x(j), node_y(i), 1);
    }
  }

  int ans = max_flow(S, T);
  if(ans >= inf) cout << -1 << endl;
  else cout << ans << endl;

  return 0;
}

