#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <stack>
#include <queue>
#include <functional>
#include <algorithm>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <vector>
#include <array>
#include <tuple>
#include <utility>
#include <numeric>
#include <iomanip>
#include <cctype>
#include <cmath>
#include <assert.h>
#include <cstdlib>
#include <list>
using namespace std;

#define repeat(i, x) for (long long i = 0; (i) < (long long)(x); (i)++)
#define rrepeat(i, x) for (long long i = (long long)((x) - 1); (i) >= 0; (i)--)
#define traverse(it, ctn) for (auto it = (ctn).begin(); (it) != (ctn).end(); (it)++)
#define rtraverse(it, ctn) for (auto it = (ctn).rbegin(); (it) != (ctn).rend(); (it)++)
#define enumerate(i, a, b) for (long long i = (long long)(a); (i) < (long long)(b); (i)++)

template<typename T> void chmax(T& a1, T a2) { a1 = std::max(a1, a2); }
template<typename T> void chmin(T& a1, T a2) { a1 = std::min(a1, a2); }

template<typename T1, typename T2> ostream& operator<<(ostream& os, const pair<T1, T2>& p) { return os << "(" << p.first << ", " << p.second << ")"; }
template<typename T> ostream& operator<<(ostream& os, const vector<T>& v) { os << "["; for (int i = 0; i < v.size(); i++) os << (i == 0 ? "" : ", ") << v[i]; os << "]"; return os; }
template<typename T1, typename T2> ostream& operator << (ostream& os, map<T1, T2>& mp) { os << "{"; for (auto it = mp.begin(); it != mp.end(); it++) { os << "(" << it->first << ": " << it->second << ")"; it++; if(it != mp.end()) os << ", "; it--; } os << "}"; return os; }
template<typename T> ostream& operator << (ostream& os, set<T>& st) { os << "{"; for (auto it = st.begin(); it != st.end(); it++) { os << *it; ++it; if(it != st.end()) os << ", "; it--; } os << "}"; return os; }

using int64 = long long;
using Cost = int;

const int INF = (1 << 28);

struct FArc {
    int from, to, cap;
    Cost cost;
    int rev;

    FArc() {}
    FArc(int from, int to, int cap) : from(from), to(to), cap(cap) {}
    FArc(int from, int to, int cap, Cost cost) : from(from), to(to), cap(cap),
                                                 cost(cost) {}
    FArc(int from, int to, int cap, Cost cost, int rev) :
        from(from), to(to), cap(cap), cost(cost), rev(rev) {}
};

using FGraph = vector<vector<FArc>>;

void add_farc(FGraph& fg, int from, int to, int cap, Cost cost = -1) {
    fg[from].push_back(FArc(from, to, cap, cost, fg[to].size()));
    fg[to].push_back(FArc(to, from, 0, -cost, fg[from].size() - 1));
}

namespace FordFulkerson {
    const int MAX_V = 1000;
    const int INF = (1 << 28);

    FGraph fgraph;
    int source, sink;
    array<bool, MAX_V> used;

    void initialize(FGraph& fg, int s, int t) {
        fgraph = fg;
        source = s;
        sink = t;
    }

    int dfs(int v, int flow) {
        if (v == sink) {
            return flow;
        }
        used[v] = true;
        for (FArc& fa : fgraph[v]) {
            if (!used[fa.to] && fa.cap > 0) {
                int d = dfs(fa.to, min(flow, fa.cap));
                if (d > 0) {
                    fa.cap -= d;
                    fgraph[fa.to][fa.rev].cap += d;
                    return d;
                }
            }
        }
        return 0;
    }

    int solve() {
        int flow = 0;
        while (true) {
            used.fill(false);
            int f = dfs(source, INF);
            if (f == 0) {
                break;
            }
            flow += f;
        }
        return flow;
    }
};

static string a[110];

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int H, W;
    cin >> H >> W;

    int S = H + W;
    int T = S + 1;

    FGraph fg(H + W + 2);

    for (int r = 0; r < H; r++) {
        cin >> a[r];
        for (int c = 0; c < W; c++) {
            int rnode = r, cnode = H + c;
            if (a[r][c] == 'o') {
                add_farc(fg, rnode, cnode, 1);
                add_farc(fg, cnode, rnode, 1);
            } else if (a[r][c] == 'S') {
                add_farc(fg, S, rnode, INF);
                add_farc(fg, S, cnode, INF);
            } else if (a[r][c] == 'T') {
                add_farc(fg, rnode, T, INF);
                add_farc(fg, cnode, T, INF);
            }
        }
    }

    FordFulkerson::initialize(fg, S, T);
    int cut = FordFulkerson::solve();
    
    if (cut >= INF) cout << -1 << endl;
    else cout << cut << endl;

    return 0;
}


Measured memory_bytes: 2048