#include <iostream>
#include <vector>
#include <algorithm>
#include <string>
#include <set>
#include <map>
#include <list>
#include <time.h>
#include <math.h>
#include <random>
#include <deque>
#include <queue>
#include <cassert>
#include <iomanip>

using namespace std;

mt19937 Rand(16092002);
mt19937_64 BigRand(16092002);

typedef long long ll;

typedef long long ll;

struct edge
{
    int v, to, cap;
    edge(int a, int b, int c)
    {
        v = a, to = b, cap = c;
    }
    edge() {}
};

const int N = 1e6 + 7;

vector <edge> e;
vector <int> g[N];
int us[N];
int usbs = 1;
int d[N];
int q[N];
int ded[N];
int ptr[N];
int after_bfs = 1;
int visb = 1;
ll ans = 0;
int qh, qt;
int s, t;
int l;

void add_edge(int u, int v, int cap)
{
    g[u].push_back(e.size());
    e.push_back({u, v, cap});
    g[v].push_back(e.size());
    e.push_back({v, u, 0});
}

bool bfs()
{
    qh = qt = 0;
    us[s] = usbs;
    q[qt++] = s;
    d[s] = 0;
    while (qh < qt)
    {
        int v = q[qh++];
        for (auto c : g[v])
        {
            if (us[e[c].to] != usbs && e[c].cap >= l)
            {
                d[e[c].to] = d[v] + 1;
                us[e[c].to] = usbs;
                q[qt++] = e[c].to;
            }
        }
    }
    return (us[t] == usbs++);
}

int dfs(int v = s, int c = 1e9)
{
    if (!c)
    {
        return 0;
    }
    if (v == t)
    {
        ans += c;
        return c;
    }
    if (ded[v] != after_bfs)
    {
        ded[v] = after_bfs;
        ptr[v] = 0;
    }
    for (; ptr[v] < (int) g[v].size(); ptr[v]++)
    {
        int ind = g[v][ptr[v]];
        if (e[ind].cap >= l && d[e[ind].to] == d[v] + 1)
        {
            int x = dfs(e[ind].to, min(c, e[ind].cap));
            if (x)
            {
                e[ind].cap -= x;
                e[ind ^ 1].cap += x;
                return x;
            }
        }
    }
    return 0;
}

const int A = 100 + 7;
char c[A][A];

int main()
{
#ifdef ONPC
    freopen("a.in", "r", stdin);
    //freopen("a.out", "w", stdout);
#else
    ///freopen("flow2.in", "r", stdin);
    //freopen("flow2.out", "w", stdout);
#endif
    int n, m;
    scanf("%d%d", &n, &m);
    int x = -1, y = -1;
    int dx = -1, dy = -1;
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            scanf(" %c", &c[i][j]);
            if (c[i][j] == 'S')
            {
                x = i, y = j;
            }
            if (c[i][j] == 'T')
            {
                dx = i, dy = j;
            }
        }
    }
    for (int i = 0; i < n; i++)
    {
        for (int j = 0; j < m; j++)
        {
            if (c[i][j] == 'o')
            {
                add_edge(i, n + j, 1);
                add_edge(n + j, i, 1);
            }
            else if (c[i][j] == 'S' || c[i][j] == 'T')
            {
                add_edge(i, n + j, 1e9);
                add_edge(n + j, i, 1e9);
            }
        }
    }
    l = (1 << 30);
    s = x, t = n + dy;
    for (; l > 0; l /= 2)
    {
        while (bfs())
        {
            after_bfs++;
            while (dfs())
            {
                continue;
            }
        }
    }
    if (ans > n * m)
    {
        puts("-1");
    }
    else
    {
        printf("%lld\n", ans);
    }
}

Measured memory_bytes: 33704