#include<bits/stdc++.h>
#define N 105
using namespace std;
#define add(x,y,f) (Dinic::addedge(x,y,f)) 
const int INF = 0x3f3f3f3f;
namespace Dinic{
	struct edge{
		int t,flow,next;
	}e[N*N*100];int ecnt,head[N*N*2];
	void addedge(int f,int t,int flow){
		e[++ecnt]=(edge){t,flow,head[f]};head[f]=ecnt;
		e[++ecnt]=(edge){f,0,head[t]};head[t]=ecnt;
	}
	
	int S,T,sz;
	int cur[N*N*2],dis[N*N*2];
	int DFS(int u,int a){
		if(u==T||a==0) return a;
		int ret=0;
		for(int &i=cur[u];i;i=e[i].next){
			if(e[i].flow!=0&&dis[e[i].t]==dis[u]+1){
				int t=DFS(e[i].t,min(e[i].flow,a));
				if(t){
					e[i].flow-=t;e[i^1].flow+=t;
					a-=t;ret+=t;
				}
			}
		}
		return ret;
	}
	
	bool BFS(){
		memset(dis,0x3f,sizeof(int)*(sz+2));
		queue<int> q;
		q.push(S);dis[S]=0;
		while(!q.empty()){
			int u=q.front();q.pop();
			for(int i=head[u];i;i=e[i].next){
				if(e[i].flow!=0&&dis[e[i].t]==INF){
					dis[e[i].t]=dis[u]+1;
					q.push(e[i].t);
				}
			} 
		}
		return dis[T]!=INF;
	}
	
	int work(int S1,int T1,int size){
		S=S1,T=T1;sz=size;
		int ret=0;
		while(BFS()){
			memcpy(cur,head,sizeof(int)*(sz+2));
			ret+=DFS(S1,INF);
			if(ret>=INF) return -1;
		}
		return ret;
	}
}

int cnt;
int id[N][N][2];//0 in 1 out
char mp[N][N];
int r[N],c[N];
int main(){
	Dinic::ecnt=1;
	int h,w;
	scanf("%d%d",&h,&w);
	for(int i=1;i<=h;i++) scanf("%s",mp[i]+1);
	for(int i=1;i<=h;i++) r[i]=++cnt;
	for(int i=1;i<=w;i++) c[i]=++cnt;
	int S,T;
	for(int i=1;i<=h;i++)
		for(int j=1;j<=w;j++){
			if(mp[i][j]=='.') continue;
			id[i][j][0]=++cnt;
			id[i][j][1]=++cnt;
			if(mp[i][j]=='S') S=id[i][j][1];
			if(mp[i][j]=='T') T=id[i][j][0];
			add(id[i][j][0],id[i][j][1],1);
			add(id[i][j][1],r[i],INF);
			add(id[i][j][1],c[j],INF);
			add(r[i],id[i][j][0],INF);
			add(c[j],id[i][j][0],INF);
		}
	printf("%d\n",Dinic::work(S,T,cnt));
	return 0;
} 