#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int INF = 10000000;

template <typename T>
struct Edge
{
    int to;
    T cap;
    int rev;
};

template <typename T>
struct Flow
{
    int n, c;
    vector<vector<Edge<T>>> g;
    vector<int> ch;
    
    Flow(int n) : n(n), c(1){
        g.resize(n);
        ch.resize(n);
    }
    
    void add_edge(int from, int to, T cap){
        g[from].push_back((Edge<T>){to, cap, (int)g[to].size()});
        g[to].push_back((Edge<T>){from, 0, (int)g[from].size() - 1});
    }
    
    T dfs(int u, T f, int t){
        if(u == t) return f;
        ch[u] = c;
        for(int i = 0; i < (int)g[u].size(); i++){
            Edge<T> &e = g[u][i];
            int v = e.to;
            if(e.cap > 0 && ch[v] != c){
                T fl = dfs(v, min(f, e.cap), t);
                if(fl > 0){
                    e.cap -= fl;
                    g[v][e.rev].cap += fl;
                    return fl;
                }
            }
        }
        return 0;
    }
    
    T max_flow(int s, int t){
        T res = 0;
        for(T f; (f = dfs(s, INF, t)) > 0; c++) res += f;
        return res;
    }
};

int main()
{
    int h, w;
    cin >> h >> w;
    string a[102];
    Flow<int> g(h + w + 2);
    for(int i = 0; i < h; i++){
        cin >> a[i];
        for(int j = 0; j < w; j++){
            if(a[i][j] == 'S'){
                g.add_edge(h + w, i, INF);
                g.add_edge(h + w, j + h, INF);
            }
            if(a[i][j] == 'T'){
                g.add_edge(i, h + w + 1, INF);
                g.add_edge(j + h, h + w + 1, INF);
            }
            if(a[i][j] == 'o'){
                g.add_edge(i, j + h, 1);
                g.add_edge(j + h, i, 1);
            }
        }
    }
    int ans = g.max_flow(h + w, h + w + 1);
    if(ans >= INF) cout << -1 << endl;
    else cout << ans << endl;
}