#include <iostream>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <cctype>
#include <cstring>
#include <vector>
#include <list>
#include <queue>
#include <deque>
#include <stack>
#include <map>
#include <set>
#include <algorithm>
#include <iterator>
#include <bitset>
#include <ctime>
using namespace std;

#define FOR(i,a,b) for (int i = (a); i < (b); i++)
#define RFOR(i,b,a) for (int i = (b)-1; i >= (a); i--)
#define ITER(it,a) for (__typeof(a.begin()) it = a.begin(); it != a.end(); it++)
#define FILL(a,value) memset(a, value, sizeof(a))

#define SZ(a) (int)a.size()
#define ALL(a) a.begin(), a.end()
#define PB push_back
#define MP make_pair

typedef long long LL;
typedef vector<int> VI;
typedef pair<int, int> PII;

const double PI = acos(-1.0);
const int INF = 1000 * 1000 * 1000 + 7;
const int MOD = 1000 * 1000 * 1000 + 7;
const LL LINF = INF * (LL) INF;
const int MAX = 111;


const int MAXN = 111 * 111 * 2 ;

string ss[MAX];
int m[MAX][MAX];
int M[MAX][MAX];


struct edge {
    int a, b, cap, flow;
};

int n, s, t, d[MAXN], ptr[MAXN], q[MAXN];
vector<edge> e;
vector<int> g[MAXN];

void add_edge (int a, int b, int cap) {
    edge e1 = { a, b, cap, 0 };
    edge e2 = { b, a, 0, 0 };
    g[a].push_back ((int) e.size());
    e.push_back (e1);
    g[b].push_back ((int) e.size());
    e.push_back (e2);
}

bool bfs() {
    int qh=0, qt=0;
    q[qt++] = s;
    memset (d, -1, n * sizeof d[0]);
    d[s] = 0;
    while (qh < qt && d[t] == -1) {
        int v = q[qh++];
        for (size_t i=0; i<g[v].size(); ++i) {
            int id = g[v][i],
            to = e[id].b;
            if (d[to] == -1 && e[id].flow < e[id].cap) {
                q[qt++] = to;
                d[to] = d[v] + 1;
            }
        }
    }
    return d[t] != -1;
}

int dfs (int v, int flow) {
    if (!flow)  return 0;
    if (v == t)  return flow;
    for (; ptr[v]<(int)g[v].size(); ++ptr[v]) {
        int id = g[v][ptr[v]],
        to = e[id].b;
        if (d[to] != d[v] + 1)  continue;
        int pushed = dfs (to, min (flow, e[id].cap - e[id].flow));
        if (pushed) {
            e[id].flow += pushed;
            e[id^1].flow -= pushed;
            return pushed;
        }
    }
    return 0;
}

int dinic() {
    int flow = 0;
    for (;;) {
        if (!bfs())  break;
        memset (ptr, 0, n * sizeof ptr[0]);
        while (int pushed = dfs (s, INF))
            flow += pushed;
    }
    return flow;
}


int main() {
    int a, b;
    cin >> a >> b;
    FOR(i, 0, a)
    cin >> ss[i];
    
    
    int idx = 0;
    PII S, T;
    FOR(i, 0, a)
    FOR(j, 0, b)
    {
        if (ss[i][j] == '.')continue;
        m[i][j] = idx++;
        if (ss[i][j] == 'S'){
            M[i][j] = m[i][j];
            S = MP(i, j);
            continue;
        }
        if (ss[i][j] == 'T'){
            T = MP(i, j);
            M[i][j] = m[i][j];
            continue;
        }
        M[i][j] = idx++;

    }
    
    if (S.first == T.first || S.second == T.second) {
        cout << -1 << endl;
        return  0;
    }
    
    n = idx;
    s = m[S.first][S.second];
    t = m[T.first][T.second];
    
    
    FOR(i, 0, a)
    FOR(j, 0, b) {
        if (ss[i][j] == '.')continue;
        FOR(k, 0, a) {
            if (ss[k][j] == '.')continue;
            if (k == i)continue;
            add_edge(m[i][j], M[k][j], 2);
        }
        FOR(k, 0, b) {
            if (ss[i][k] == '.')continue;
            if (k == j)continue;
            add_edge(m[i][j], M[i][k], 2);
        }
    }
    
    FOR(i, 0, a)
    FOR(j, 0, b)
    if (m[i][j] != M[i][j])
        add_edge(M[i][j], m[i][j], 1);
    
    cout << dinic();
    
    
    return 0;
}


Measured memory_bytes: 84932