#include<bits/stdc++.h>
/*
*/

using namespace std;

// 辺を表す構造体 (行き先、容量、逆辺)
struct edge { int to, cap, rev; };
vector<edge> G[2000]; // グラフの隣接リスト表現
bool used[2000]; // DFSですでに調べたかのフラグ
				  // fromからtoへ向かう容量capの辺をグラフに追加する
void add_edge( int from, int to, int cap ) {
	edge a, b;
	a.to = to;
	a.cap = cap;
	a.rev = G[to].size();
	G[from].push_back( a );
	b.to = from;
	b.cap = cap;
	b.rev = G[from].size() - 1;
	G[to].push_back( b );
}
// 増加パスをDFSで探す
int dfs( int v, int t, int f ) {
	if( v == t ) return f;
	used[v] = true;
	for( int i = 0; i < G[v].size(); i++ ) {
		edge &e = G[v][i];
		if( !used[e.to] && e.cap > 0 ) {
			int d = dfs( e.to, t, min( f, e.cap ) );
			if( d > 0 ) {
				e.cap -= d;
				G[e.to][e.rev].cap += d;
				return d;
			}
		}
	}
	return 0;
}
// sからtへの最大流を求める
int max_flow( int s, int t ) {
	int flow = 0;
	for( ;;) {
		memset( used, 0, sizeof( used ) );
		int f = dfs( s, t, INT_MAX / 6 );
		if( f == 0 ) return flow;
		flow += f;
	}
}

int main() {
	int H, W;
	cin >> H >> W;
	vector<string>S( H );
	int start, goal;
	for( size_t i = 0; i < H; i++ ) {
		cin >> S[i];
		for( size_t j = 0; j < W; j++ ) {
			if( S[i][j] != '.' ) {
				add_edge( i + W, j, 1 );
				if( S[i][j] == 'S' ) {
					start = i*W + j;
					add_edge( H + W + 1, i + W, 1000 );
					add_edge( H + W + 1, j, 10000 );
				} else if( S[i][j] == 'T' ) {
					goal = i*W + j;
					add_edge( H + W + 2, i + W, 1000 );
					add_edge( H + W + 2, j, 1000 );
				}
			}
		}
	}
	if( start / W == goal / W || start%W == goal%W ) {
		cout << -1 << endl;
		return 0;
	}
	cout << max_flow( H + W + 1, H + W + 2 ) << endl;
}