#include<bits/stdc++.h>
#define rep(i, n) for(int i=0;i<(n);++i)
#define per(i, n) for(int i=(n)-1;i>=0;--i)
#define repa(i, n) for(int i=1;i<(n);++i)
#define foreach(i, n) for(auto &i:(n))
#define pii pair<int, int>
#define pll pair<long long, long long>
#define all(x) (x).begin(), (x).end()
#define bit(x) (1ll << (x))
using namespace std;
using ll = long long;
const ll MOD = (ll)1e9+7;
//const ll MOD = 998244353;
//const ll MOD = 924844033;
const int INF = (ll)1e9+7;
const ll INFLL = (ll)1e18;
const double EPS = 1e-5;
using namespace std;
template<class t>
using vvector = vector<vector<t>>;
template<class t>
using vvvector = vvector<vector<t>>;
template<class t>
using vvvvector = vvvector<vector<t>>;
template<class t>
using priority_queuer = priority_queue<t, vector<t>, greater<t>>;
template<class t, class u> bool chmax(t &a, u b){if(a<b){a=b;return true;}return false;}
template<class t, class u> bool chmin(t &a, u b){if(a>b){a=b;return true;}return false;}

#ifdef DEBUG
#define OUTPUT(x) (output(x), outendl())
#else
#define OUTPUT(x) (void)0
#endif

ll modpow(ll x, ll b){
	ll res = 1;
	while(b){
		if(b&1)res = res * x % MOD;
		x = x * x % MOD;
		b>>=1;
	}
	return res;
}

ll modinv(ll x){ return modpow(x, MOD-2); }
ll in(){ ll x; scanf("%lld",&x); return x; }
string in_s(){ string res;cin >> res;return res; }
char in_c(){char res;scanf(" %c",&res);return res;}
bool was_output = false;
template<class t>
void output(t a){ if(was_output)cout << " "; cout << a; was_output = true; }
void outendl(){ was_output = false; cout << endl; }
string outopen = "";
string outclose = "";
string outsplit = " ";
string outenter = "\n";
template<class t>
ostream& operator<<(ostream& os,vector<t> &x){
	if(typeid(t)==typeid(int)||typeid(t)==typeid(long long)||typeid(t)==typeid(char)||typeid(t)==typeid(string)||typeid(t)==typeid(double)){
		bool flag = false;
		os << outopen;
		for(auto i:x){
			if(flag)os << outsplit;
			flag = true;
			os << i;
		}
		os << outclose;
		os << outenter;
		return os;
	}
	os << outopen;
	for(auto i:x){
		os << i;
	}
	os << outclose;
	return os;
}
template<class t>
istream& operator>>(istream &is,vector<t> &x){
	for(auto &i:x){
		is >> i;
	}
	return is;
}

struct edge{
	int to;
	long long cap;
	int rev;
	edge(){}
	edge(int to, long long cap, int rev):to(to), cap(cap), rev(rev){}
};

class dinic{
    using LL = long long;
	public:
		int n;
		vector<vector<edge>> E;
		vector<int> level;
		vector<int> itr;
		int INF;

		dinic(int N, long long inf=(int)1e9):n(N), E(N), level(N, inf), itr(N), INF(inf){}

		void add_edge(int from, int to, long long cap){
			E[from].emplace_back(to, cap, E[to].size());
			E[to].emplace_back(from, 0, E[from].size()-1);
		}

		void bfs(int s){
			queue<int> que;
			level[s] = 0;
			que.push(s);
			while(que.size()){
				int d = que.front();
				que.pop();
				for(int i=0;i<E[d].size();++i){
					if(E[d][i].cap > 0&&level[d] < level[E[d][i].to]){
						level[E[d][i].to] = level[d] + 1;
						que.push(E[d][i].to);
					}
				}
			}
		}

		LL dfs(int p, int to, LL f){
			if(p==to)return f;
			for(int i=itr[p];i<E[p].size();++i){
				itr[p] = i;
				edge &e = E[p][i];
				if(e.cap > 0 && level[p] < level[e.to]){
					LL d = dfs(e.to, to, min(f, e.cap));
					if(d){
						e.cap -= d;
						E[e.to][e.rev].cap += d;
						return d;
					}
				}
			}
			return 0;
		}

		LL max_flow(int s, int t){
			LL res = 0;
			while(true){
				fill(level.begin(), level.end(), INF);
				bfs(s);
				if(level[t]==INF)return res;
				fill(itr.begin(), itr.end(), 0);
				LL f = dfs(s, t, INF);
				while(f){
					res += f;
					f = dfs(s, t, INF);
				}
			}
		}
};



//ys y ga onazi yatu
vvector<int> ys;
vvector<int> xs;
int h;
int w;
int start_x;
int start_y;
int end_x;
int end_y;


int main(){
    h = in();
    w = in();
    ys.resize(h);
    xs.resize(w);
    dinic di(22000);
    int slide = 11000;
    int cnt = 500;
    int sp = 1;
    int gp = 2;
    rep(i,h){
        rep(j,w){
            char d;
            d = in_c();
            if(d=='S'){
                start_x = j;
                start_y = i;
            }
            if(d=='T'){
                end_x = j;
                end_y = i;
            }
            if(d=='o'){
                xs[j].push_back(cnt);
                ys[i].push_back(cnt);
                di.add_edge(cnt+slide,cnt,1);
                ++cnt;
            }
        }
    }
    di.add_edge(sp,3+start_x,INF);
    di.add_edge(sp,3+start_y+w,INF);
    di.add_edge(3+end_x,gp,INF);
    di.add_edge(3+end_y+w,gp,INF);
    rep(i,w){
        foreach(j,xs[i]){
            di.add_edge(j,3+i,1);
            di.add_edge(3+i,j+slide,1);
        }
    }
    rep(i,h){
        foreach(j,ys[i]){
            di.add_edge(j,3+i+w,1);
            di.add_edge(3+i+w,j+slide,1);
        }
    }

    if(start_x==end_x||start_y==end_y){
        cout << -1 << endl;
        return 0;
    }

    cout << di.max_flow(sp,gp) << endl;

    return 0;
}


Measured memory_bytes: 6836