#include<algorithm>
#include<complex>
#include<ctype.h>
#include<iomanip>
#include<iostream>
#include<fstream>
#include<map>
#include<math.h>
#include<numeric>
#include<queue>
#include<set>
#include<stack>
#include<stdio.h>
#include<string>
#include<string>
#include<vector>

using namespace std;
typedef long long ll;

#define FOR(i,a,b) for(ll i=(a);i<(b);++i)
#define ALL(v) (v).begin(), (v).end()
#define p(s) cout<<(s)<<endl
#define p2(s, t) cout << (s) << " " << (t) << endl
#define br() p("")
#define pn(s) cout << (#s) << " " << (s) << endl
#define p_yes() p("Yes")
#define p_no() p("No")

const ll mod = 1e9 + 7;
const ll inf = 1e18;

template < typename T >
void vprint(T &V){
	for(auto v : V){
    	cout << v << " ";
	}
	cout << endl;
}

struct Edge{
    ll to;
    ll capacity;
    ll rev; // index
    Edge(ll t, ll c, ll r){
        to = t;
        capacity = c;
        rev = r;
    }
    Edge(){}
};

// ford fulkerson ver
struct MaxFlow{
    vector<vector<Edge> > G;
    vector<bool> used;

    MaxFlow(ll node_num){
        G.resize(node_num);
        used.resize(node_num);
    }

    void add_edge(ll from, ll to, ll capacity){
        G[from].push_back(Edge(to, capacity, G[to].size()));
        G[to].push_back(Edge(from, 0, G[from].size()-1));
    }

    ll dfs(ll v, ll t, ll flow){
        if(v==t) return flow;
        used[v] = true;
        for(Edge &edge : G[v]){
            if(!used[edge.to] && edge.capacity > 0){
                ll d = dfs(edge.to, t, min(flow, edge.capacity));
                if(d>0){
                    edge.capacity -= d;
                    G[edge.to][edge.rev].capacity += d;
                    return d;
                }
            }
        }
        return 0;
    }

    ll calc(ll start, ll end){
        ll flow_sum = 0;
        while(true){
            fill(ALL(used), false);
            ll f = dfs(start, end, inf);
            if(f==0){
                break;
            }
            flow_sum += f;
        }
        return flow_sum;
    }
};


int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);

    // input
    ll H, W;
    cin >> H >> W;
    ll N = H+W;

    vector<string> A(H);
    FOR(i, 0, H){
        cin >> A[i];
    }

    // SとTが同じ行 or 列にいるならフローを考えるまでもなく-1
    ll S_i;
    ll S_j;
    ll T_i;
    ll T_j;
    FOR(i, 0, H){
        FOR(j, 0, W){
            char c = A[i][j];
            if(c=='S'){
                S_i = i;
                S_j = j;
            }
            else if(c=='T'){
                T_i = i;
                T_j = j;
            }
        }
    }
    if(S_i==T_i || S_j==T_j){
        p(-1);
        return 0;
    }

    auto mf = MaxFlow(N+2);
    // N : 始点
    // N+1 : 終点とする
    // [0, ..., H-1, 0, ..., W-1, N, N+1]

    FOR(i, 0, H){
        FOR(j, 0, W){
            char c = A[i][j];
            if(c=='S'){
                mf.add_edge(N, i, inf);
                mf.add_edge(N, H+j, inf);
            }
            else if(c=='T'){
                mf.add_edge(i, N+1, inf);
                mf.add_edge(H+j, N+1, inf);
            }
            else if(c=='o'){
                mf.add_edge(i, H+j, 1);
                mf.add_edge(H+j, i, 1);
            }
        }
    }

    ll f = mf.calc(N, N+1);
    if(f==inf){
        p(-1);
    }else{
        p(f);
    }
    
    return 0;
}

Measured memory_bytes: 1536