#include<iostream>
#include<vector>
#include<set>
#include<algorithm>
#include<string>
#include<cstdio>
#include<queue>
using namespace std;
typedef long long ll;

template<typename T> class Dinic {
public:
    struct edge{
        int to;
        T cap;
        int rev;
    };
    vector<vector<edge> > G;
    vector<int> level,iter;
    int n;
    Dinic(int node_size){
        n = node_size;
        G.resize(node_size),level.resize(node_size),iter.resize(node_size);
    }
    //辺を張る
    void add_edge(int from,int to,T cap)
    {
    	G[from].push_back((edge){to,cap,(int)G[to].size()});
    	G[to].push_back((edge){from,(T)0,(int)G[from].size()-1});
    }
    void bfs(int s)
    {
    	fill(level.begin(),level.end(),-1);
    	queue<int> que;
    	level[s] = 0;
    	que.push(s);
    	while(!que.empty()){
    		int v = que.front();
    		que.pop();
    		for(auto& e : G[v]){
    			if(e.cap > 0 && level[e.to] < 0){
    				level[e.to] = level[v] + 1;
    				que.push(e.to);
    			}
    		}
    	}
    }
    T dfs(int v,int t,T f)
    {
    	if(v==t){
    		return f;
    	}
    	for(int &i = iter[v];i<(int)G[v].size();i++){
    		edge &e = G[v][i];
    		if(e.cap > 0 && level[v] < level[e.to]){
    			T 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;
    }
    //最大流を計算
    T solve(int s,int t)
    {
    	T flow = 0;
    	for(;;){
    		bfs(s);
    		if(level[t]<0){
    			return flow;
    		}
    		fill(iter.begin(),iter.end(),0);
    		T f;
    		while((f=dfs(s,t,numeric_limits<T>::max())) > 0){
    			flow += f;
    		}
    	}
    }
};
int h,w;
int calc(int a,int b){
    return a*w+b;
}

int main(){
    
    cin >> h >> w;
    vector<string> s(h);
    for(int i=0;i<h;i++){
        cin >> s[i];
    }
    int n = h*w;
    int a,b;
    for(int i=0;i<h;i++){
        for(int j=0;j<w;j++){
            if(s[i][j]=='S'){
                s[i][j] = 'o';
                a = calc(i,j)+n;
            }
            if(s[i][j]=='T'){
                s[i][j] = 'o';
                b = calc(i,j);
            }
        }
    }
    if((a-n)%w==b%w||(a-n)/w==b/w){
        cout << -1 << endl;
        return 0;
    }
    Dinic<int> dn(2*h*w);
    for(int i=0;i<h*w;i++){
        dn.add_edge(i,i+n,1);
    }
    for(int i=0;i<h;i++){
        vector<int> p;
        for(int j=0;j<w;j++){
            if(s[i][j]=='o'){
                p.push_back(j);
            }
        }
        for(int j=0;j<p.size();j++){
            for(int k = j+1;k<p.size();k++){
                dn.add_edge(calc(i,p[k])+n,calc(i,p[j]),1);
                dn.add_edge(calc(i,p[j])+n,calc(i,p[k]),1);
            }
        }
    }
    for(int i=0;i<w;i++){
        vector<int> p;
        for(int j=0;j<h;j++){
            if(s[j][i]=='o'){
                p.push_back(j);
                //cout << j << " " << i << endl;
            }
        }
        for(int j=0;j<p.size();j++){
            for(int k = j+1;k<p.size();k++){
                dn.add_edge(calc(p[j],i)+n,calc(p[k],i),1);
                dn.add_edge(calc(p[k],i)+n,calc(p[j],i),1);
            }
        }
    }
    int ans = dn.solve(a,b);
    cout << ans << endl;
    return 0;
}

Measured memory_bytes: 61824