#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <vector>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stdlib.h>
#include <time.h>
#include <iomanip>
#include <math.h>
#include <bitset>
#include <random>


using namespace std;

#define taskname "A"
#define LL long long 
#define uLL unsigned long long 
#define FOR(i,l,r) for(int i = l; i <= r; ++i)
#define REP(i,l,r) for(int i = l; i < r; ++i)
#define FORD(i,r,l) for(int i = r; i >= l; --i)
#define REPD(i,r,l) for(int i = r; i > l; --i)
#define sz(x) (int)((x).size())
#define all(x) (x).begin(), (x).end()
#define debug(x) { cerr << #x << " = " << x << endl; }
#define sci(x) int x; scanf("%d", &x);
#define scii(x, y) int x, y; scanf("%d %d", &x, &y);
#define sciii(x, y, z) int x, y, z; scanf("%d %d %d", &x, &y, &z);
#define pi pair<int,int>
#define pii pair<int,pi>
#define mp make_pair
#define fi first
#define se second
#define pb push_back
#define _USE_MATH_DEFINES 
/* M_PI */
#define SetLength2(a, n, t) a=((t*) calloc(n, sizeof(t))) + (n)/2

const int N = 123;

int tcases = 1;

int m,n,res = 1e9 + 123;
pi X,Y;
char str[N];

namespace DinitzFlow{
    const int maxN = 1e5 + 123;
    const int oo = 1e9 + 123;

    int flow[maxN],G[maxN],d[maxN],s,t,nFlow = 0,mFlow = 0,maxflow = 0,times = 0;
    pi e[maxN];
    vector<int> a[maxN];
    deque <int> Q;

    bool bfs(){
        FOR(i,1,nFlow) d[i] = 0;
        d[s] = 1;
        Q.clear();
        Q.pb(s);
        while(!Q.empty()){
            int u = Q.front(); Q.pop_front();
            for(auto j : a[u]){
                int v = e[j].fi;
                if(flow[j] < e[j].se && !d[v]){
                    d[v] = d[u] + 1;
                    if(v == t) return 1;
                    Q.pb(v);
                }
            }
        }
        return 0;
    }
    int dfs(int u,int curFlow){
        if(u == t) return curFlow;
        G[u] = times;
        for(int j : a[u]){
            int v = e[j].fi;
            if(flow[j] < e[j].se && d[v] == d[u] + 1 && G[v] != times){
                if(int x = dfs(v,min(curFlow,e[j].se - flow[j]))){
                    flow[j] += x;
                    flow[j ^ 1] -= x;
                    return x;
                }
            }
        }
        return 0;
    }
    void findMaxFlow(){
        while(bfs()){
            while(int x = (++times,dfs(s,oo))) maxflow += x;
        }
        printf("%d",maxflow);
    }
    
    void newEdge(int u,int v,int c){
        a[u].pb(mFlow);
        e[mFlow++] = mp(v,c);
        a[v].pb(mFlow);
        e[mFlow++] = mp(u,c);
    }
};

void testcase(){
    scanf("%d%d",&m,&n);
    DinitzFlow::nFlow = m + n;
    FOR(i,1,m){
        scanf("%s",str + 1);
        FOR(j,1,n){
            if(str[j] == 'S'){
                DinitzFlow::newEdge(i,m + j,DinitzFlow::oo);
                X = mp(i,j);
            }else if(str[j] == 'T'){
                DinitzFlow::newEdge(i,m + j,DinitzFlow::oo);
                Y = mp(i,j);
            }else if(str[j] == 'o'){
                DinitzFlow::newEdge(i,m + j,1);
            }
        }
    }
    if(X.fi == Y.fi || X.se == Y.se){
        puts("-1");
        return ;
    }
    DinitzFlow::s = X.se + m;
    DinitzFlow::t = Y.se + m;
    DinitzFlow::findMaxFlow();
}
int main(){

    FOR(i,1,tcases) testcase();

    return 0;
}

Measured memory_bytes: 4480