#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <queue>
#include <algorithm>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <unordered_map>
#include <unordered_set>
#include <cmath>
#include <cstdlib>
#include <memory.h>
#include <ctime>
#include <bitset>

using namespace std;

#define ABS(a) ((a>0)?a:-(a))
#define MIN(a,b) ((a<b)?(a):(b))
#define MAX(a,b) ((a<b)?(b):(a))
#define FOR(i,a,n) for (int i=(a);i<(n);++i)
#define FI(i,n) for (int i=0; i<(n); ++i)
#define pnt pair <int, int>
#define mp make_pair
#define PI 3.1415926535897
#define MEMS(a,b) memset(a,b,sizeof(a))
#define LL long long
#define U unsigned

char a[110][110];
int b[110][110];


struct edge
{
	int u, v, cap;
	edge()
	{
		u = v = cap = 0;
	}
	edge(int u, int v, int cap)
	{
		this->u = u;
		this->v = v;
		this->cap = cap;
	}
};

vector<edge> e;
vector<vector<int> > g;
vector<int> ptr;
vector<int> d;

void addedge(int u, int v, int cap)
{
	edge e1 = *new edge(u, v, cap);
	g[u].push_back(e.size());
	e.push_back(e1);
	edge e2 = *new edge(v, u, 0);
	g[v].push_back(e.size());
	e.push_back(e2);
}

int dfs(int v, int finish, int have)
{
	if (v == finish)
	{
		return have;
	}
	for (; ptr[v] < g[v].size(); ++ptr[v])
	{
		int to = g[v][ptr[v]];
		int ne = e[to].v;
		if ((e[to].cap>0) && (d[v] + 1 == d[ne]))
		{
			int res = 0;
			if (have == -1)
				res = dfs(e[to].v, finish, e[to].cap);
			else
				res = dfs(e[to].v, finish, MIN(have, e[to].cap));
			if (res > 0)
			{
				e[to].cap -= res;
				e[to ^ 1].cap += res;
				return res;
			}
		}
	}
	return 0;
}
vector<int> q;
bool bfs(int start, int finish, int n)
{
	d.clear();
	d.resize(n, -1);
	q.clear();
	q.push_back(start);
	d[start] = 0;
	int l = 0;
	while (l < q.size())
	{
		int v = q[l++];
		FOR(i, 0, g[v].size())
		{
			int to = g[v][i];
			if ((e[to].cap > 0) && (d[e[to].v] == -1))
			{
				d[e[to].v] = d[v] + 1;
				q.push_back(e[to].v);
			}
		}
	}
	return (d[finish] != -1);
}

LL getFlow(int start, int finish, int n)
{
	LL res = 0;
	while (true)
	{
		bool f = bfs(start, finish, n);
		if (!f)
			break;
		ptr.clear();
		ptr.resize(n, 0);
		while (1)
		{
			int k = dfs(start, finish, -1);
			if (k <= 0)
				break;
			res += k;
		}
	}
	return res;
}

const int INF = 1000000;

int main()
{
#ifdef Fcdkbear
	freopen("in.txt", "r", stdin);
	//freopen("out.txt", "w", stdout);
	double beg = clock();
#endif

	int n, m;
	scanf("%d%d", &n, &m);
	FOR(i, 0, n) {
		scanf("%s", a[i]);
	}
	int cnt = 0;
	int numS = 0;
	int numT = 0;
	MEMS(b, -1);
	FOR(i, 0, n) {
		FOR(j, 0, m) {
			if (a[i][j] == 'S') {
				b[i][j] = cnt++;
				numS = cnt - 1;
			}
			if (a[i][j] == 'T') {
				b[i][j] = cnt++;
				numT = cnt - 1;
			}
			if (a[i][j] == 'o') {
				b[i][j] = cnt++;
			}
		}
	}
	g.resize(cnt + cnt);
	FOR(i, 0, cnt) {
		if ((i == numS) || (i == numT)) {
			addedge(i + i, i + i + 1, INF);
		}
		else {
			addedge(i + i, i + i + 1, 1);
		}
	}
	FOR(i, 0, n) {
		FOR(j, 0, m) {
			if (b[i][j] != -1) {
				FOR(k, i + 1, n) {
					if (b[k][j] != -1) {
						addedge(b[i][j] + b[i][j] + 1, b[k][j] + b[k][j], INF);
						//break;
					}
				}
				for (int k = i - 1; k >= 0; --k) {
					if (b[k][j] != -1) {
						addedge(b[i][j] + b[i][j] + 1, b[k][j] + b[k][j], INF);
						//break;
					}
				}
				FOR(k, j + 1, m) {
					if (b[i][k] != -1) {
						addedge(b[i][j] + b[i][j] + 1, b[i][k] + b[i][k], INF);
						//break;
					}
				}
				for (int k = j - 1; k >= 0; --k) {
					if (b[i][k] != -1) {
						addedge(b[i][j] + b[i][j] + 1, b[i][k] + b[i][k], INF);
						//break;
					}
				}
			}
		}
	}
	LL res = getFlow(numS + numS, numT + numT + 1, cnt * 2);
	if (res >= INF) {
		res = -1;
	}
	cout << res << endl;

#ifdef Fcdkbear
	double end = clock();
	fprintf(stderr, "*** Total time = %.3lf ***\n", (end - beg) / CLOCKS_PER_SEC);
#endif
	return 0;
}

Measured memory_bytes: 195744