// Original C++ solution (slower):
#include<bits/stdc++.h>



using namespace std;



#define ll  long long

#define ld  double



#define sz(x)   (int)x.size()

#define all(x)  x.begin(),x.end()



#define pb  emplace_back

#define X   first

#define Y   second



const int   N   = 2e5 + 5;



typedef pair<int,int>   ii;



struct Edge {

    int v, c;

    Edge(int _v,int _c) : v(_v), c(_c)  {}

};



vector<Edge> E;

vector<int>  g[N];



int addEdge(int u,int v,int c)  {

    g[u].pb(sz(E)); E.pb(v,c);

    g[v].pb(sz(E)); E.pb(u,0);



    return  sz(E) - 1;

}



int S, T;

int d[N];

int p[N];



bool bfs()  {

    for(int i = 0 ; i <= T ; ++i)

        d[i] = -1,

        p[i] = 0;



    queue<int>  q;

    q.push(S);  d[S] = 0;



    while (q.size())    {

        int u = q.front();  q.pop();

        for(int i : g[u])   {

            int v = E[i].v;

            if (E[i].c == 0)    continue;

            if (d[v] < 0)   {

                d[v] = d[u] + 1;

                q.push(v);

            }

        }

    }



    return  d[T] >= 0;

}



int dfs(int u,int F)    {

    if (u == T || F == 0)   return  F;

    for(int &i = p[u] ; i < sz(g[u]) ; ++i)  {

        int j = g[u][i];

        int v = E[j].v;

        if (E[j].c == 0 || d[v] != d[u] + 1)

            continue;

        int res = dfs(v,min(E[j].c,F));

        if (res)    {

            E[j].c -= res;  j ^= 1;

            E[j].c += res;  return  res;

        }

    }

    return  0;

}



int MaxFlow()   {

    while (bfs())

    while (dfs(S,N));



    int ans = 0;



    for(int i : g[T])

        ans += E[i].c;



    return  ans;

}



int main()  {

    ios_base::sync_with_stdio(0);

    cin.tie(0); cout.tie(0);



    int R;  cin >> R;

    int C;  cin >> C;



    S = 0;

    T = R + C + 1;



    for(int i = 1 ; i <= R ; ++i)

    for(int j = 1 ; j <= C ; ++j)   {

        char c; cin >> c;



        int u = i;

        int v = j + R;



        if (c == 'S')   addEdge(S,u,N), addEdge(S,v,N);

        if (c == 'T')   addEdge(u,T,N), addEdge(v,T,N);



        if (c == 'o')   addEdge(u,v,1), addEdge(v,u,1);

    }

    int ans = MaxFlow();



    if (ans > R + C)

        ans = -1;



    cout << ans << endl;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>



using namespace std;



struct FlowEdge

{

	int u, v;

	long long c, f = 0;

	FlowEdge(){}

	FlowEdge(int _u,int _v,long long _c)

	{

		u = _u; v = _v; c = _c;

	}

};



struct Template_Dinic

{

	const long long flow_INF = 1e18;	

	vector<FlowEdge> Edges;

	vector<vector<int>> AdjList;

	int n, s, t, m = 0;

	vector<int> d, ptr;

	queue<int> q;



	void init(int _n,int _s,int _t)

	{

		n = _n, s = _s, t = _t;

		AdjList.resize(n + 1); 

		d.resize(n + 1);

		ptr.resize(n + 1);

	}



	void add_edge(int u,int v,long long c)

	{

		Edges.push_back(FlowEdge(u,v,c));

		Edges.push_back(FlowEdge(v,u,c));

		AdjList[u].push_back(m);

		AdjList[v].push_back(m + 1);

		m += 2;

	}



	bool bfs()

	{

		while(!q.empty())

		{

			int u = q.front();

			q.pop();

			for (int i=0;i<AdjList[u].size();i++)

			{

				int id = AdjList[u][i];

				if (Edges[id].f < Edges[id].c && d[Edges[id].v] == -1)

				{

					d[Edges[id].v] = d[u] + 1;

					q.push(Edges[id].v);

				}

			}

		}

		return d[t] != -1;

	}



	long long dfs(int u, long long cur)

	{

		if (cur == 0) return 0;

		if (u == t) return cur;

		for (int& cid = ptr[u];cid < AdjList[u].size();cid++)

		{

			int id = AdjList[u][cid];

			int v = Edges[id].v;

			if (d[u] + 1 == d[v] && Edges[id].f < Edges[id].c)

			{

				long long nxt = dfs(v, min(cur,Edges[id].c - Edges[id].f));

				if (!nxt) continue;

				Edges[id].f += nxt;

				Edges[id ^ 1].f -= nxt;

				return nxt;

			}

		}

		return 0;

	}



	long long flow()

	{

		long long res = 0;

		while(1)

		{

			for (int i=0;i<d.size();i++) d[i] = -1;

			d[s] = 0;

			q.push(s);

			if (!bfs())

				break;

			for (int i=0;i<ptr.size();i++) ptr[i] = 0;

			while(long long cur = dfs(s, flow_INF))

				res += cur; 	

		}

		return res;

	}

}Dinic;



int h,w;



int main()

{

	ios::sync_with_stdio(false);

	cin.tie(0);

	cout.tie(0);



	cin >> h >> w;

	Dinic.init(500,0,201);

	for (int i=1;i<=h;i++)

		for (int j=1;j<=w;j++)	

		{

			char c; cin >> c;

			if (c == 'S')

			{

				Dinic.add_edge(0,i,1e9);

				Dinic.add_edge(0,j+100,1e9);	

			}

			else if (c == 'T')

			{

				Dinic.add_edge(i,201,1e9);

				Dinic.add_edge(j+100,201,1e9);

			}

			else if (c == 'o')

				Dinic.add_edge(i,j+100,1);

		}

	long long res = Dinic.flow();

	if (res >= 1e9) cout << -1;

	else cout << res;

}

// Fastest known solution for this problem: