#include <iostream>
#include <cstdio>
#include <algorithm>
#include <vector>
#include <map>
#include <queue>
#include <set>
#include <cmath>
#include <list>
#include <chrono>
#include <thread>

using namespace std;

const bool debug = false;

#ifndef M_PI
    const double M_PI = acos(-1.0);
#endif // M_PI

#define y1 roman_kaban
#define rank oryshych_konb
#define ull unsigned long long
//#define ll long long
//const int mod = int(1e9) + 7;
//const int inf = 1e9;
const long long infLL = 1e16;
//const int MX2 = 10100500; //  e7
//const long long INF = 1e18 + 0.5;
const int MX = 3100500; //       e5
const int SZ = 2100;
//const int delta = 1 << 19;


int s, t;
int w, h;

int get_v(int x, int y){
    int ans = x * w + y;
    return ans * 2;
}

struct edge{
    int u;
    int v;
    int rev;
    int cap;
    edge(int _u, int _v, int _rev, int _cap){
        u = _u;
        v = _v;
        rev = _rev;
        cap = _cap;
    }
};

vector<edge> e[MX];

void simple_add(int u, int v, int cap){
    e[u].push_back(edge(u, v, int(e[v].size()), cap));
    e[v].push_back(edge(v, u, e[u].size() - 1, 0));
    //cerr << "add " << u << ' ' << v <<  ' ' << cap << endl;
}

bool ok = true;

void add_edge(int u, int v){
    if(u + 1 == s && v == t) ok = false;
    if(v + 1 == s && u == t) ok = false;
    simple_add(u + 1, v, int(1e5));
    simple_add(v + 1, u, int(1e5));
}

int sp[MX];
int o = 0;
int visited[MX];
pair<int,int> pr[MX];
int it[MX];

int go2(int u, int cap){
    //cerr << u << ' ' << cap << endl;
    if(u == t || cap == 0) return cap;
    int ans = 0;
    while(it[u] != e[u].size()){
        edge &curr = e[u][it[u]++];
        int &v = curr.v;
        int mx_flow = min(cap, curr.cap);
        //cerr << u << ' ' << v << ' ' << mx_flow << endl;
        if(visited[u] + 1 != visited[v] || mx_flow == 0) continue;
        int z = go2(v, mx_flow);
        if(z){
            curr.cap -= z;
            e[v][ curr.rev ].cap += z;
            ans += z;
            cap -= z;
            if(cap == 0){
                it[u]--;
                return ans;
            }
        }
    }
    return ans;
}

int go(){
    o += 1e5;
    int k = 0;
    sp[0] = s;
    int l = 1;
    visited[s] = o;
    while(k < l){
        int &u = sp[k++];
        it[u] = 0;
        //cerr <<"!"<< u << ' ' << visited[u] << endl;
        for(int i = 0; i < e[u].size(); i++){
            if(e[u][i].cap == 0) continue;
            int &v = e[u][i].v;
            //cerr << "?" << v << ' ' << visited[v] << endl;
            if(visited[v] >= o) continue;
            visited[v] = visited[u] + 1;
            sp[l++] = v;
        }
    }
    int ans =0 ;
    while(true){
        int z = go2(s, 1e9);
        if(z) ans += z; else return ans;
    }
}

string st[SZ];

int main()
{
    ios_base::sync_with_stdio(false);
    //if(debug)
//freopen("/Users/ozzy/Documents/in.txt","r", stdin);
//    freopen("/Users/ozzy/Documents/C-small-attempt1.in.txt","r", stdin);
//freopen("/Users/ozzy/Documents/out.txt","w", stdout);
    cin >> h >> w;
    for(int i = 0; i < h; i++){
        cin >> st[i];
        for(int j = 0; j < w; j++){
            if(st[i][j] == 'S'){ s = get_v(i, j) + 1; st[i][j] = 'o'; }
            if(st[i][j] == 'T'){ t = get_v(i, j); st[i][j] = 'o'; }
        }
    }
    //cerr << s << ' ' << t << endl;

    for(int i = 0; i < h; i++){
        for(int j = 0; j < w; j++){
            if(st[i][j] == 'o'){
                for(int x = i + 1; x < h; x++){
                    if(st[x][j] == 'o'){
                        add_edge(get_v(i, j), get_v(x, j));
                    }
                }
                for(int y = j + 1; y < w; y++){
                    if(st[i][y] == 'o'){
                        add_edge(get_v(i, j), get_v(i, y));
                    }
                }
            }
        }
    }
    for(int i = 0; i < w * h; i++){
        simple_add(2 * i, 2 * i + 1, 1);
    }
    if(!ok) {cout << -1 << endl; return 0;}
    int ans = 0;
    while(true){
        int z = go();
        if(z) ans += z; else break;
    }
    //if(ans > h * w) ans = -1;
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 161280