#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define mst(a,b) memset(a,b,sizeof(a))
#define lowbit(x) ((x)&(-x))
#define X first
#define Y second
using namespace std;
using namespace __gnu_cxx;
using namespace __gnu_pbds;
typedef long long LL;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 20000+10;
const int maxm = 2222222+10;
const int mod = 1e9+7;
const double eps = 1e-9;
struct Edge{
    int to,next,cap,flow;
}edge[maxm<<1];
int tot,head[maxn];
int gap[maxn],dep[maxn],pre[maxn],cur[maxn];
void init(){
    tot=0;
    mst(head,-1);
}
void addedge(int u,int v,int w,int rw=0){
    edge[tot].to=v; edge[tot].cap=w; edge[tot].flow=0; edge[tot].next=head[u]; head[u]=tot++;
    edge[tot].to=u; edge[tot].cap=rw; edge[tot].flow=0; edge[tot].next=head[v]; head[v]=tot++;
}
int sap(int st,int en,int N){
    mst(gap,0);
    mst(dep,0);
    memcpy(cur,head,sizeof(head));
    int u=st;
    pre[u]=-1;
    gap[0]=N;
    int ans=0;
    while (dep[st]<N){
        if (u==en){
            int Min=inf;
            for (int i=pre[u];~i;i=pre[edge[i^1].to]){
                Min=min(Min,edge[i].cap-edge[i].flow);
            }
            for (int i=pre[u];~i;i=pre[edge[i^1].to]){
                edge[i].flow+=Min;
                edge[i^1].flow-=Min;
            }
            u=st;
            ans+=Min;
            continue;
        }
        bool flag=false;
        int v;
        for (int i=cur[u];~i;i=edge[i].next){
            v=edge[i].to;
            if (edge[i].cap-edge[i].flow && dep[v]+1==dep[u]){
                flag=true;
                cur[u]=pre[v]=i;
                break;
            }
        }
        if (flag){
            u=v;
            continue;
        }
        int Min=N;
        for (int i=head[u];~i;i=edge[i].next){
            if (edge[i].cap-edge[i].flow && dep[edge[i].to]<Min){
                Min=dep[edge[i].to];
                cur[u]=i;
            }
        }
        gap[dep[u]]--;
        if (!gap[dep[u]]) return ans;
        dep[u]=Min+1;
        gap[dep[u]]++;
        if (u!=st) u=edge[pre[u]^1].to;
    }
    return ans;
}
int node1[110][110],node2[110][110],S,T;
char mp[110][110];
int main() {
#ifdef local
    freopen("in.txt", "r", stdin);
//    freopen("out.txt", "w", stdout);
#endif
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    init();
    int n,m,c=0; cin>>n>>m;
    for (int i=0;i<n;i++) {
        cin>>mp[i];
        for (int j=0;j<m;j++){
            if (mp[i][j]=='S'){
                S=c++;
            } else if (mp[i][j]=='T'){
                T=c++;
            } else if (mp[i][j]=='o'){
                node1[i][j]=c++;
                node2[i][j]=c++;
                addedge(node1[i][j],node2[i][j],1);
            }
        }
    }
    for (int i=0;i<n;i++) for (int j=0;j<m;j++){
            if (mp[i][j]=='S'){
                for (int k=0;k<n;k++){
                    if (mp[k][j]=='T'){
                        cout<<-1<<"\n";
                        return 0;
                    }
                    if (k==i || mp[k][j]!='o') continue;
                    addedge(S,node1[k][j],inf);
                }
                for (int k=0;k<m;k++){
                    if (mp[i][k]=='T'){
                        cout<<-1<<"\n";
                        return 0;
                    }
                    if (k==j || mp[i][k]!='o') continue;
                    addedge(S,node1[i][k],inf);
                }
            } else if (mp[i][j]=='T'){
                for (int k=0;k<n;k++){
                    if (mp[k][j]=='S'){
                        cout<<-1<<"\n";
                            return 0;
                    }
                    if (k==i || mp[k][j]!='o') continue;
                    addedge(node2[k][j],T,inf);
                }
                for (int k=0;k<m;k++){
                    if (mp[i][k]=='S'){
                        cout<<-1<<"\n";
                        return 0;
                    }
                    if (k==j || mp[i][k]!='o') continue;
                    addedge(node2[i][k],T,inf);
                }
            } else if (mp[i][j]=='o'){
                for (int k=0;k<n;k++){
                    if (k==i || mp[k][j]!='o') continue;
                    addedge(node2[i][j],node1[k][j],inf);
                }
                for (int k=0;k<m;k++){
                    if (k==j || mp[i][k]!='o') continue;
                    addedge(node2[i][j],node1[i][k],inf);
                }
            }
    }
    cout<<sap(S,T,c)<<"\n";
    return 0;
}


Measured memory_bytes: 63744