#include <bits/stdc++.h>

using flow_type = int;

struct dinic {
    struct edge {
        int src, dst;
        flow_type cap, flow;
        edge *next, *rev;

        flow_type residue() const {
            return cap - flow;
        }

        void *operator new (std::size_t) {
            constexpr std::size_t MAX_E = 5000010;
            static edge pool[MAX_E];
            static std::size_t p = 0;
            return pool + p++;
        }
    };
    int n, source, sink;
    edge **g;
    int *level, *queue;
    edge **prog;

    dinic(int n_ = 0) :
        n(n_), g(new edge*[n]()), level(new int[n]), queue(new int[n]), prog(new edge*[n]) { }

    ~dinic() {
        delete[] g;
        delete[] level;
        delete[] queue;
        delete[] prog;
    }

    flow_type maximum_flow(int source_, int sink_) {
        source = source_;
        sink = sink_;
        flow_type res = 0;
        while (levelize()) {
            std::copy(g, g + n, prog);
            res += augment(source, std::numeric_limits<flow_type>::max());
        }
        return res;
    }

    edge *add_edge1(int u, int v, flow_type c, flow_type f) {
        return g[u] = new edge { u, v, c, f, g[u], nullptr };
    }

    std::pair<edge*, edge*> add_edge(int u, int v, flow_type c) {
        if (u == v || c == 0) return { nullptr, nullptr };
        auto uv = add_edge1(u, v, c, 0);
        auto vu = add_edge1(v, u, c, c);
        uv->rev = vu;
        vu->rev = uv;
        return {uv, vu};
    }

    bool levelize() {
        int fst = 0, lst = 0;
        queue[lst++] = source;
        std::fill(level, level + n, -1);
        level[source] = 0;
        while (fst != lst) {
            int v = queue[fst++];
            if (v == sink) break;
            for (auto e = g[v]; e != nullptr; e = e->next) {
                if (level[e->dst] == -1 && e->residue() != 0) {
                    level[e->dst] = level[v] + 1;
                    queue[lst++] = e->dst;
                }
            }
        }
        return level[sink] != -1;
    }

    flow_type augment(int v, flow_type lim) {
        flow_type res = 0;
        if (v == sink) return lim;
        for (auto &e = prog[v]; e; e = e->next) {
            if (lim == 0) break;
            if (level[v] < level[e->dst] && e->residue() != 0) {
                flow_type aug = augment(e->dst, std::min(lim, e->residue()));
                if (aug == 0) continue;
                e->flow += aug;
                e->rev->flow -= aug;
                res += aug;
                lim -= aug;
            }
        }
        return res;
    }
};

using namespace std;

// int main() {
//     int N, M;
//     cin >> N >> M;
//     dinic g(N);
//     while (M--) {
//         int a, b, c;
//         cin >> a >> b >> c;
//         g.add_edge(a, b, c);
//     }
//     cout << g.maximum_flow(0, N - 1) << endl;
// }
#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;

const int INF = 1e6;

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: 125696