#include <stdio.h>
#include <algorithm>
#include <assert.h>
#include <bitset>
#include <cmath>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits.h>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stdlib.h>
#include <string.h>
#include <string>
#include <time.h>
#include <unordered_map>
#include <unordered_set>
#include <vector>

#pragma warning(disable:4996)
#pragma comment(linker, "/STACK:336777216")
using namespace std;

#define mp make_pair
#define all(x) (x).begin(), (x).end()
#define ldb ldouble

typedef tuple<int, int, int> t3;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef long double ldb;
typedef pair <int, int> pii;
typedef pair <ll, ll> pll;
typedef pair <ll, int> pli;
typedef pair <db, db> pdd;

int IT_MAX = 1 << 18;
int MOD = 1000000007;
const int INF = 0x3f3f3f3f;
const ll LL_INF = 0x3f3f3f3f3f3f3f3f;
const db PI = acos(-1);
const db ERR = 1e-10;
#define szz(x) (int)(x).size()
#define rep(i, n) for(int i=0;i<n;i++)
#define Se second
#define Fi first

const int MX = 400005;
const int MM = 1000000007;

class Maxflow{
	public:
		struct Edge{
			int e, c, f; 
			Edge(){}
			Edge(int e, int c, int f):e(e), c(c), f(f){}
		};
		static const int MAXE = 500005;
		static const int MAXV = 500005;
		vector<int> G[MAXV];
		Edge E[MAXE*2];
		int dist[MAXV], cur[MAXV];
		int sz = 0;

		void clear(int N){
			for(int i = 0; i <= N; i++) G[i].clear();
			sz = 0;
		}

		void add(int s, int e, int c){
			E[sz] = Edge(e, c, 0); G[s].push_back(sz); sz++;
			E[sz] = Edge(s, c, c); G[e].push_back(sz); sz++;
		}

		int BFS(int s, int e, int N){
			for(int i = 0; i <= N; i++) dist[i] = 0;
			queue<int> Q;
			Q.push(s); dist[s] = 1;
			while(Q.size()){
				int p = Q.front(); Q.pop();
				for(int cc : G[p]){
					Edge c = E[cc];
					if( c.c > c.f && dist[c.e] == 0 ){
						dist[c.e] = dist[p] + 1;
						Q.push(c.e);
					}
				}
			}
			return dist[e];
		}

		int dfs(int s, int e, int f){
			if( s == e ) return f;
			for(; cur[s] < G[s].size(); cur[s]++){
				int d = G[s][cur[s]];
				Edge c = E[d];
				if( c.c > c.f && dist[c.e] == dist[s] + 1){
					int t = dfs(c.e, e, min(f, c.c - c.f));
					if( t ){
						E[d].f += t;
						E[d^1].f -= t;
						return t;
					}
				}
			}
			return 0;
		}

		int run(int s, int e, int N){
			int ans = 0, c;
			while(BFS(s, e, N) != 0){
				for(int i = 0; i <= N; i++) cur[i] = 0;
				while((c = dfs(s, e, 1e9)) != 0) ans += c;
			}
			return ans;
		}
}flow;

int N, M;
vector<pii> P;

int hsh(int x, int y){ return x*(M+1)+y; }
char D[105][105];

int main()
{
	int S, E;
	scanf("%d%d", &N, &M);
	for(int i = 0; i < N; i++) scanf("%s", D[i]);
	for(int i = 0; i < N; i++){
		for(int j = 0; j < M; j++){
			int v = hsh(i, j);
			flow.add(v*2, v*2+1, 1);
			if( D[i][j] == 'S' ) S = v*2+1;
			if( D[i][j] == 'T' ) E = v*2;

			if(D[i][j] != '.'){
				int a = hsh(N, j)*2;
				int b = hsh(i, M)*2;

				flow.add(v*2+1, a, 1e9);
				flow.add(a, v*2, 1e9);
				flow.add(v*2+1, b, 1e9);
				flow.add(b, v*2, 1e9);
			}
		}
	}
	int f = flow.run(S, E, (N+1)*(M+1)*2+5);
	if( f >= 1e8) printf("-1\n");
	else printf("%d\n", f);
}


Measured memory_bytes: 19584