#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 Node
{
    T value;
    Node<T> *left;
    Node<T> *right;
};

template <typename T>
struct List
{
    Node<T> *first;
    Node<T> *last;
    int size;
    
    List() : first(nullptr), last(nullptr), size(0) {}
    
    void insert(Node<T> *node){
        if(size == 0){
            first = node;
            last = node;
            node->right = node;
            node->left = node;
        }
        else{
            node->right = first;
            node->left = last;
            first = node;
        }
        size++;
    }
    
    Node<T> *insert(T value){
        Node<T> *node;
        node = new Node<T>;
        node->value = value;
        insert(node);
        return node;
    }
    
    Node<T> *erase(Node<T> *node){
        if(size == 1){
            first = nullptr;
            last = nullptr;
            size--;
            return nullptr;
        }
        else{
            if(node == first) first = node->right;
            if(node == last) last = node->left;
            node->left->right = node->right;
            node->right->left = node->left;
            size--;
            return node->right;
        }
    }
};

template <typename T>
struct Flow
{
    int n;
    vector<vector<Edge<T>>> g;
    vector<int> label;
    vector<int> f;
    vector<int> itr;
    vector<Node<int>*> ptr;
    vector<bool> active;
    vector<List<int>> d;
    
    Flow(int n) : n(n){
        g.resize(n);
        label.resize(n);
        f.resize(n);
        itr.resize(n);
        ptr.resize(n);
        active.resize(n);
        d.resize(n * 2 + 1);
    }
    
    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});
    }
    
    void relabel(int u){
        d[label[u]].erase(ptr[u]);
        label[u]++;
        d[label[u]].insert(ptr[u]);
        itr[u] = 0;
    }
    
    void activete(int u){
        active[u] = true;
        d[label[u]].insert(ptr[u]);
    }
    
    void inactivate(int u){
        active[u] = false;
        d[label[u]].erase(ptr[u]);
    }
    
    void push(int u, int r, int s){
        for(int &i = itr[u]; i < (int)g[u].size(); i++){
            Edge<T> &e = g[u][i];
            int v = e.to;
            if(label[v] < label[u] && e.cap > 0){
                if(!active[v] && v != r && v != s) activete(v);
                if(f[u] <= e.cap){
                    e.cap -= f[u];
                    g[v][e.rev].cap += f[u];
                    f[v] += f[u];
                    f[u] = 0;
                    inactivate(u);
                    break;
                }
                f[u] -= e.cap;
                f[v] += e.cap;
                g[v][e.rev].cap = e.cap;
                e.cap = 0;
            }
        }
        if(f[u]) relabel(u);
    }
    
    int max_flow(int r, int s){
        for(int i = 0; i < n; i++){
            ptr[i] = new Node<T>;
            ptr[i]->value = i;
        }
        label[r] = n;
        for(Edge<T> &e : g[r]){
            if(e.cap == 0) continue;
            int v = e.to;
            f[r] -= e.cap;
            f[v] += e.cap;
            g[v][e.rev].cap = e.cap;
            e.cap = 0;
            if(v != s) activete(v);
        }
        int h = 0;
        while(h >= 0){
            if(d[h].size == 0){
                h--;
                continue;
            }
            int u = d[h].first->value;
            push(u, r, s);
            h++;
        }
        return f[s];
    }
};

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;
}


Measured memory_bytes: 4204