#include <bits/stdc++.h>
#define rep(i, n) for (int i = 0; i < (n); ++i)
#define sz(x) int(x.size())
using namespace std;

typedef long long ll;
const int INF = 1e8;
// const ll INF = 1LL << 60;
typedef pair<int, int> P;

struct edge { int to, cap, rev; };
vector<edge> G[20000];
int level[20000];
int iter[20000];
int H, W;

// G[e.to][e.rev] で逆辺の構造体にアクセスできる
void add_edge(int from, int to, int cap) {
    int D = H * W;
    if (from == to) {
        to += D;
    } else {
        from += D;
    }
    G[from].push_back((edge){to, cap, G[to].size()});
    G[to].push_back((edge){from, 0, G[from].size() - 1});
}

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 < 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 < 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;
    for (;;) {
        bfs(s);
        if (level[t] < 0) return flow;
        memset(iter, 0, sizeof(iter));
        int f;
        while ((f = dfs(s, t, INF)) > 0) {
            flow += f;
        }
    }
}

int main() {

    cin >> H >> W;
    vector<string> a;
    a.resize(H);
    rep(i, H) {
        cin >> a[i];
    }

    // for (int i = 1; i <= H; i++) {
    //     for (int j = 1; j <= W; j++) {
    //         cout << (i - 1) * W + j << endl;
    //     }
    // }
    // return 0;

    // グラフを作成する
    int s = 0, sx = 0, sy = 0;
    int t = 0, tx = 0, ty = 0;
    for (int y = 0; y < H; y++) {
        for (int x = 0; x < W; x++) {
            char target = a[y][x];
            if (target == '.') continue;

            int v = y * W + x;
            add_edge(v, v, 1);

            if (target == 'S') {
                sx = x; 
                sy = y;
            }
            if (target == 'T') {
                tx = x; 
                ty = y;
            }

            // 縦 (j 固定)
            for (int y2 = 0; y2 < H; y2++) {
                int u = y2 * W + x;

                if (u == v) continue;
                if (a[y2][x] == '.') continue; 

                add_edge(v, u, 1);
            }
            // 横 (i 固定)
            for (int x2 = 0; x2 < W; x2++) {
                int u = y * W + x2; 
                if (u == v) continue;
                if (a[y][x2] == '.') continue; 
                add_edge(v, u, 1);
            }
        }
    }

    if (sx == tx || sy == ty) {
        cout << -1 << endl;
        return 0;
    }

    // int ans = max_flow(s, t);
    // cout << ans << endl;

    // cout << s << " " << t << endl;

    int D = H * W;
    // fprintf(stderr, "(%d, %d) -> (%d, %d)\n", sy, sx, ty, tx);
    // cout << sx * W + sy << " " << tx * W + ty << endl;
    s = sy * W + sx + D;
    t = ty * W + tx;
    cout << max_flow(s, t) << endl;
    // cout << max_flow(sy * W + sx + D, ty * W + tx) << endl;
    // cout << max_flow(s, t) << endl;
}


Measured memory_bytes: 62464