#include<bits/stdc++.h>
using namespace std;
const int N = 500;
char ch[200];
struct Edge
{
	int from,to,cap,flow;
	Edge(int u,int v,int c,int f):from(u),to(v),cap(c),flow(f){}
};
struct Dinic
{
	int n,m,s,t;
	vector<Edge>edges;
	vector<int>G[N];
	bool vis[N];
	int d[N];
	int cur[N];
	void addedge(int from,int to,int cap)
	{
		edges.push_back(Edge(from,to,cap,0));
		edges.push_back(Edge(to,from,0,0));
		int m=edges.size();
		G[from].push_back(m-2);
		G[to].push_back(m-1);
	}
	bool bfs()
	{
		memset(vis,0,sizeof(vis));
		queue<int>Q;
		Q.push(s);
		d[s]=0;
		vis[s]=1;
		while(!Q.empty())
		{
			int x=Q.front();
			Q.pop();
			for(int i=0;i<G[x].size();i++)
			{
				Edge&e=edges[G[x][i]];
				if(!vis[e.to]&&e.cap>e.flow)
				{
					vis[e.to]=1;
					d[e.to]=d[x]+1;
					Q.push(e.to);
				}
			}
		}
		return vis[t];
	}
	int dfs(int x,int a)
	{
		if(x==t||a==0)return a;
		int flow=0,f;
		for(int&i=cur[x];i<G[x].size();i++)
		{
			Edge&e=edges[G[x][i]];
			if(d[x]+1==d[e.to]&&(f=dfs(e.to,min(a,e.cap-e.flow)))>0)
			{
				e.flow+=f;
				edges[G[x][i]^1].flow-=f;
				flow+=f;
				a-=f;
				if(!a)break;
			}
		}
		return flow;
	}
	int Maxflow(int s,int t)
	{
		this->s=s,this->t=t;
		int flow=0;
		while(bfs())
		{
			memset(cur,0,sizeof(cur));
			flow+=dfs(s,0x3f3f3f3f);
		}
		return flow;
	}
}; 
int main()
{
	Dinic dinic;
	int n,m;
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",ch);
		for(int j=0;j<m;j++)
		{
			if(ch[j]!='.')
			{
				dinic.addedge(i,j+1+n,1);
				dinic.addedge(j+1+n,i,1);
				if(ch[j]=='S') dinic.addedge(0,i,0x3f3f3f3f),dinic.addedge(0,j+1+n,0x3f3f3f3f);
				else if(ch[j]=='T') dinic.addedge(i,n+m+1,0x3f3f3f3f),dinic.addedge(j+1+n,n+m+1,0x3f3f3f3f);
			}
		}
	}
	int ans = dinic.Maxflow(0,n+m+1);
	if(ans>=0x3f3f3f3f) printf("%d\n",-1);
	else printf("%d\n",ans);
	return 0;
}