#include <bits/stdc++.h>
using namespace std;
typedef long long unsigned int ll;

#define EPS (1e-7)
#define INF (1e9)
#define PI (acos(-1))
struct max_flow {
    struct edge { int to, cap, rev; };
    int V;
    vector<vector<edge>> G;
    vector<int> itr, level;

    max_flow(int V) : V(V) { G.assign(V,vector<edge>()); }

    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});
    }

    void bfs(int s) {
        level.assign(V,-1);
        queue<int> q;
        level[s] = 0; q.push(s);
        while (!q.empty()) {
            int v = q.front(); q.pop();
            for(auto &e: G[v]){
                if (e.cap > 0 and level[e.to] < 0) {
                    level[e.to] = level[v] + 1;
                    q.push(e.to);
                }
            }
        }
    }

    int dfs(int v, int t, int f) {
        if (v == t) return f;
        for (int& i = itr[v]; i < (int) G[v].size(); ++i) {
            edge& e = G[v][i];
            if (e.cap > 0 and 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 run(int s, int t) {
        int ret = 0, f;
        while (bfs(s), level[t] >= 0) {
            itr.assign(V,0);
            while ((f = dfs(s, t, INF)) > 0) ret += f;
        }
        return ret;
    }
};


int main() {
    //cout.precision(10);
    int h, w;
    cin >> h >> w;
    string field[105];
    int sw, sh, tw, th;
    for(int i = 0; i < h; i++){
        cin >> field[i];
        for(int j = 0; j < w; j++){
            if(field[i][j] == 'S'){
                sw = j;
                sh = i;
            }
            if(field[i][j] == 'T'){
                tw = j;
                th = i;
            }
        }
    }
    //cout << sw << " " << tw << " " << sh << " " << th << endl;
    if((sw == tw) || (sh == th)){
        cout << -1 << endl;
        return 0;
    }
    max_flow graph(20005);
    for(int i = 0; i < w; i++){
        for(int j = 0; j < h; j++){
            if(field[j][i] == '.'){
                //cout << "skipped " << j << " " << i << endl;
                continue;
            }
            int from = 100 * j + i;
            for(int k =  j + 1; k < h; k++){
                if(field[k][i] == '.'){
                    continue;
                }
                int to = 100 * k + i;
                //cout << from << " " << to << endl;
                graph.add_edge(from, to + 10000, 1);
                graph.add_edge(to, from + 10000, 1);
            }
        }
    }
    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            if(field[i][j] == '.'){
                continue;
            }
            int from = 100 * i + j;
            for(int k =  j + 1; k < w; k++){
                if(field[i][k] == '.'){
                    continue;
                }
                int to = 100 * i + k;
                graph.add_edge(from, to + 10000, 1);
                graph.add_edge(to, from + 10000, 1);
            }
        }
    }
    for(int i = 1; i <= 10000; i++){
        graph.add_edge(i + 10000, i, 1);
    }
    cout << graph.run(sh * 100 + sw, th * 100 + tw + 10000) << endl;
    return 0;
}

Measured memory_bytes: 61568