#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <typename X, typename Y> istream& operator>>(istream& is, pair<X, Y>& p) { return is >> p.first >> p.second; }
template <bool Directed, typename TEdge, bool Index> struct graph {
    using EType = TEdge;
    vector<TEdge> edges;
    vector<vector<int>> adj;
    graph(int n) : adj(n + Index) {}
    graph(int n, int m) : graph(n) { edges.reserve(m << not Directed); }
    TEdge& operator()(int e) { return edges[e]; }
    vector<int>& operator[](int u) { return adj[u]; }
    int size() { return adj.size() - Index; }
    void add_edge(const TEdge& e) {
        adj[e.u].push_back(edges.size());
        edges.push_back(e);
        if(not Directed) {
            adj[e.v].push_back(edges.size());
            edges.push_back(e.reverse());
        }
    }
};
template <typename T> struct fedge {
    int u, v; T c, f;
    T resid() { return c - f; }
    fedge reverse() const { return {v, u, 0, 0}; }
    friend ostream& operator<<(ostream& os, const fedge& e) {
        return os << "(" << e.u << ", " << e.v << ", " << e.w << ", " << e.c << ", " << e.f << ")";
    }
};
template <typename T, bool Index> using flow_graph = graph<0, fedge<T>, Index>;
template <typename T, bool Index> T max_flow(flow_graph<T, Index>& g, int s, int t) {
    vector<int> d(g.adj.size()), adj_ptr(g.adj.size());
    auto make_level_graph = [&]() {
        fill(d.begin(), d.end(), -1);
        d[s] = 0;
        queue<int> q({s});
        while(not q.empty()) {
            int u = q.front(); q.pop();
            for(int e : g[u]) {
                if(g(e).resid() > 0 and d[g(e).v] == -1) {
                    d[g(e).v] = d[g(e).u] + 1;
                    q.push(g(e).v);
                }
            }
        }
        return d[t] != -1;
    };
    function<T(int, T)> augment = [&](int u, T b) {
        if(u == t) return b;
        for(int& j = adj_ptr[u]; j < g[u].size(); j++) {
            fedge<T>& e = g(g[u][j]);
            T df;
            if(d[e.v] == d[u] + 1 and e.resid() > 0 and (df = augment(e.v, min(b, e.resid())))) {
                e.f += df, g(g[u][j] ^ 1).f -= df;
                return df;
            }
        }
        return T(0);
    };
    T ans = 0;
    while(make_level_graph()) {
        fill(adj_ptr.begin(), adj_ptr.end(), 0);
        while(T df = augment(s, numeric_limits<T>::max())) {
            ans += df;
        }
    }
    return ans;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int h, w;
    cin >> h >> w;
    int s = h + w, t = s + 1;
    flow_graph<int, 0> g(t + 1);
    int si, sj, ti, tj;
    for(int i = 0; i < h; i++) {
        string s;
        cin >> s;
        for(int j = 0; j < w; j++) {
            if(s[j] != '.') {
                g.add_edge({i, h + j, 1});
                g.add_edge({h + j, i, 1});
            }
            if(s[j] == 'S') {
                si = i, sj = j;
            } else if(s[j] == 'T') {
                ti = i, tj = j;
            }
        }
    }
    g.add_edge({s, si, h * w});
    g.add_edge({s, h + sj, h * w});
    g.add_edge({ti, t, h * w});
    g.add_edge({h + tj, t, h * w});
    cout << (si != ti and sj != tj ? max_flow<int, 0>(g, s, t) : -1) << endl;
    return 0;
}


Measured memory_bytes: 1528