#include <algorithm>
#include <cassert>
#include <climits>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
//#include <regex>

/* g++ -g -std=c++0x */
/* g++ -g -std=c++11 */

using namespace std;

// std::ios::sync_with_stdio(false);

// freopen("input.txt", "rt", stdin);
// freopen("output.txt", "wt", stdout);

#define ALL(c)          (c).begin(), (c).end()
#define ALLR(c)         (c).rbegin(), (c).rend()
#define FOR(i,a,b)      for (int i=(a); i < (b); ++i)
#define FORR(i,a,b)     for (int i=(a); i > (b); --i)
#define FOR_ALL(i,c)    for (__typeof((c).begin()) i=(c).begin();   \
                             i != (c).end(); ++i)
#define FOR_ALLR(i,c)   for (__typeof((c).rbegin()) i=(c).rbegin(); \
                             i != (c).rend(); ++i)
#define SZ(array)       (sizeof(array)/sizeof(array[0]))
#define lc(x)           (x<<1)     /* 2*x */
#define rc(x)           (x<<1 | 1) /* 2*x+1 */
#define lowbit(x)       (x & (-x)) /* 0b10100 -> 0b100 */

typedef long long       LL;
typedef map<int,int>    MII;
typedef pair<int,int>   PII;
typedef set<int>        SI;
typedef vector<bool>    VB;
typedef vector<double>  VD;
typedef vector<int>     VI;
typedef vector<string>  VS;

/* check if a key is in container C */
template <class C>
inline bool in_(const typename C::key_type& k, const C& A)
{ return A.find(k) != A.end(); }
inline bool in_(const string& s, const string& S)
{ return S.find(s) != string::npos; }

const int inf = 1e9;

struct Network {
    static const int maxv = 1e5;
    static const int maxe = 5e6;
    struct Edge { int u,v,cap,next,tag; } E[maxe];
    int ne, head[maxv], head_[maxv], dis[maxv], Q[maxv], du[maxv];

    void init()
    {
        ne = 0;
        memset(head,-1,sizeof(head));
        memset(du,0,sizeof(du));
    }

    void addedge(const int u, const int v, const int c, const int tag=0)
    {
        assert(0 <= u && u < maxv && 0 <= v && v < maxv);
        assert(ne < maxe-1);
        E[ne].u = u; E[ne].v = v; E[ne].cap = c; E[ne].tag = tag;
        E[ne].next = head[u]; head[u] = ne++;
        E[ne].u = v; E[ne].v = u; E[ne].cap = 0; E[ne].tag = 0;
        E[ne].next = head[v]; head[v] = ne++;
    }

    bool bfs(const int src, const int sink)
    {
        memset(dis,-1,sizeof(dis));
        int front,end; front = 0; end = 1; Q[front] = src; dis[src] = 0;
        while (front != end) {
            const int u = Q[front++];
            for (int i = head[u]; i != -1; i = E[i].next) {
                const int v = E[i].v;
                if (E[i].cap && dis[v] == -1) {
                    dis[v] = dis[u]+1; Q[end++] = v;
                }
            }
        }
        return dis[sink] != -1;
    }

    int dfs(const int u, const int sink, const int flow)
    {
        if (u == sink)
            return flow;
        for (int& i = head_[u]; i != -1; i = E[i].next) {
            const int v = E[i].v;
            const int minf = min(E[i].cap, flow);
            int f;
            if (E[i].cap && dis[v]==dis[u]+1 && (f=dfs(v,sink,minf))) {
                E[i].cap -= f; E[i^1].cap += f;
                return f;
            }
        }
        return 0;
    }

    int dinic(const int src, const int sink)
    {
        int flow = 0;
        while (bfs(src,sink)) {
            memcpy(head_,head,sizeof(head));
            int f;
            while (f = dfs(src,sink,inf)) {
                flow += f;
                flow = min(flow,inf);
            }
        }
        return flow;
    }

    int maxflow(const int src, const int sink)
    { return dinic(src,sink); }
} G;

const int maxn = 110;
char A[maxn][maxn];
int H,W;

int ij2v(const int i, const int j)
{ return i*W + j; }

int main()
{
/* #ifndef ONLINE_JUDGE */
/*     freopen("foo", "rt", stdin); */
/* #endif */
    while (cin >> H >> W) {
        G.init();
        set<char> leaf = {'S','T','o'};
        const int N = H*W;
        int src,tgt;
        FOR(i,0,H) FOR(j,0,W) {
            cin >> A[i][j];
            if (A[i][j] == 'S')
                src = ij2v(i,j);
            if (A[i][j] == 'T')
                tgt = ij2v(i,j);
        }
        FOR(i,0,H) FOR(j,0,W) if (in_(A[i][j],leaf)) {
            const int u = ij2v(i,j);
            const int v = u + N;
            const int c = A[i][j] == 'o' ? 1 : inf;
            G.addedge(u,v,c);
            FOR(k,i+1,H) if (in_(A[k][j],leaf)) {
                const int x = ij2v(k,j);
                const int y = x + N;
                G.addedge(v,x,inf);
                G.addedge(y,u,inf);
            }
            FOR(k,j+1,W) if (in_(A[i][k],leaf)) {
                const int x = ij2v(i,k);
                const int y = x + N;
                G.addedge(v,x,inf);
                G.addedge(y,u,inf);
            }
        }
        const int f = G.maxflow(src,tgt);
        const int ans = f < inf ? f : -1;
        cout << ans << endl;
    }
    return 0;
}


Measured memory_bytes: 81152