#include <iostream>
#include <fstream>
#include <sstream>
#include <string.h>
#include <algorithm>
#include <cmath>
#include <assert.h>
#include <stack>
#include <queue>
#include <list>
#include <vector>
#include <map>
#include <set>

//#define DEBUG 1

#define for0(i,n) for (int i=0; i<n; i++)
#define forr(i,n) for (int i=n-1; i>=0; i--)
#define fori(i,a,b) for (int i=a; i<=b; i++)
#define iter(c) for(auto it=c.begin(); it!=c.end(); it++)
#define vec(x) vector< x >
#define pb push_back
#define ms(a,z) memset(a,z,sizeof(a));
#define mp make_pair
#define X first
#define Y second
#define sqr(x) 1LL*(x)*(x)
#define max(a,b) ((a)>(b)?(a):(b))
#define min(a,b) ((a)<(b)?(a):(b))
#define all(a) a.begin(),a.end()
#define size(x) (int)(x).size()
#define read(x) int x; scanf("%d",&x);
#ifdef DEBUG
#define nl cout<<"\n";
#define pr(x) cout<<(x)<<" ";
#define prl(x) cout<<#x " = "<<x<<endl;
#define prp(x) cout<<"("<<(x).first<<" "<<(x).second<<") ";
#define printv(v) {for(int _=0; _<size(v); _++) cout<<v[_]<<" "; cout<<"\n";}
#define printa(a,s) {for (int _=0; _<s; _++) cout<<a[_]<<" "; cout<<"\n";}
#define print2D(a,m,n) {for (int _=0; _<m; _++) {for (int __=0; __<n; __++) cout<<a[_][__]<<" "; cout<<"\n";} cout<<"\n";}
#define debug cout<<"ok at line "<<__LINE__<<endl;
#else
#define nl
#define pr(x)
#define prl(x)
#define prp(x)
#define printv(v)
#define printa(a,s)
#define print2D(a,m,n)
#define debug
#endif

using namespace std;

typedef long long ll;

const int INF = 2147483647;
const long long INFL = 9223372036854775807LL;
const double EPSILON = 0.00000001;
const long long MOD = 1000000007;

int H, W, N;

int graph[205][205];
int from[205];
bool visited[205];

bool bfs(int source, int sink)
{
    queue<int> q;
    ms(visited,false);
    ms(from,-1);
    visited[source] = true;
    q.push(source);

    while (!q.empty()) {
        int top = q.front(); q.pop();
        if (top == sink)
            return true;
        for0(i,N) {
            if (!visited[i] && graph[top][i] > 0) {
                visited[i] = true;
                q.push(i);
                from[i] = top;
            }
        }
    }
    return false;
}

int main()
{
    #ifdef DEBUG
    freopen("D.txt","r",stdin);
    //freopen("","w",stdout);
    #endif

    scanf("%d %d",&H,&W);
    int source = H+W;
    int sink = H+W+1;
    N = H+W+2;
    ms(graph,0);
    pair<int,int> src_point, sink_point;

    for0(y,H) {
        string row;
        cin >> row;
        for0(x,W) {
            if (row[x] == 'S') {
                graph[source][y] = INF;
                graph[source][H+x] = INF;
                src_point = mp(x,y);
            }
            else if (row[x] == 'T') {
                graph[y][sink] = INF;
                graph[H+x][sink] = INF;
                sink_point = mp(x,y);
            }
            else if (row[x] == 'o') {
                graph[y][H+x] = graph[H+x][y] = 1;
            }
        }
    }
    if (src_point.X == sink_point.X || src_point.Y == sink_point.Y) {
        cout<<-1<<endl;
        return 0;
    }

    //print2D(graph,N,N);

    /*for0(i,H+W+2) {
        prl(i)
        for0(j,size(adj[i]))
            prp(adj[i][j])
        nl
    }*/

    bool success = bfs(source, sink);
    int iters = 0;
    int flow = 0;
    while(success) {
        int capacity = INF;
        int cur = sink;
        while (from[cur] != -1) {
            capacity = min(capacity, graph[from[cur]][cur]);
            cur = from[cur];
        }
        cur = sink;
        flow += capacity;
        //prl(capacity)

        while (from[cur] != -1) {
            graph[from[cur]][cur] -= capacity;
            graph[cur][from[cur]] += capacity;
            cur = from[cur];
        }
        //print2D(graph,N,N);
        success = bfs(source, sink);
        iters++;
    }

    if (flow >= INF) {
        cout<<-1<<endl;
    }
    else {
        cout<<flow<<endl;
    }
    return 0;
}


Measured memory_bytes: 384