#include <bits/stdc++.h>
using namespace std;
using pint = pair<int, int>;
using ll = long long;
using ull = unsigned long long;
using vll = vector<long long>;
using pll = pair<ll, ll>;
#define FOR(i, begin, end) \
    for (int i = (begin), i##_end_ = (end); i < i##_end_; i++)
#define IFOR(i, begin, end) \
    for (int i = (end)-1, i##_begin_ = (begin); i >= i##_begin_; i--)
#define REP(i, n) FOR(i, 0, n)
#define IREP(i, n) IFOR(i, 0, n)
#define VREP(s, ite) for (auto ite = s.begin(); ite != s.end(); ++ite)
#define FI first
#define SE second
#define ALL(v) v.begin(), v.end()
#define endl "\n"
#define ciosup  \
    cin.tie(0); \
    ios::sync_with_stdio(false);
#define eb emplace_back
#define vint vector<int>
constexpr ll INF = 1e15 + 7LL;
constexpr ll MOD = ll(1e9) + 7LL;

template <typename T>
istream &operator>>(istream &is, vector<T> &v) {
    for (int i = 0; i < v.size(); ++i) {
        is >> v[i];
    }
    return is;
}
template <typename T>
ostream &operator<<(ostream &os, const vector<T> &v) {
    if (v.size() == 0) return os;
    for (int i = 0; i < v.size() - 1; ++i) {
        os << v[i] << " ";
    }
    os << v[v.size() - 1];
    return os;
}

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

int dfs(int v, int t, int f, vector<bool>& used, vector<vector<edge>>& G) {
    if (v == t) return f;
    used[v] = true;
    REP(i, G[v].size()) {
        edge& e = G[v][i];
        if (!used[e.to] && e.cap > 0) {
            int d = dfs(e.to, t, min(f, e.cap), used, G);
            if (d > 0) {
                e.cap -= d;
                G[e.to][e.rev].cap += d;
                return d;
            }
        }
    }
    return 0;
}

void solve() {
    int h, w;
    cin >> h >> w;
    vector<vector<char>> G(h, vector<char>(w));
    pint st, go;
    REP(i, h) {
        REP(j, w) {
            cin >> G[i][j];
            if (G[i][j] == 'S') {
                st = make_pair(i, j);
            }
            if (G[i][j] == 'T') {
                go = make_pair(i, j);
            }
        }
    }
    vector<vector<edge>> GS(h + w);
    REP(i, h) {
        REP(j, w) {
            if (G[i][j] == 'o') {
                GS[i].push_back({h + j, 1, (int)GS[h + j].size()});
                GS[h + j].push_back({i, 0, (int)GS[i].size() - 1});

                GS[h + j].push_back({i, 1, (int)GS[i].size()});
                GS[i].push_back({h + j, 0, (int)GS[h + j].size() - 1});
            }
        }
    }
    if (st.first == go.first || st.second == go.second) {
        cout << -1 << endl;
        return;
    }
    GS[st.first].push_back({st.second + h, 103, (int)GS[h + st.second].size()});
    GS[st.second + h].push_back({st.first, 0, (int)GS[st.first].size() - 1});

    GS[st.second + h].push_back({st.first, 103, (int)GS[st.first].size()});
    GS[st.first].push_back({st.second + h, 0, (int)GS[st.second + h].size() - 1});

    GS[go.first].push_back({go.second + h, 103, (int)GS[h + go.second].size()});
    GS[go.second + h].push_back({go.first, 0, (int)GS[go.first].size() - 1});

    GS[go.second + h].push_back({go.first, 103, (int)GS[go.first].size()});
    GS[go.first].push_back({go.second + h, 0, (int)GS[go.second + h].size() - 1});
    
    int flow1 = 0;
    vector<bool> used(h + w);
    while (true) {
        REP(i, h + w) {
            used[i] = false;
        }
        int f = dfs(st.first, go.first, INT_MAX / 2, used, GS);
        if (f == 0) break;
        flow1 += f;
    }
    cout << flow1 << endl;
}

int main() {
    char tmp;
    while (cin >> tmp) {
        cin.putback(tmp);
        solve();
    }
}


Measured memory_bytes: 4256