#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define fbo find_by_order
#define ook order_of_key

typedef long long ll;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef long double ld; 
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> pbds;
typedef set<int>::iterator sit;
typedef map<int,int>::iterator mit;
typedef vector<int>::iterator vit;
const int MX = 20051;
const int INF = int(1e9);
struct MaxFlow //by yutaka1999, have to define INF and MX (the Max number of vertices)
{
	struct edge
	{
		int to,cap,rev;
		edge(int to=0,int cap=0,int rev=0):to(to),cap(cap),rev(rev){}
	};
	vector <edge> vec[MX];
	int level[MX];
	int iter[MX];
	
	void addedge(int s,int t,int c) //adds an edge of cap c to the flow graph
	{
		int S=vec[s].size(),T=vec[t].size();
		vec[s].push_back(edge(t,c,T));
		vec[t].push_back(edge(s,0,S));
	}
	void bfs(int s)
	{
		memset(level,-1,sizeof(level));
		queue <int> que;
		level[s] = 0;
		que.push(s);
		while (!que.empty())
		{
			int v = que.front();que.pop();
			for(int i=0;i<vec[v].size();i++)
			{
				edge&e=vec[v][i];
				if (e.cap>0&&level[e.to]<0)
				{
					level[e.to]=level[v]+1;
					que.push(e.to);
				}
			}
		}
	}
	ll flow_dfs(int v,int t,ll f)
	{
		if (v==t) return f;
		for(int &i=iter[v];i<vec[v].size();i++)
		{
			edge &e=vec[v][i];
			if (e.cap>0&&level[v]<level[e.to])
			{
				ll d=flow_dfs(e.to,t,min(f,ll(e.cap)));
				if (d>0)
				{
					e.cap-=d;
					vec[e.to][e.rev].cap+=d;
					return d;
				}
			}
		}
		return 0;
	}
	ll maxflow(int s,int t) //finds max flow using dinic from s to t
	{
		ll flow = 0;
		while(1)
		{
			bfs(s);
			if (level[t]<0) return flow;
			memset(iter,0,sizeof(iter));
			while (1)
			{
				ll f=flow_dfs(s,t,INF);
				if(f==0) break;
				flow += f;
			}
		}
	}
};

char a[101][101];
int h,w; 
int inid(int x, int y)
{
	return (x*w+y)*2;
}
int outid(int x,int y)
{
	return (x*w+y)*2+1;
}


int main()
{
	ios_base::sync_with_stdio(0); cin.tie(0);
	MaxFlow mf;
	cin>>h>>w;
	int s=20035; int e= 20036;
	for(int i = 0; i < h; i++)
	{
		for(int j = 0; j < w; j++)
		{
			cin>>a[i][j];
			if(a[i][j]=='S') 
			{
				//cerr<<inid(i,j)<<'\n';
				mf.addedge(s,inid(i,j),100000000);
				mf.addedge(inid(i,j),outid(i,j),100000000);
			}
			else if(a[i][j]=='T') 
			{
				//cerr<<outid(i,j)<<'\n';
				mf.addedge(outid(i,j),e,100000000);
				mf.addedge(inid(i,j),outid(i,j),100000000);
			}
		}
	}
	for(int i=0;i<h;i++)
	{
		for(int j=0;j<w;j++)
		{
			if(a[i][j]!='.')
			{
				if(a[i][j]=='o')
				{
					//cerr<<inid(i,j)<<' '<<outid(i,j)<<'\n';
					mf.addedge(inid(i,j),outid(i,j),1);
				}
				for(int k = 0; k < h; k++)
				{
					if(k!=i&&a[k][j]!='.')
					{
						//cerr<<outid(i,j)<<' '<<inid(k,j)<<'\n';
						mf.addedge(outid(i,j),inid(k,j),100000000);
					}
				}
				for(int k = 0; k < w; k++)
				{
					if(k!=j&&a[i][k]!='.')
					{
						//cerr<<outid(i,j)<<' '<<inid(i,k)<<'\n';
						mf.addedge(outid(i,j),inid(i,k),100000000);
					}
				}
			}
		}
	}
	ll ans = mf.maxflow(s,e);
	if(ans>=100000000) ans=-1;
	cout<<ans<<'\n';
}


Measured memory_bytes: 62464