#include <bits/stdc++.h>

using namespace std;

#define REP(i, N) for (int (i) = 0; (i) < (N); ++(i))
#define READALL(c) for (auto &e : c) { cin >> e; }
#define PRINTALL(c) for (const auto &e : c) { cout << e << "\t"; } cout << "\n";

template <typename T>
using V = vector<T>;

typedef long double ld;

typedef int cap_t;
const cap_t CAPINF = numeric_limits<cap_t>::max()/2;
// Dinics algorithm.O(V^2E) max flow. O(sqrt(V)*E) for bipartite.
// O(sqrt(V)*E) for any graph in which non-soruce/sink nodes
// Have either 1 incoming or 1 outgoing edges with unit capacity.
// Very fast in practice because I blended some ideas from push-relabel.
struct Dinic {
	int S, T;
	vector<int> layer, dfs_child_i;
	vector<vector<int>> adj;
	vector<V<int>> cap;
	cap_t dfs(int u, cap_t f) {
		if (u == T) return f;
		for (;dfs_child_i[u] < adj[u].size(); ++dfs_child_i[u]) {
			int v = adj[u][dfs_child_i[u]];
			if (layer[v] != layer[u]+1 || cap[u][v] <= 0) continue;
			cap_t pushedf = dfs(v, min(f, cap[u][v]));
			if (pushedf) {
				cap[u][v] -= pushedf; cap[v][u] += pushedf;
				return pushedf;
			}
		}
		return 0;
	}
	cap_t max_flow(const vector<V<cap_t>> &incaps, int s, int t) {
		S = s; T = t;
		cap = incaps;
		const int N = cap.size();
		adj.assign(N, vector<int>());
		for (int i = 0; i < N; ++i) { // Build adjacency lists.
			for (int j = 0; j < N; ++j) if (cap[i][j] > 0) {
				adj[i].push_back(j);
				adj[j].push_back(i);
			}
		}
		cap_t flow = 0;
		while (true) {
			layer.assign(N, -1); // Shortest path tree level.
			queue<int> Q; Q.push(S); layer[S] = 0;
			while (!Q.empty()) { // BFS.
				int u = Q.front(); Q.pop();
				for (int c : adj[u]) if (cap[u][c] > 0 && layer[c] == -1) {
					layer[c] = layer[u]+1; Q.push(c);
				}
			}
			if (layer[T]  == -1) break;
			dfs_child_i.assign(N, 0);
			for (cap_t f = dfs(S, CAPINF); f > 0; f = dfs(S, CAPINF)) {
				flow += f;
			}
		}
		return flow;
	}
};

int R, C;
V<string> G;

int main() {

	// cout << 100 << " " << 100 << endl;
	// V<string> G(100);
	// REP(i, 100) {
	// 	string s;
	// 	REP(j, 100) {
	// 		s.push_back('o');
	// 	}
	// 	G[i] = s;
	// }
	// G[0][0] = 'S';
	// G[99][99] = 'T';

	// for (string s : G) {
	// 	cout << s << endl;
	// }
	cin >> R >> C;
	G.resize(R);
	READALL(G);

	// V<unordered_map<int, int>> cap(R*C);
	V<set<int>> adj(R+C);

	pair<int, int> S, T;

	REP(r, R) {
		REP(c, C) {
			if (G[r][c] == '.')
				continue;
			if (G[r][c] == 'S')
				S = make_pair(r, c);
			if (G[r][c] == 'T')
				T = make_pair(r, c);

			adj[r].insert(R+c);
		}
	}

	REP(c, C) {
		REP(r, R) {
			if (G[r][c] == '.')
				continue;
			adj[R+c].insert(r);
		}
	}

	if (S.first == T.first || S.second == T.second) {
		cout << -1 << endl;
		return 0;
	}

	V<V<int>> cap(R+C+2, V<int>(R+C+2));
	int s = R+C;
	int t = s+1;

	// cout << s << " " << t << endl;
	REP(r, R) {
		for (int c : adj[r]) {
			cap[r][c] = 1;
			// cout << r << " " << c+R << endl;
		}
		if (r == S.first)
			cap[s][r] = 999999;
		if (r == T.first)
			cap[r][t] = 999999;
	}
	REP(c, C) {
		for (int r : adj[c+R]) {
			// cout << c+R << " " << r << endl;
			cap[c+R][r] = 1;
		}
		if (c == S.second)
			cap[s][c+R] = 999999;
		if (c == T.second)
			cap[c+R][t] = 999999;
	}


	Dinic d;

	int mf = d.max_flow(cap, s, t);

	cout << mf << endl;
}

Measured memory_bytes: 1792