// eddy1021
#pragma GCC optimize("O3")
#include <bits/stdc++.h>
using namespace std;
typedef double D;
typedef long double LD;
typedef long long LL;
typedef pair<int,int> PII;
typedef pair<LL,LL> PLL;
#define mod9 1000000009LL
#define mod7 1000000007LL
#define INF16 10000000000000000LL
#define eps 1e-9
//#define SZ(x) (int)(x).size()
#define ALL(x) (x).begin(), (x).end()
#ifndef ONLINE_JUDGE
#define debug(...) printf(__VA_ARGS__)
#else 
#define debug(...)
#endif
inline LL getint(){
  LL _x=0,_tmp=1; char _tc=getchar();    
  while( (_tc<'0'||_tc>'9')&&_tc!='-' ) _tc=getchar();
  if( _tc == '-' ) _tc=getchar() , _tmp = -1;
  while(_tc>='0'&&_tc<='9') _x*=10,_x+=(_tc-'0'),_tc=getchar();
  return _x*_tmp;
}
inline LL add( LL _x , LL _y , LL _mod = mod7 ){
  _x += _y;
  return _x >= _mod ? _x - _mod : _x;
}
inline LL sub( LL _x , LL _y , LL _mod = mod7 ){
  _x -= _y;
  return _x < 0 ? _x + _mod : _x;
}
inline LL mul( LL _x , LL _y , LL _mod = mod7 ){
  _x *= _y;
  return _x >= _mod ? _x % _mod : _x;
}
LL mypow( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 1LL;
  LL _ret = mypow( mul( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = mul( _ret , _a , _mod );
  return _ret;
}
LL mymul( LL _a , LL _x , LL _mod ){
  if( _x == 0 ) return 0LL;
  LL _ret = mymul( add( _a , _a , _mod ) , _x >> 1 , _mod );
  if( _x & 1 ) _ret = add( _ret , _a , _mod );
  return _ret;
}
inline bool equal( D _x ,  D _y ){
  return _x > _y - eps && _x < _y + eps;
}
#define Bye exit(0)
int __ = 1 , _cs;
/*********default*********/
#define N 111
#define SZ(c) ((int)(c).size())
static const int INF  = 1000000;
struct Maxflow {
  static const int MAXV = 40010;
  struct Edge {
    int v, c, r;
    Edge(int _v, int _c, int _r):
      v(_v), c(_c), r(_r) {}
  };
  int s, t;
  vector<Edge> G[MAXV*2];
  int iter[MAXV*2], d[MAXV*2], gap[MAXV*2], tot;
  void init(int x) {
    tot = x+2;
    s = x+1, t = x+2;
    for(int i = 0; i <= tot; i++) {
      G[i].clear();
      iter[i] = d[i] = gap[i] = 0;
    }
  }
  void addEdge(int u, int v, int c) {
    G[u].push_back(Edge(v, c, SZ(G[v]) ));
    G[v].push_back(Edge(u, 0, SZ(G[u]) - 1));
  }
  int dfs(int p, int flow) {
    if(p == t) return flow;
    for(int &i = iter[p]; i < SZ(G[p]); i++) {
      Edge &e = G[p][i];
      if(e.c > 0 && d[p] == d[e.v]+1) {
        int f = dfs(e.v, min(flow, e.c));
        if(f) {
          e.c -= f;
          G[e.v][e.r].c += f;
          return f;
        }
      }
    }
    if( (--gap[d[p]]) == 0) d[s] = tot;
    else {
      d[p]++;
      iter[p] = 0;
      ++gap[d[p]];
    }
    return 0;
  }
  int solve() {
    //puts("MF");
    int res = 0;
    gap[0] = tot;
    for(res = 0; d[s] < tot; res += dfs(s, INF));
    return res;
  }
} flow;
#define tm fkjkl
void build(){

}
int n , m , id[ N ][ N ] , iid;
char c[ N ][ N ];
int sn , sm , tn , tm;
void init(){
  n = getint();
  m = getint();
  //n = m = 100;
  for( int i = 0 ; i < n ; i ++ ){
    scanf( "%s" , c[ i ] );
    //for( int j = 0 ; j < m ; j ++ ){
      //if( i == 0 and j == 0 ) c[ i ][ j ] = 'S';
      //else if( i == n - 1 and j == m - 1 ) c[ i ][ j ] = 'T';
      //else c[ i ][ j ] = 'o';
    //}
    for( int j = 0 ; j < m ; j ++ ){
      if( c[ i ][ j ] == '.' )
        continue;
      id[ i ][ j ] = iid ++;
      if( c[ i ][ j ] == 'S' )
        sn = i, sm = j;
      if( c[ i ][ j ] == 'T' )
        tn = i, tm = j;
    }
  }
}
void solve(){
  if( sn == tn or sm == tm ){
    puts( "-1" );
    Bye;
  }
  flow.init( iid * 2 );
  flow.addEdge( flow.s , id[ sn ][ sm ] * 2 , INF );
  flow.addEdge( id[ tn ][ tm ] * 2 + 1 , flow.t , INF );
  for( int i = 0 ; i < n ; i ++ )
    for( int j = 0 ; j < m ; j ++ ){
      if( c[ i ][ j ] == '.' ) continue;
      if( id[ i ][ j ] == id[ sn ][ sm ] or
          id[ i ][ j ] == id[ tn ][ tm ] )
        flow.addEdge( id[ i ][ j ] * 2 , 
                      id[ i ][ j ] * 2 + 1 , INF );
      else
        flow.addEdge( id[ i ][ j ] * 2 , 
                      id[ i ][ j ] * 2 + 1 , 1 );
      for( int jj = j + 1 ; jj < m ; jj ++ ){
        if( c[ i ][ jj ] == '.' ) continue;
        int id1 = id[ i ][ j ];
        int id2 = id[ i ][ jj ];
        flow.addEdge( id1 * 2 + 1 , id2 * 2 , INF );
        flow.addEdge( id2 * 2 + 1 , id1 * 2 , INF );
      }
    }
  for( int j = 0 ; j < m ; j ++ )
    for( int i = 0 ; i < n ; i ++ ){
      if( c[ i ][ j ] == '.' ) continue;
      for( int ii = i + 1 ; ii < n ; ii ++ ){
        if( c[ ii ][ j ] == '.' ) continue;
        int id1 = id[ i ][ j ];
        int id2 = id[ ii ][ j ];
        flow.addEdge( id1 * 2 + 1 , id2 * 2 , INF );
        flow.addEdge( id2 * 2 + 1 , id1 * 2 , INF );
      }
    }
  printf( "%d\n" , flow.solve() );
}
int main(){
  build();
  //__ = getint();
  while( __ -- ){
    init();
    solve();
  }
}


Measured memory_bytes: 63232