#pragma warning(disable:4786)
#pragma warning(disable:4996)
#include<list>
#include<bitset>
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<vector>
#include<set>
#include<map>
#include<functional>
#include<string>
#include<cstring>
#include<cstdlib>
#include<queue>
#include<utility>
#include<fstream>
#include<sstream>
#include<cmath>
#include<stack>
#include<assert.h>
using namespace std;

#define MEM(a, b) memset(a, (b), sizeof(a))
#define CLR(a) memset(a, 0, sizeof(a))
#define MAX(a, b) ((a) > (b) ? (a) : (b))
#define MIN(a, b) ((a) < (b) ? (a) : (b))
#define ABS(X) ( (X) > 0 ? (X) : ( -(X) ) )
#define S(X) ( (X) * (X) )
#define SZ(V) (int )V.size()
#define FORN(i, n) for(i = 0; i < n; i++)
#define FORAB(i, a, b) for(i = a; i <= b; i++)
#define ALL(V) V.begin(), V.end()
#define IN(A, B, C)  ((B) <= (A) && (A) <= (C))

typedef pair<int,int> PII;
typedef pair<double, double> PDD;
typedef vector<int> VI;
typedef vector<PII > VP;

#define AIN(A, B, C) assert(IN(A, B, C))

//typedef int LL;
typedef long long int LL;
//typedef __int64 LL;

struct EDGE
{
	int u, cf, id, ini;

	EDGE(int a, int b, int d)
	{
		u = a;
		cf = b;
		id = d;
		ini = cf;
	}

	EDGE()
	{
	}
};

#define SIZE 21000

struct Max_Flow
{
	int vis[SIZE], p[SIZE], id[SIZE];
	int source, sink;
	int n;

	vector<EDGE> V[SIZE];

	void add_edge(int a, int b, int cf)
	{
		int sz1 = V[a].size();
		int sz2 = V[b].size();

		V[a].push_back(EDGE(b, cf, sz2));
		V[b].push_back(EDGE(a, 0, sz1));
	}


	int augment()
	{
		queue<int> Q;
		int X;
		int sz, j, a, b, now, i;

		for (i = 0; i <= n; i++) p[i] = -1, vis[i] = 0;

		Q.push(source);
		p[source] = -1;
		vis[source] = 1;

		while (!Q.empty())
		{
			X = Q.front();
			Q.pop();

			sz = V[X].size();
			for (j = 0; j<sz; j++)
				if (V[X][j].cf>0)
				{
					if (!vis[V[X][j].u])
					{
						vis[V[X][j].u] = 1;
						p[V[X][j].u] = X;
						id[V[X][j].u] = j;
						Q.push(V[X][j].u);
					}
				}
		}

		if (p[sink] == -1) return 0;

		int flow = 1000000000;
		now = sink;

		while (p[now] != -1)
		{
			a = p[now];
			b = now;

			flow = MIN(flow, V[a][id[b]].cf);

			now = p[now];
		}

		now = sink;
		while (p[now] != -1)
		{
			a = p[now];
			b = now;

			V[a][id[b]].cf -= flow;
			V[b][V[a][id[b]].id].cf += flow;

			now = p[now];
		}

		return flow;
	}

	//returns total cost, flow is not counted here.
	int total_flow;

	int flow()
	{
		int temp;

		total_flow = 0;

		while (temp = augment())
		{
			total_flow += temp;
		}

		return total_flow;
	}

	void clear()
	{
		for (int i = 0; i < SIZE; i++)
			V[i].clear();
	}

	void set(int a, int b)
	{
		source = a;
		sink = b;
	}

	void setN(int a)
	{
		n = a;
	}
};


char board[102][102];
int H, W;
Max_Flow A;

int main()
{
	scanf("%d %d", &H, &W);
	for (int i = 0; i < H; i++) {
		scanf("%s", board[i]);
	}

	PII S, T;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			if (board[i][j] == 'S') S = PII(i, j);
			else if (board[i][j] == 'T') T = PII(i, j);
		}
	}

	if (S.first == T.first || S.second == T.second) {
		printf("-1\n");
		return 0;
	}

	A.setN(2 * W * H + H + W + 2);
	int source = 2 * W * H + H + W;
	int sink = source + 1;
	A.set(source, sink);

	int INFS = 1000000;
	for (int i = 0; i < H; i++) {
		for (int j = 0; j < W; j++) {
			int indeg = 2 * (i * W + j);
			int outdeg = indeg + 1;
			if (board[i][j] == 'S') {
				A.add_edge(source, indeg, INFS);
				A.add_edge(indeg, outdeg, INFS);
				A.add_edge(outdeg, 2 * W * H + j, INFS);
				A.add_edge(outdeg, 2 * W * H + W + i, INFS);
				A.add_edge(2 * W * H + j, indeg, INFS);
				A.add_edge(2 * W * H + W + i, indeg, INFS);
			}
			else if (board[i][j] == 'T') {
				A.add_edge(outdeg, sink, INFS);
				A.add_edge(indeg, outdeg, INFS);
				A.add_edge(outdeg, 2 * W * H + j, INFS);
				A.add_edge(outdeg, 2 * W * H + W + i, INFS);
				A.add_edge(2 * W * H + j, indeg, INFS);
				A.add_edge(2 * W * H + W + i, indeg, INFS);
			}
			else if (board[i][j] == 'o') {
				A.add_edge(indeg, outdeg, 1);
				A.add_edge(outdeg, 2 * W * H + j, INFS);
				A.add_edge(outdeg, 2 * W * H + W + i, INFS);
				A.add_edge(2 * W * H + j, indeg, INFS);
				A.add_edge(2 * W * H + W + i, indeg, INFS);
			}
		}
	}

	A.flow();
	int ans = A.total_flow;
	printf("%d\n", ans);

	return 0;
}

/*
Max_Flow A;
A.setN(n);
A.set(source, sink);
A.add_edge(s, t, cap);
A.clear();
A.flow();
A.total_flow;
*/



Measured memory_bytes: 3456