#include <bits/stdc++.h>
    using namespace std;
    using ll = long long;
    #define FOR(i, a, b) for (int i = (a); i < int(b); ++i)
    #define RFOR(i, a, b) for (int i = (b)-1; i >= int(a); --i)
    #define rep(i, n) FOR(i, 0, n)
    #define rep1(i, n) FOR(i, 1, int(n) + 1)
    #define rrep(i, n) RFOR(i, 0, n)
    #define rrep1(i, n) RFOR(i, 1, int(n) + 1)
    #define all(c) begin(c), end(c)
    const int MOD = 1000000007;
     
     
    template <typename T>
    void __dump__(std::ostream &os, const T &first) {
        os << first;
    }
    template <typename First, typename... Rest>
    void __dump__(std::ostream &os, const First &first, const Rest &... rest) {
        os << first << ", ";
        __dump__(os, rest...);
    }
    #define dump(...)                                         \
        do {                                                  \
            std::ostringstream os;                            \
            os << __LINE__ << ":\t" << #__VA_ARGS__ << " = "; \
            __dump__(os, __VA_ARGS__);                        \
            std::cerr << os.str() << std::endl;               \
        } while (0)
     
    const int INF = 1e6;
     
    using Weight = int;
    using Flow = int;
    struct Edge {
        int src, dst;
        Weight weight;
        Flow cap;
        Edge() : src(0), dst(0), weight(0) {}
        Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
    };
    using Edges = std::vector<Edge>;
    using Graph = std::vector<Edges>;
    using Array = std::vector<Weight>;
    using Matrix = std::vector<Array>;
     
    void add_edge(Graph &g, int a, int b, Weight w = 1) {
        g[a].emplace_back(a, b, w);
        g[b].emplace_back(b, a, w);
    }
    void add_arc(Graph &g, int a, int b, Weight w = 1) { g[a].emplace_back(a, b, w); }
     
    struct Dinic {
    public:
        using Flow = int;
        Dinic(int n_) : n(n_), g(n_) {}
        Flow maximum_flow(int s_, int t_) {
            s = s_;
            t = t_;
            que.resize(n);
            Flow res = 0;
            while (levelize()) {
                prog.assign(n, 0);
                res += augment(s, std::numeric_limits<Flow>::max());
            }
            return res;
        }
        void add_edge(int u, int v, Flow c) {
            if (u == v || c == 0) return;
            g[u].push_back({u, v, c, 0, (int)g[v].size()});
            g[v].push_back({v, u, c, c, (int)g[u].size() - 1});
        }
     
    private:
        struct Edge {
            int s, d;
            Flow c, f;
            int r;
        };
        int n, s, t;
        std::vector<std::vector<Edge>> g;
        std::vector<int> level, prog, que;
     
        bool levelize() {
            int fst = 0, lst = 0;
            que[lst++] = s;
            level.assign(n, -1);
            level[s] = 0;
            while (fst != lst) {
                int v = que[fst++];
                if (v == t) break;
                for (auto &e : g[v]) {
                    if (level[e.d] == -1 && residue(e) != 0) {
                        level[e.d] = level[v] + 1;
                        que[lst++] = e.d;
                    }
                }
            }
            return level[t] != -1;
        }
        Flow augment(int v, Flow lim) {
            Flow res = 0;
            if (v == t) return lim;
            for (int &i = prog[v]; i < (int)g[v].size(); ++i) {
                if (lim == 0) break;
                auto &e = g[v][i];
                if (level[v] < level[e.d] && residue(e) != 0) {
                    Flow aug = augment(e.d, std::min(lim, residue(e)));
                    if (aug == 0) continue;
                    e.f += aug;
                    reverse(e).f -= aug;
                    res += aug;
                    lim -= aug;
                }
            }
            return res;
        }
        Flow residue(const Edge &e) { return e.c - e.f; }
        Edge &reverse(const Edge &e) { return g[e.d][e.r]; }
     
    public:
        void show() {
            rep(i, n) {
                for (auto &e : g[i]){
                    printf("%2d -> %2d (%2d/%2d)\n", e.s, e.d, e.f, e.c);
                }
            }
        }
    };
     
    signed main() {
        int h, w;
        while (cin >> h >> w && h) {
            vector<string> g(h);
     
            rep(i, h) {
                cin >> g[i];
            }
            Dinic dn(h * w * 2);
            rep(i, h) {
                rep(j1, w) rep(j2, w) if (j1 != j2) {
                    if (g[i][j1] != '.' && g[i][j2] != '.') {
                        int u = i*w + j1;
                        int v = i*w + j2 + h*w;
                        dn.add_edge(u, v, INF);
                    }
                }
            }
            rep(j, w) {
                rep(i1, h) rep(i2, h) if (i1 != i2) {
                    if (g[i1][j] != '.' && g[i2][j] != '.') {
                        int u = i1*w + j;
                        int v = i2*w + j + h*w;
                        dn.add_edge(u, v, INF);
                    }
                }
            }
     
            rep(i, h) rep(j, w) {
                if (g[i][j] != '.') {
                    int cost;
                    if (g[i][j] == 'S' || g[i][j] == 'T') {
                        cost = INF;
                    } else {
                        cost = 1;
                    }
                    int u = i*w + j;
                    int v = i*w + j + h*w;
                    dn.add_edge(v, u, cost);
                }
            }
     
            int si = -1, sj = -1, ti = -1, tj = -1;
            rep(i, h) rep(j, w) {
                if (g[i][j] == 'S') si = i, sj = j;
                if (g[i][j] == 'T') ti = i, tj = j;
            }
            dump(si*w + sj, ti*w + tj + h*w);
            if (si == ti || sj == tj) {
                cout << -1;
            } else {
                cout << dn.maximum_flow(si*w + sj,
                                        ti*w + tj + h*w);
            }
            cout << endl;
            //dn.show();
        }
    }

Measured memory_bytes: 102016