#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