#include <bits/stdc++.h>

const int MAXN = 110 * 110 * 2;
const int INF = std::numeric_limits<int>::max();
const int MAXM = MAXN * 10;
int head[MAXN], nxt[MAXM], to[MAXM], val[MAXM], tot = 1;
int S, T, idx;
void addedge(int b, int e, int v) {
	nxt[++tot] = head[b]; to[head[b] = tot] = e; val[tot] = v;
	nxt[++tot] = head[e]; to[head[e] = tot] = b; val[tot] = 0;
}
int dis[MAXN]; std::queue<int> q;
bool bfs() {
	memset(dis, 0, idx + 1 << 2);
	q.push(S); dis[S] = 1;
	while (!q.empty()) {
		int t = q.front(); q.pop();
		for (int i = head[t]; i; i = nxt[i])
			if (val[i] && !dis[to[i]]) {
				q.push(to[i]);
				dis[to[i]] = dis[t] + 1;
			}
	}
	return dis[T] > 0;
}
int dinic(int u, int minv) {
	if (!minv || u == T) return minv;
	int res = 0, t;
	for (int & i = head[u]; i; i = nxt[i])
		if (val[i] && dis[to[i]] == dis[u] + 1 && (t = dinic(to[i], std::min(minv, val[i])))) {
			val[i] -= t;
			val[i ^ 1] += t;
			res += t;
			minv -= t;
			if (!minv) break;
		}
	if (!res) dis[u] = -1;
	return res;
}
int tmp;
int flow() {
	static int te[MAXN];
	int ans = 0;
	memcpy(te, head, idx + 1 << 2);
	while (bfs()) {
		ans += dinic(S, INF);
		if (ans > tmp) break;
		memcpy(head, te, idx + 1 << 2);
	}
	return ans;
}
char mat[110];
int main() {
	std::ios_base::sync_with_stdio(false), std::cin.tie(0);
	int H, W; std::cin >> H >> W;
	S = 0, T = idx = H + W + 1;
	for (int i = 1; i <= H; ++i) {
		std::cin >> mat + 1;
		for (int j = 1; j <= W; ++j)
			if (mat[j] != '.') {
				if (mat[j] == 'S')
					addedge(S, i, INF), addedge(S, j + H, INF);
				else if (mat[j] == 'T')
					addedge(i, T, INF), addedge(j + H, T, INF);
				else
					addedge(i, j + H, 1), addedge(j + H, i, 1);
				tmp += mat[j] == 'o';
			}
	}
	int ans = flow(); if (ans > tmp) ans = -1;
	std::cout << ans << std::endl;
	return 0;
}
