#include <bits/stdc++.h>
using namespace std;

#define GET_MACRO(_1,_2,_3,_4,NAME,...) NAME
#define REP2(i,n) for(int i=0;i<(int)(n);i++)
#define REP3(i,m,n) for(int i=m;i<(int)(n);i++)
#define REP4(i,m,n,s) for(int i=m;(s>0 and i<(int)(n)) or (s<0 and i>(int)(n));i+=s)
#define REP(...) GET_MACRO(__VA_ARGS__, REP4, REP3, REP2)(__VA_ARGS__)
#define REPIT(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define PIS(x) printf("%d ",x)
#define PRINTIA(a,n) REP(i,n){printf("%d ", *((a)+i));}putchar('\n');
#define PN() putchar('\n')
#define MP make_pair
#define PB push_back

typedef pair<int,int> PII;
typedef long long LL;
typedef unsigned long long ULL;

void RI() {}
template<typename... T>
void RI( int& head, T&... tail ) {
    scanf("%d",&head);
    RI(tail...);
}
void PI() {putchar('\n');}
template<typename... T>
void PI(const int head, T... tail ) {
    printf("%d ", head);
    PI(tail...);
}

#define MAX_N 20005
#define INF INT_MAX

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

vector<edge> G[MAX_N];
int level[MAX_N];
int iter[MAX_N];

void add_edge(int from, int to, int cap) {
    int i = G[from].size();
    int j = G[to].size();
    G[from].push_back((edge){to, cap, j});
    G[to].push_back((edge){from, 0, i});
}

void bfs(int s) {
    memset(level, -1, sizeof(level));
    queue<int> que;
    level[s] = 0;
    que.push(s);
    while(!que.empty()) {
        int v = que.front();
        que.pop();
        for(int i = 0; i < (int)G[v].size(); i++) {
            edge &e = G[v][i];
            if(e.cap > 0 && level[e.to] < 0) {
                level[e.to] = level[v] + 1;
                que.push(e.to);
            }
        }
    }
}

int dfs(int v, int t, int f) {
    if(v == t)
        return f;
    for(int &i = iter[v]; i < (int)G[v].size(); i++) {
        edge &e = G[v][i];
        if(e.cap > 0 && level[v] < level[e.to]) {
            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) {
        bfs(s);
        if(level[t] < 0)
            return flow;
        memset(iter, 0, sizeof(iter));
        int f;
        while((f=dfs(s, t, INF)) > 0) {
            flow += f;
        }
    }
}

char pond[102][102];
vector<int> row[102];
vector<int> col[102];

int main()
{
    int H, W;
    RI(H, W);
    REP(i, H) {
        scanf("%s", pond[i]);
    }
    int si = -1, sj = -1, ti = -1, tj = -1;
    REP(i, H) {
        REP(j, W) {
            add_edge(i*W + j + H*W,  i*W + j, 1);

            if(pond[i][j] == 'o') {
                row[i].PB(j);
                col[j].PB(i);
            }
            if(pond[i][j] == 'S') {
                si = i;
                sj = j;
            }
            if(pond[i][j] == 'T') {
                ti = i;
                tj = j;
            }
        }
    }
    if(si == ti or sj == tj) {
        printf("-1\n");
        return 0;
    }

    REP(i, H) {
        REPIT(ii, row[i]) {
            REPIT(ii2, row[i]) {
                if(*ii != *ii2) {
                    int j1 = *ii, j2 = *ii2;
                    add_edge(i*W + j1,  i*W + j2 + H*W, 100000);
                }
            }
        }
    }

    REP(j, W) {
        REPIT(ii, col[j]) {
            REPIT(ii2, col[j]) {
                if(*ii != *ii2) {
                    int i1 = *ii, i2 = *ii2;
                    add_edge(i1*W + j,  i2*W + j + H*W, 1);
                }
            }
        }
    }

    REPIT(ii, row[si]) {
        int j = *ii;
        add_edge(si*W + sj, si*W + j + H*W, 1);
    }
    REPIT(ii, col[sj]) {
        int i = *ii;
        add_edge(si*W + sj, i*W + sj + H*W, 1);
    }
    REPIT(ii, row[ti]) {
        int j = *ii;
        add_edge(ti*W + j, ti*W + tj + H*W, 1);
    }
    REPIT(ii, col[tj]) {
        int i = *ii;
        add_edge(i*W + tj, ti*W + tj + H*W, 1);
    }

    PI(max_flow(si*W+sj, ti*W+tj + H*W));
    return 0;
}


Measured memory_bytes: 61952