#include <bits/stdc++.h>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()
#define LL long long

using namespace std;

struct edge{int to, cap, rev;};

vector<edge> G[60001];
bool used[60001];

void add_edge(int from,int to,int cap){
    G[from].push_back((edge){to,cap,(int)G[to].size()});
    G[to].push_back((edge){from,0,(int)G[from].size()-1});
    swap(from,to);
    G[from].push_back((edge){to,cap,(int)G[to].size()});
    G[to].push_back((edge){from,0,(int)G[from].size()-1});
}

int dfs(int v,int t,int f){
    if(v==t)return f;
    used[v]=true;
    for(int i=0;i<G[v].size();i++){
        edge &e = G[v][i];
        if(!used[e.to]&&e.cap>0){
            int d = dfs(e.to,t,min(f,e.cap));
            if(d>0){
                e.cap-=d;
                G[e.to][e.rev].cap+=d;
                return d;
            }
        }
    }
    return 0;
}

int max_flow(int s,int t){
    int flow = 0;
    while(true){
        memset(used,false,sizeof(used));
        int f = dfs(s,t,10000000);
        if(f==0)return flow;
        flow +=f;
    }
}

int main(){

    int H,W;cin>>H>>W;

    //0~HW-1 :  横軸から集める点
    //HW~2*HW-1:縦軸から集める点
    //2*HW + 0~H-1,H~H+W:　軸で集める点
    //i*W + j　→ i to 2*HW+i(cap=inf) , HW+j to 2*HW+H+j, i to HW+j(cap=1)
    vector<int> st;

    int inf = 10000;
    REP(i,H){
        REP(j,W){
            char c;cin>>c;
            if(c=='o'){
                add_edge(i*W+j,2*H*W+i,inf);
                add_edge(H*W+i*W+j,2*H*W+H+j,inf);
                add_edge(i*W+j,H*W+i*W+j,1);

            }else if(c=='S'||c=='T'){
                st.push_back(i*W+j);
                add_edge(i*W+j,2*H*W+i,inf);
                add_edge(H*W+i*W+j,2*H*W+H+j,inf);
                add_edge(i*W+j,H*W+i*W+j,inf);
            }
        }
    }


    int ans = max_flow(st[0],st[1]);


    if(ans>=inf)ans=-1;
    cout<<ans<<endl;




    return 0;
}