#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
using pii = pair<int, int>;
 
template <typename T> T inf;
template <> constexpr int inf<int> = 1e9;
template <> constexpr ll inf<ll> = 1e18;


using weight = int;

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

using edges = std::vector<edge>;
using graph = std::vector<edges>;

void add_edge(graph& g, int from, int to, weight cap) {
    g[from].push_back(edge{to, cap, static_cast<int>(g[to].size())});
    g[to].push_back(edge{from, 0, static_cast<int>(g[from].size()-1)});
}

void bfs(graph& g, std::vector<int>& level, int s) {
    for(int i = 0; i < (int)level.size(); ++i) {
        level[i] = -1;
    }
    level[s] = 0;
    std::queue<int> que;
    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);
            }
        }
    }
}

weight dfs(graph& g, std::vector<int>& level, std::vector<int>& iter, int v, int t, weight 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]) {
            weight d = dfs(g, level, iter, e.to, t, std::min(f, e.cap));
            if(d > 0) {
                e.cap -= d;
                g[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

weight max_flow(graph& g, int s, int t) {
    weight flow = 0;
    std::vector<int> level(g.size(), -1);
    std::vector<int> iter(g.size(), 0);
    weight INF = 1e9;
    while(true) {
        bfs(g, level, s);
        if(level[t] < 0) {
            return flow;
        }
        for(int i = 0; i < (int)iter.size(); ++i) {
            iter[i] = 0;
        }
        weight f;
        while((f = dfs(g, level, iter, s, t, INF)) > 0) {
            flow += f;
        }
    }
}

int main() {
    int H, W;
    cin >> H >> W;
    vector<string> a(H);
    for(int i = 0; i < H; ++i) {
        cin >> a[i];
    }
    graph g(2 * H * W);
    int source, sink;
    for(int i = 0; i < H; ++i) {
        for(int j = 0; j < W; ++j) {
            if(a[i][j] == 'S') {
                source = i * W + j;
            } else if(a[i][j] == 'T') {
                sink = i * W + j;
            }
            if(a[i][j] == '.') {
                continue;
            }
            add_edge(g, i * W + j, i * W + j + H * W, (a[i][j] == 'T' || a[i][j] == 'S' ? inf<int> : 1));
            for(int k = 0; k < H; ++k) {
                if(i != k && a[k][j] != '.') {
                    add_edge(g, i * W + j + H * W, k * W + j, 1);
                }
            }
            for(int k = 0; k < W; ++k) {
                if(j != k && a[i][k] != '.') {
                    add_edge(g, i * W + j + H * W, i * W + k, 1);
                }
            }
        }
    }
    if(source / W == sink / W || source % W == sink % W) {
        cout << -1 << endl;
    } else {
        cout << max_flow(g, source, sink) << endl;
    }
}


Measured memory_bytes: 62464