There is a pond with a rectangular shape.
The pond is divided into a grid with H rows and W columns of squares.
We will denote the square at the i-th row from the top and j-th column from the left by (i,\ j).
Some of the squares in the pond contains a lotus leaf floating on the water.
On one of those leaves, S, there is a frog trying to get to another leaf T.
The state of square (i,\ j) is given to you by a character a_{ij}, as follows:
 - . : A square without a leaf.
 - o : A square with a leaf floating on the water.
 - S : A square with the leaf S.
 - T : A square with the leaf T.
The frog will repeatedly perform the following action to get to the leaf T: "jump to a leaf that is in the same row or the same column as the leaf where the frog is currently located."
Snuke is trying to remove some of the leaves, other than S and T, so that the frog cannot get to the leaf T.
Determine whether this objective is achievable. If it is achievable, find the minimum necessary number of leaves to remove.

-----Constraints-----
 - 2 ≤ H, W ≤ 100
 - a_{ij} is ., o, S or T.
 - There is exactly one S among a_{ij}.
 - There is exactly one T among a_{ij}.

-----Input-----
Input is given from Standard Input in the following format:
H W
a_{11} ... a_{1W}
:
a_{H1} ... a_{HW}

-----Output-----
If the objective is achievable, print the minimum necessary number of leaves to remove.
Otherwise, print -1 instead.

-----Sample Input-----
3 3
S.o
.o.
o.T

-----Sample Output-----
2

Remove the upper-right and lower-left leaves.

Difficulty: HARD

Solutions:
import sys

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c] * b for i in range(a)]

def list3d(a, b, c, d):
	return [[[d] * c for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e] * d for j in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 10 ** 9 + 7

class Dinic:

	def __init__(self, n):
		self.n = n
		self.links = [[] for _ in range(n)]
		self.depth = None
		self.progress = None

	def add_link(self, _from, to, cap):
		self.links[_from].append([cap, to, len(self.links[to])])
		self.links[to].append([0, _from, len(self.links[_from]) - 1])

	def bfs(self, s):
		from collections import deque
		depth = [-1] * self.n
		depth[s] = 0
		q = deque([s])
		while q:
			v = q.popleft()
			for (cap, to, _) in self.links[v]:
				if cap > 0 and depth[to] < 0:
					depth[to] = depth[v] + 1
					q.append(to)
		self.depth = depth

	def dfs(self, v, t, flow):
		if v == t:
			return flow
		links_v = self.links[v]
		for i in range(self.progress[v], len(links_v)):
			self.progress[v] = i
			(cap, to, rev) = link = links_v[i]
			if cap == 0 or self.depth[v] >= self.depth[to]:
				continue
			d = self.dfs(to, t, min(flow, cap))
			if d == 0:
				continue
			link[0] -= d
			self.links[to][rev][0] += d
			return d
		return 0

	def max_flow(self, s, t):
		flow = 0
		while True:
			self.bfs(s)
			if self.depth[t] < 0:
				return flow
			self.progress = [0] * self.n
			current_flow = self.dfs(s, t, INF)
			while current_flow > 0:
				flow += current_flow
				current_flow = self.dfs(s, t, INF)

def build_grid(H, W, intv, _type, space=True, padding=False):
	if space:
		_input = lambda : input().split()
	else:
		_input = lambda : input()
	_list = lambda : list(map(_type, _input()))
	if padding:
		offset = 1
	else:
		offset = 0
	grid = list2d(H + offset * 2, W + offset * 2, intv)
	for i in range(offset, H + offset):
		row = _list()
		for j in range(offset, W + offset):
			grid[i][j] = row[j - offset]
	return grid
(H, W) = MAP()
grid = build_grid(H, W, '', str, space=0)
dn = Dinic(H + W + 2)
s = H + W
t = H + W + 1
for i in range(H):
	for j in range(W):
		if grid[i][j] == 'o':
			dn.add_link(i, H + j, 1)
			dn.add_link(H + j, i, 1)
		elif grid[i][j] == 'S':
			dn.add_link(s, i, INF)
			dn.add_link(s, H + j, INF)
		elif grid[i][j] == 'T':
			dn.add_link(i, t, INF)
			dn.add_link(H + j, t, INF)
ans = dn.max_flow(s, t)
if ans >= INF:
	print(-1)
else:
	print(ans)


from collections import deque

class Dinic:

	def __init__(self, n):
		self.n = n
		self.g = [[] for i in range(n)]

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		forward[2] = backward = [fr, 0, forward]
		self.g[fr].append(forward)
		self.g[to].append(backward)

	def add_bidirectional_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge1[2] = edge2 = [v1, cap2, edge1]
		self.g[v1].append(edge1)
		self.g[v2].append(edge2)

	def bfs(self, s, t):
		self.level = level = [None] * self.n
		deq = deque([s])
		level[s] = 0
		g = self.g
		while deq:
			v = deq.popleft()
			lv = level[v] + 1
			for (w, cap, _) in g[v]:
				if cap and level[w] is None:
					level[w] = lv
					deq.append(w)
		return level[t] is not None

	def dfs(self, v, t, f):
		if v == t:
			return f
		level = self.level
		for e in self.it[v]:
			(w, cap, rev) = e
			if cap and level[v] < level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d:
					e[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		INF = 10 ** 30
		g = self.g
		while self.bfs(s, t):
			(*self.it,) = map(iter, self.g)
			f = INF
			while f:
				f = self.dfs(s, t, INF)
				flow += f
		return flow
(H, W) = map(int, input().split())
a = [input() for _ in range(H)]
d = Dinic(H + W + 2)
for i in range(H):
	for j in range(W):
		if a[i][j] == 'S':
			d.add_edge(H + W, i, 10 ** 5)
			d.add_edge(H + W, H + j, 10 ** 5)
		elif a[i][j] == 'T':
			d.add_edge(i, H + W + 1, 10 ** 5)
			d.add_edge(H + j, H + W + 1, 10 ** 5)
		elif a[i][j] == 'o':
			d.add_edge(i, H + j, 1)
			d.add_edge(H + j, i, 1)
ans = d.flow(H + W, H + W + 1)
if ans > 10000:
	print(-1)
else:
	print(ans)


from typing import NamedTuple, Optional, List, cast

class MFGraph:

	class Edge(NamedTuple):
		src: int
		dst: int
		cap: int
		flow: int

	class _Edge:

		def __init__(self, dst: int, cap: int) -> None:
			self.dst = dst
			self.cap = cap
			self.rev: Optional[MFGraph._Edge] = None

	def __init__(self, n: int) -> None:
		self._n = n
		self._g: List[List[MFGraph._Edge]] = [[] for _ in range(n)]
		self._edges: List[MFGraph._Edge] = []

	def add_edge(self, src: int, dst: int, cap: int) -> int:
		assert 0 <= src < self._n
		assert 0 <= dst < self._n
		assert 0 <= cap
		m = len(self._edges)
		e = MFGraph._Edge(dst, cap)
		re = MFGraph._Edge(src, 0)
		e.rev = re
		re.rev = e
		self._g[src].append(e)
		self._g[dst].append(re)
		self._edges.append(e)
		return m

	def get_edge(self, i: int) -> Edge:
		assert 0 <= i < len(self._edges)
		e = self._edges[i]
		re = cast(MFGraph._Edge, e.rev)
		return MFGraph.Edge(re.dst, e.dst, e.cap + re.cap, re.cap)

	def edges(self) -> List[Edge]:
		return [self.get_edge(i) for i in range(len(self._edges))]

	def change_edge(self, i: int, new_cap: int, new_flow: int) -> None:
		assert 0 <= i < len(self._edges)
		assert 0 <= new_flow <= new_cap
		e = self._edges[i]
		e.cap = new_cap - new_flow
		assert e.rev is not None
		e.rev.cap = new_flow

	def flow(self, s: int, t: int, flow_limit: Optional[int]=None) -> int:
		assert 0 <= s < self._n
		assert 0 <= t < self._n
		assert s != t
		if flow_limit is None:
			flow_limit = cast(int, sum((e.cap for e in self._g[s])))
		current_edge = [0] * self._n
		level = [0] * self._n

		def fill(arr: List[int], value: int) -> None:
			for i in range(len(arr)):
				arr[i] = value

		def bfs() -> bool:
			fill(level, self._n)
			queue = []
			q_front = 0
			queue.append(s)
			level[s] = 0
			while q_front < len(queue):
				v = queue[q_front]
				q_front += 1
				next_level = level[v] + 1
				for e in self._g[v]:
					if e.cap == 0 or level[e.dst] <= next_level:
						continue
					level[e.dst] = next_level
					if e.dst == t:
						return True
					queue.append(e.dst)
			return False

		def dfs(lim: int) -> int:
			stack = []
			edge_stack: List[MFGraph._Edge] = []
			stack.append(t)
			while stack:
				v = stack[-1]
				if v == s:
					flow = min(lim, min((e.cap for e in edge_stack)))
					for e in edge_stack:
						e.cap -= flow
						assert e.rev is not None
						e.rev.cap += flow
					return flow
				next_level = level[v] - 1
				while current_edge[v] < len(self._g[v]):
					e = self._g[v][current_edge[v]]
					re = cast(MFGraph._Edge, e.rev)
					if level[e.dst] != next_level or re.cap == 0:
						current_edge[v] += 1
						continue
					stack.append(e.dst)
					edge_stack.append(re)
					break
				else:
					stack.pop()
					if edge_stack:
						edge_stack.pop()
					level[v] = self._n
			return 0
		flow = 0
		while flow < flow_limit:
			if not bfs():
				break
			fill(current_edge, 0)
			while flow < flow_limit:
				f = dfs(flow_limit - flow)
				flow += f
				if f == 0:
					break
		return flow

	def min_cut(self, s: int) -> List[bool]:
		visited = [False] * self._n
		stack = [s]
		visited[s] = True
		while stack:
			v = stack.pop()
			for e in self._g[v]:
				if e.cap > 0 and (not visited[e.dst]):
					visited[e.dst] = True
					stack.append(e.dst)
		return visited
import sys
input = sys.stdin.readline
(h, w) = map(int, input().split())
A = tuple((input().rstrip() for _ in range(h)))
G = MFGraph(h + w + 2)
s = h + w
t = s + 1
big = 10 ** 9
for i in range(h):
	for j in range(w):
		if A[i][j] == 'S':
			G.add_edge(s, i, big)
			G.add_edge(s, h + j, big)
		if A[i][j] == 'T':
			G.add_edge(i, t, big)
			G.add_edge(h + j, t, big)
		if A[i][j] == 'o':
			G.add_edge(i, h + j, 1)
			G.add_edge(h + j, i, 1)
ans = G.flow(s, t)
if ans >= big:
	ans = -1
print(ans)


import sys
INF = 1 << 60
MOD = 10 ** 9 + 7
sys.setrecursionlimit(2147483647)
input = lambda : sys.stdin.readline().rstrip()

class MaxFlow(object):

	def __init__(self, n):
		self.n = n
		self.E = [[] for _ in range(n)]

	def add_edge(self, u, v, cap):
		e = [v, cap, 0]
		rev = [u, 0, e]
		e[-1] = rev
		self.E[u].append(e)
		self.E[v].append(rev)

	def _bfs(self, s, t):
		self._level = level = [-1] * self.n
		level[s] = 0
		queue = [s]
		for v in queue:
			for (nv, cap, _) in self.E[v]:
				if cap and level[nv] == -1:
					level[nv] = level[v] + 1
					if nv == t:
						return True
					queue.append(nv)
		return level[t] != -1

	def _dfs(self, s, t):
		(E, level, it) = (self.E, self._level, self._iter)
		stack = [(s, INF)]
		while stack:
			(v, f) = stack[-1]
			if v == t:
				for (v, _) in stack[:-1]:
					E[v][it[v]][1] -= f
					E[v][it[v]][-1][1] += f
				return f
			while it[v] < len(E[v]):
				(nv, cap, _) = E[v][it[v]]
				if cap and level[v] < level[nv]:
					stack.append((nv, min(f, cap)))
					break
				it[v] += 1
			else:
				stack.pop()
				level[v] = 0
		return 0

	def solve(self, s, t):
		res = 0
		while self._bfs(s, t):
			self._iter = [0] * self.n
			f = 1
			while f:
				f = self._dfs(s, t)
				res += f
		return res
from itertools import product

def resolve():
	(m, n) = map(int, input().split())
	grid = [input() for _ in range(m)]
	N = m + n
	flow = MaxFlow(N + 2)
	for (i, j) in product(range(m), range(n)):
		if grid[i][j] == 'S':
			flow.add_edge(i, j + m, INF)
			flow.add_edge(j + m, i, INF)
			flow.add_edge(N, i, INF)
			flow.add_edge(N, j + m, INF)
		elif grid[i][j] == 'T':
			flow.add_edge(i, j + m, INF)
			flow.add_edge(j + m, i, INF)
			flow.add_edge(i, N + 1, INF)
			flow.add_edge(j + m, N + 1, INF)
		elif grid[i][j] != '.':
			flow.add_edge(i, j + m, 1)
			flow.add_edge(j + m, i, 1)
	ans = flow.solve(N, N + 1)
	if ans > 10 << 30:
		ans = -1
	print(ans)
resolve()


def main():

	def add_edge(From, to, cap):
		g[From][to] = cap
		g[to][-From - 1] = 0

	def max_flow(s, t):
		flow = 0
		while True:
			used = [False] * n
			used2 = [0] * n
			q = [(s, 10 ** 6)]
			ans = [0]
			while q:
				(v, f) = q[-1]
				a = ans[0]
				if a == 0:
					if v == t:
						ans[0] = f
						continue
					(gkv, gv) = (gkey[v], g[v])
					(l, used[v]) = (len(gkv), True)
					while True:
						i = used2[v]
						used2[v] += 1
						if i < l:
							to = gkv[i]
							(cap, to2) = (gv[to], [to, -to - 1][to < 0])
							if not used[to2] and cap:
								q.append((to2, min(f, cap)))
								break
						else:
							q.pop()
							ans[0] = 0
							break
				else:
					q.pop()
					if q:
						v = q[-1][0]
						i = used2[v] - 1
						to = gkey[v][i]
						g[v][to] -= a
						g[[to, -to - 1][to < 0]][-v - 1] += a
			if not ans[0]:
				return flow
			flow += ans[0]
	(h, w) = list(map(int, input().split()))
	n = h + w + 2
	g = [dict() for _ in range(n)]
	for i in range(h):
		A = input()
		for j in range(w):
			if A[j] == 'o':
				add_edge(i, j + h, 1)
				add_edge(j + h, i, 1)
			elif A[j] == 'S':
				add_edge(h + w, i, 10 ** 6)
				add_edge(h + w, j + h, 10 ** 6)
			elif A[j] == 'T':
				add_edge(i, h + w + 1, 10 ** 6)
				add_edge(j + h, h + w + 1, 10 ** 6)
	gkey = [list(i.keys()) for i in g]
	ans = max_flow(h + w, h + w + 1)
	if ans >= 10 ** 6:
		print(-1)
	else:
		print(ans)
main()


from collections import deque

class MaxFlow:

	def __init__(self, n):
		self.n = n
		self.graph = [[] for _ in range(n)]
		self.pos = []

	def add_edge(self, fr, to, cap):
		m = len(self.pos)
		self.pos.append((fr, len(self.graph[fr])))
		self.graph[fr].append([to, len(self.graph[to]), cap])
		self.graph[to].append([fr, len(self.graph[fr]) - 1, 0])
		return m

	def get_edge(self, idx):
		(to, rev, cap) = self.graph[self.pos[idx][0]][self.pos[idx][1]]
		(rev_to, rev_rev, rev_cap) = self.graph[to][rev]
		return (rev_to, to, cap + rev_cap, rev_cap)

	def edges(self):
		m = len(self.pos)
		for i in range(m):
			yield self.get_edge(i)

	def change_edge(self, idx, new_cap, new_flow):
		(to, rev, cap) = self.graph[self.pos[idx][0]][self.pos[idx][1]]
		self.graph[self.pos[idx][0]][self.pos[idx][1]][2] = new_cap - new_flow
		self.graph[to][rev][2] = new_flow

	def dfs(self, s, v, up):
		if v == s:
			return up
		res = 0
		lv = self.level[v]
		for i in range(self.iter[v], len(self.graph[v])):
			(to, rev, cap) = self.graph[v][i]
			if lv <= self.level[to] or self.graph[to][rev][2] == 0:
				continue
			d = self.dfs(s, to, min(up - res, self.graph[to][rev][2]))
			if d <= 0:
				continue
			self.graph[v][i][2] += d
			self.graph[to][rev][2] -= d
			res += d
			if res == up:
				break
			self.iter[v] += 1
		return res

	def max_flow(self, s, t):
		return self.max_flow_with_limit(s, t, 2 ** 63 - 1)

	def max_flow_with_limit(self, s, t, limit):
		flow = 0
		while flow < limit:
			self.level = [-1] * self.n
			self.level[s] = 0
			queue = deque()
			queue.append(s)
			while queue:
				v = queue.popleft()
				for (to, rev, cap) in self.graph[v]:
					if cap == 0 or self.level[to] >= 0:
						continue
					self.level[to] = self.level[v] + 1
					if to == t:
						break
					queue.append(to)
			if self.level[t] == -1:
				break
			self.iter = [0] * self.n
			while flow < limit:
				f = self.dfs(s, t, limit - flow)
				if not f:
					break
				flow += f
		return flow

	def min_cut(self, s):
		visited = [0] * self.n
		queue = deque()
		queue.append(s)
		while queue:
			p = queue.popleft()
			visited[p] = True
			for (to, rev, cap) in self.graph[p]:
				if cap and (not visited[to]):
					visited[to] = True
					queue.append(to)
		return visited
(H, W) = map(int, input().split())
a = [list(input().rstrip()) for _ in range(H)]
mf = MaxFlow(H + W + 2)
start = H + W
terminal = H + W + 1
INF = 10 ** 6
for i in range(H):
	for j in range(W):
		if a[i][j] == 'S':
			mf.add_edge(start, i, INF)
			mf.add_edge(start, H + j, INF)
		elif a[i][j] == 'T':
			mf.add_edge(i, terminal, INF)
			mf.add_edge(H + j, terminal, INF)
		elif a[i][j] == 'o':
			mf.add_edge(i, H + j, 1)
			mf.add_edge(H + j, i, 1)
ans = mf.max_flow(start, terminal)
if ans >= INF:
	print(-1)
else:
	print(ans)


from collections import deque
INF = 1 << 23

class Dinic:

	def __init__(self, N):
		self.N = N
		self.G = [[] for _ in range(self.N)]

	def add_edge(self, u, v, cap):
		self.G[u].append([v, cap, len(self.G[v])])
		self.G[v].append([u, 0, len(self.G[u]) - 1])

	def bfs(self, s):
		self.level = [-1] * self.N
		que = deque([s])
		self.level[s] = 0
		while que:
			u = que.popleft()
			for (v, cap, _) in self.G[u]:
				if cap > 0 and self.level[v] < 0:
					self.level[v] = self.level[u] + 1
					que.append(v)

	def dfs(self, u, t, f):
		if u == t:
			return f
		for i in range(self.progress[u], len(self.G[u])):
			self.progress[u] = i
			(v, cap, rev) = self.G[u][i]
			if cap > 0 and self.level[u] < self.level[v]:
				d = self.dfs(v, t, min(f, cap))
				if d > 0:
					self.G[u][i][1] -= d
					self.G[v][rev][1] += d
					return d
		return 0

	def max_flow(self, s, t):
		flow = 0
		INF = 10 ** 9
		while True:
			self.bfs(s)
			if self.level[t] < 0:
				return flow
			self.progress = [0] * self.N
			current_flow = self.dfs(s, t, INF)
			while current_flow > 0:
				flow += current_flow
				current_flow = self.dfs(s, t, INF)

def main():
	(H, W) = (int(i) for i in input().split())
	A = [input() for i in range(H)]
	F = Dinic(H + W + 2)
	s = H + W
	t = H + W + 1
	for h in range(H):
		for w in range(W):
			if A[h][w] == 'S':
				F.add_edge(s, h + W, INF)
				F.add_edge(s, w, INF)
			elif A[h][w] == 'T':
				F.add_edge(h + W, t, INF)
				F.add_edge(w, t, INF)
			if A[h][w] != '.':
				F.add_edge(h + W, w, 1)
				F.add_edge(w, h + W, 1)
	ans = F.max_flow(s, t)
	if INF <= ans:
		print(-1)
	else:
		print(ans)
main()


import sys
from collections import deque
sys.setrecursionlimit(10 ** 7)
rl = sys.stdin.readline

class Dinic:

	def __init__(self, n):
		self.n = n
		self.graph = [[] for _ in range(n)]
		self.level = None
		self.it = None

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		forward[2] = backward = [fr, 0, forward]
		self.graph[fr].append(forward)
		self.graph[to].append(backward)

	def add_multi_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge1[2] = edge2 = [v1, cap2, edge1]
		self.graph[v1].append(edge1)
		self.graph[v2].append(edge2)

	def bfs(self, s, t):
		self.level = level = [-1] * self.n
		deq = deque([s])
		level[s] = 0
		G = self.graph
		while deq:
			v = deq.popleft()
			lv = level[v] + 1
			for (w, cap, _) in G[v]:
				if cap and level[w] == -1:
					level[w] = lv
					deq.append(w)
		return level[t] != -1

	def dfs(self, v, t, f):
		if v == t:
			return f
		for e in self.it[v]:
			(w, cap, rev) = e
			if cap and self.level[v] < self.level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d:
					e[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		INF = 10 ** 18
		while self.bfs(s, t):
			(*self.it,) = list(map(iter, self.graph))
			f = INF
			while f:
				f = self.dfs(s, t, INF)
				flow += f
		return flow

def solve():
	(H, W) = list(map(int, rl().split()))
	INF = 10 ** 18
	s = H + W
	t = s + 1
	dinic = Dinic(t + 1)
	for i in range(H):
		line = input()
		for j in range(W):
			if line[j] == 'o':
				dinic.add_multi_edge(i, H + j, 1, 1)
			elif line[j] == 'S':
				dinic.add_edge(s, i, INF)
				dinic.add_edge(s, H + j, INF)
			elif line[j] == 'T':
				dinic.add_edge(i, t, INF)
				dinic.add_edge(H + j, t, INF)
	ans = dinic.flow(s, t)
	print(ans if ans < INF else -1)

def __starting_point():
	solve()
__starting_point()


import sys
input = sys.stdin.readline
sys.setrecursionlimit(10 ** 9)
from collections import deque

class Dinic:

	def __init__(self, n, edges):
		self.n = n
		self.edges = [[] for _ in range(n)]
		self.iter = [0] * n
		self.level = None
		self.graph(edges)

	def graph(self, E):
		edges = self.edges
		for (fr, to, cap) in E:
			edges[fr].append([to, cap, len(edges[to])])
			edges[to].append([fr, 0, len(edges[fr]) - 1])

	def maxflow(self, source, sink):
		max_flow = 0
		while True:
			self.bfs(source)
			if self.level[sink] < 0:
				return max_flow
			self.iter = [0] * self.n
			flow = self.dfs(source, sink, float('inf'))
			while flow:
				max_flow += flow
				flow = self.dfs(source, sink, float('inf'))

	def bfs(self, source):
		edges = self.edges
		level = [-1] * self.n
		level[source] = 0
		q = deque([source])
		while q:
			fr = q.popleft()
			for (to, cap, _) in edges[fr]:
				if cap > 0 > level[to]:
					level[to] = level[fr] + 1
					q.append(to)
		self.level = level

	def dfs(self, source, sink, flow):
		if source == sink:
			return flow
		while self.iter[source] < len(self.edges[source]):
			(to, cap, rev) = self.edges[source][self.iter[source]]
			if cap > 0 and self.level[source] < self.level[to]:
				f = self.dfs(to, sink, min(flow, cap))
				if f:
					self.edges[source][self.iter[source]][1] -= f
					self.edges[to][rev][1] += f
					return f
			self.iter[source] += 1
		return 0
inf = float('inf')
(h, w) = map(int, input().split())
Edges = []
for x in range(h):
	s = list(input())
	for y in range(w):
		if s[y] == 'S':
			Edges.append((0, x + 1, inf))
			Edges.append((0, y + 1 + h, inf))
		elif s[y] == 'T':
			Edges.append((x + 1, h + w + 1, inf))
			Edges.append((y + 1 + h, h + w + 1, inf))
		elif s[y] == 'o':
			Edges.append((x + 1, y + 1 + h, 1))
			Edges.append((y + 1 + h, x + 1, 1))
dinic = Dinic(h + w + 2, Edges)
mf = dinic.maxflow(0, h + w + 1)
print(-1 if mf == inf else mf)


import itertools
import os
import sys
from collections import deque, defaultdict
if os.getenv('LOCAL'):
	sys.stdin = open('_in.txt', 'r')
sys.setrecursionlimit(2147483647)
INF = float('inf')
IINF = 10 ** 18
MOD = 10 ** 9 + 7
(H, W) = list(map(int, sys.stdin.readline().split()))
table = [list(sys.stdin.readline().rstrip()) for _ in range(H)]
S = H + W
T = H + W + 1
graph = [[] for _ in range(H + W + 2)]
for (h, w) in itertools.product(range(H), range(W)):
	if table[h][w] == '.':
		continue
	if table[h][w] == 'S':
		graph[S].append((h, IINF))
		graph[S].append((H + w, IINF))
	elif table[h][w] == 'T':
		graph[h].append((T, IINF))
		graph[H + w].append((T, IINF))
	graph[h].append((H + w, 1))
	graph[H + w].append((h, 1))

class Dinic:

	def __init__(self, graph=None, residual=None):
		assert graph and (not residual) or (not graph and residual)
		if graph:
			self.graph = self.residual_graph(graph)
		else:
			self.graph = residual

	@staticmethod
	def residual_graph(graph):
		ret = [[] for _ in range(len(graph))]
		for v in range(len(graph)):
			for (u, cap) in graph[v]:
				rev = [v, 0]
				edge = [u, cap, rev]
				rev.append(edge)
				ret[v].append(edge)
				ret[u].append(rev)
		return ret

	def _dist(self, s):
		ret = [-1] * len(self.graph)
		ret[s] = 0
		que = deque([(s, 0)])
		while que:
			(v, d) = que.popleft()
			for (u, cap, _) in self.graph[v]:
				if ret[u] < 0 < cap:
					ret[u] = d + 1
					que.append((u, d + 1))
		return ret

	def _dfs(self, s, t, dist, iter, flow=float('inf')):
		if s == t:
			return flow
		while iter[s] < len(self.graph[s]):
			edge = self.graph[s][iter[s]]
			(to, cap, rev) = edge
			if dist[s] < dist[to] and cap > 0:
				f = self._dfs(to, t, dist, iter, min(flow, cap))
				if f > 0:
					edge[1] -= f
					rev[1] += f
					return f
			iter[s] += 1
		return 0

	def maximum_flow(self, from_v, to_v):
		ret = 0
		while True:
			dist = self._dist(from_v)
			if dist[to_v] < 0:
				break
			iter = [0] * len(self.graph)
			while True:
				flow = self._dfs(from_v, to_v, dist, iter)
				if flow == 0:
					break
				ret += flow
		return ret
mf = Dinic(graph=graph).maximum_flow(S, T)
if mf >= IINF:
	print(-1)
else:
	print(mf)


NUMERIC_LIMITS = 10 ** 18
import queue

class maxFlow:

	class edge:

		def __init__(s, frm, to, cap, flow):
			(s.frm, s.to) = (frm, to)
			(s.cap, s.flow) = (cap, flow)

	def __init__(s, n):
		s._n = n
		s.g = [[] for _ in range(n)]
		s.pos = []

	def add_edge(s, frm, to, cap):
		m = len(s.pos)
		s.pos.append([frm, len(s.g[frm])])
		s.g[frm].append(s._edge(to, len(s.g[to]), cap))
		s.g[to].append(s._edge(frm, len(s.g[frm]) - 1, 0))
		return m

	def get_edge(s, i):
		m = len(s.pos)
		_e = s.g[s.pos[i][0]][s.pos[i][1]]
		_re = s.g[_e.to][_e.rev]
		return s.edge(s.pos[i][0], _e.to, _e.cap + _re.cap, _re.cap)

	def edges(s):
		m = len(s.pos)
		result = []
		for i in range(m):
			result.append(s.get_edge(i))
		return result

	def change_edge(s, i, new_cap, new_flow):
		m = len(s.pos)
		_e = s.g[s.pos[i].to][s.pos[i].rev]
		_re = s.g[_e.to][_e.rev]
		_e.cap = new_cap - new_flow
		_re.cap = new_flow

	def flow(self, s, t, flow_limit=NUMERIC_LIMITS):
		level = [0] * self._n
		iter = [0] * self._n

		def bfs():
			for i in range(self._n):
				level[i] = -1
			level[s] = 0
			que = queue.Queue()
			que.put(s)
			while not que.empty():
				v = que.get()
				for e in self.g[v]:
					if e.cap == 0 or level[e.to] >= 0:
						continue
					level[e.to] = level[v] + 1
					if e.to == t:
						return
					que.put(e.to)

		def dfs(this, v, up):
			if v == s:
				return up
			res = 0
			level_v = level[v]
			for i in range(iter[v], len(self.g[v])):
				e = self.g[v][i]
				if level_v <= level[e.to] or self.g[e.to][e.rev].cap == 0:
					continue
				d = this(this, e.to, min(up - res, self.g[e.to][e.rev].cap))
				if d <= 0:
					continue
				self.g[v][i].cap += d
				self.g[e.to][e.rev].cap -= d
				res += d
				if res == up:
					break
			return res
		flow = 0
		while flow < flow_limit:
			bfs()
			if level[t] == -1:
				break
			for i in range(self._n):
				iter[i]
			while flow < flow_limit:
				f = dfs(dfs, t, flow_limit - flow)
				if not f:
					break
				flow += f
		return flow

	def min_cut(self, s):
		visited = [False] * self._n
		que = queue.Queue()
		que.put(s)
		while not que.empty():
			p = que.get()
			visited[p] = True
			for e in self.g[p]:
				if e.cap and (not visited[e.to]):
					visited[e.to] = True
					que.put(e.to)
		return visited

	class _edge:

		def __init__(s, to, rev, cap):
			(s.to, s.rev) = (to, rev)
			s.cap = cap
(H, W) = list(map(int, input().split()))
a = [list(input()) for _ in range(H)]
flow = maxFlow(H + W + 2)
s = H + W
t = H + W + 1
for h in range(H):
	for w in range(W):
		if a[h][w] == 'S':
			flow.add_edge(s, h, H + W + 1)
			flow.add_edge(s, H + w, H + W + 1)
		elif a[h][w] == 'T':
			flow.add_edge(h, t, H + W + 1)
			flow.add_edge(H + w, t, H + W + 1)
		if a[h][w] != '.':
			flow.add_edge(h, H + w, 1)
			flow.add_edge(H + w, h, 1)
ans = flow.flow(s, t)
if ans > H + W:
	print(-1)
else:
	print(ans)


from collections import deque
from collections import defaultdict
import sys
sys.setrecursionlimit(100000)

class Dinic:

	def __init__(self):
		self.G = defaultdict(list)

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		backward = [fr, 0, forward]
		forward[-1] = backward
		self.G[fr].append(forward)
		self.G[to].append(backward)

	def add_multi_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge2 = [v1, cap2, edge1]
		edge1[-1] = edge2
		self.G[v1].append(edge1)
		self.G[v2].append(edge2)

	def bfs(self, s, t):
		self.level = level = defaultdict(int)
		q = deque([s])
		level[s] = 1
		G = self.G
		while len(q) > 0:
			v = q.popleft()
			lv = level[v] + 1
			nexts = G[v]
			for (w, cap, _) in nexts:
				if cap > 0 and level[w] == 0:
					level[w] = lv
					q.append(w)
		is_reach = level[t] > 0
		return is_reach

	def dfs(self, v, t, f):
		if v == t:
			return f
		level = self.level
		nexts = self.G[v]
		for edge in nexts:
			(w, cap, rev) = edge
			if cap > 0 and level[v] < level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d > 0:
					edge[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		INF = 10 ** 10
		G = self.G
		while self.bfs(s, t):
			f = INF
			while f > 0:
				f = self.dfs(s, t, INF)
				flow += f
		return flow
ans = set()
(H, W) = map(int, input().split())
fields = []
for i in range(H):
	inp = list(input())
	fields.append(inp)
dinic = Dinic()
start = -1
end = -2
INF = 10 ** 10
for i in range(H):
	for j in range(W):
		if fields[i][j] == 'T':
			dinic.add_edge(i, end, INF)
			dinic.add_edge(j + H, end, INF)
		if fields[i][j] == 'S':
			dinic.add_edge(start, i, INF)
			dinic.add_edge(start, j + H, INF)
		if fields[i][j] != '.':
			dinic.add_edge(i, j + H, 1)
			dinic.add_edge(j + H, i, 1)
ans = dinic.flow(start, end)
if ans > INF:
	print(-1)
else:
	print(ans)


import math, string, itertools, fractions, heapq, collections, re, array, bisect, sys, random, time, copy, functools
sys.setrecursionlimit(10 ** 7)
inf = 10 ** 20
eps = 1.0 / 10 ** 15
mod = 10 ** 9 + 7

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def LI_():
	return [int(x) - 1 for x in sys.stdin.readline().split()]

def LF():
	return [float(x) for x in sys.stdin.readline().split()]

def LS():
	return sys.stdin.readline().split()

def I():
	return int(sys.stdin.readline())

def F():
	return float(sys.stdin.readline())

def S():
	return input()

def pf(s):
	return print(s, flush=True)

class E:

	def __init__(self, dst, cap, rev):
		self.dst = dst
		self.cap = cap
		self.rev = rev

	def __repr__(self):
		return '({}, {}, {})'.format(self.dst, self.cap, self.rev)

	def __str__(self):
		return '({}, {}, {})'.format(self.dst, self.cap, self.rev)

class Dinic:

	def __init__(self, n):
		self.n = n
		self.g = [[] for _ in range(n)]

	def add_edge(self, src, dst, cap):
		self.g[src].append(E(dst, cap, len(self.g[dst])))
		self.g[dst].append(E(src, 0, len(self.g[src]) - 1))

	def add_undirected_edge(self, src, dst, cap):
		self.g[src].append(E(dst, cap, len(self.g[dst])))
		self.g[dst].append(E(src, cap, len(self.g[src]) - 1))

	def dfs(self, s, u, crr):
		if s == u or crr == 0:
			return crr
		sm = 0
		for i in range(self.itr[u], len(self.g[u])):
			e = self.g[u][i]
			ee = self.g[e.dst][e.rev]
			v = e.dst
			if self.level[v] >= self.level[u] or ee.cap <= 0:
				continue
			f = self.dfs(s, v, min(crr - sm, ee.cap))
			if f <= 0:
				continue
			ee.cap -= f
			e.cap += f
			sm += f
			if sm == crr:
				break
		return sm

	def run(self, s, t):
		q = [0] * self.n
		flow = 0
		while True:
			self.level = [-1] * self.n
			q[0] = s
			self.level[s] = 0
			ql = 0
			qr = 1
			while ql != qr and self.level[t] == -1:
				u = q[ql]
				ql += 1
				for e in self.g[u]:
					if e.cap > 0 and self.level[e.dst] == -1:
						self.level[e.dst] = self.level[u] + 1
						q[qr] = e.dst
						qr += 1
			if self.level[t] == -1:
				return flow
			self.itr = [0] * self.n
			flow += self.dfs(s, t, inf)
		return flow

def main():
	(h, w) = LI()
	a = [S() for _ in range(h)]
	dn = Dinic(h + w + 2)
	s = h + w
	t = s + 1
	for i in range(h):
		for j in range(w):
			c = a[i][j]
			if c == '.':
				continue
			if c == 'o':
				dn.add_undirected_edge(i, h + j, 1)
			elif c == 'S':
				dn.add_edge(s, i, inf)
				dn.add_edge(s, h + j, inf)
				for ii in range(h):
					a
			elif c == 'T':
				dn.add_edge(i, t, inf)
				dn.add_edge(h + j, t, inf)
	r = dn.run(s, t)
	if r >= inf:
		return -1
	return r
print(main())


import sys
input = sys.stdin.readline
INF = 10 ** 18
(H, W) = map(int, input().split())
V = H + W

def make():
	state = [list(input().rstrip()) for _ in range(H)]
	graph = [{} for _ in range(V + 2)]
	start = V
	finish = V + 1
	for h in range(H):
		for w in range(W):
			(u, v) = (h, w + H)
			if state[h][w] == 'o':
				graph[u][v] = 1
				graph[v][u] = 1
			if state[h][w] == 'S':
				graph[v][start] = INF
				graph[start][v] = INF
				graph[u][start] = INF
				graph[start][u] = INF
			if state[h][w] == 'T':
				graph[u][finish] = INF
				graph[finish][u] = INF
				graph[v][finish] = INF
				graph[finish][v] = INF
	return (graph, start, finish)

def dfs2(start, finish, graph):
	Flow = [INF] * len(graph)
	used = [False] * len(graph)
	Par = [-1] * len(graph)
	stack = [start]
	used[start] = True
	while stack:
		v = stack.pop()
		if v == finish:
			d = Flow[v]
			while v != start:
				nv = Par[v]
				graph[nv][v] -= d
				graph[v][nv] += d
				v = nv
			return (d, graph)
		for (i, (nv, ncap)) in enumerate(graph[v].items()):
			if not used[nv] and ncap > 0:
				used[nv] = True
				stack.append(nv)
				Par[nv] = v
				Flow[nv] = min(Flow[v], ncap)
	return (0, graph)

def max_flow(start, finish, graph):
	flow = 0
	while True:
		(f, graph) = dfs2(start, finish, graph)
		if f == 0:
			return flow
		flow += f

def main():
	(graph, start, finish) = make()
	ans = max_flow(start, finish, graph)
	if ans > INF // 2:
		print(-1)
	else:
		print(ans)
main()


from collections import deque

class Dinic:

	def __init__(self, n: int):
		self.INF = 10 ** 9 + 7
		self.n = n
		self.graph = [[] for _ in range(n)]

	def add_edge(self, _from: int, to: int, capacity: int):
		forward = [to, capacity, None]
		forward[2] = backward = [_from, 0, forward]
		self.graph[_from].append(forward)
		self.graph[to].append(backward)

	def bfs(self, s: int, t: int):
		self.level = [-1] * self.n
		q = deque([s])
		self.level[s] = 0
		while q:
			_from = q.popleft()
			for (to, capacity, _) in self.graph[_from]:
				if capacity > 0 and self.level[to] < 0:
					self.level[to] = self.level[_from] + 1
					q.append(to)

	def dfs(self, _from: int, t: int, f: int) -> int:
		if _from == t:
			return f
		for edge in self.itr[_from]:
			(to, capacity, reverse_edge) = edge
			if capacity > 0 and self.level[_from] < self.level[to]:
				d = self.dfs(to, t, min(f, capacity))
				if d > 0:
					edge[1] -= d
					reverse_edge[1] += d
					return d
		return 0

	def max_flow(self, s: int, t: int):
		flow = 0
		while True:
			self.bfs(s, t)
			if self.level[t] < 0:
				break
			self.itr = list(map(iter, self.graph))
			f = self.dfs(s, t, self.INF)
			while f > 0:
				flow += f
				f = self.dfs(s, t, self.INF)
		return flow
(h, w) = map(int, input().split())
a = [list(input()) for i in range(h)]
di = Dinic(h + w + 2)
for i in range(h):
	for j in range(w):
		if a[i][j] == 'o':
			di.add_edge(i, h + j, 1)
			di.add_edge(h + j, i, 1)
		if a[i][j] == 'S':
			di.add_edge(h + w, i, 10 ** 5)
			di.add_edge(h + w, h + j, 10 ** 5)
		if a[i][j] == 'T':
			di.add_edge(i, h + w + 1, 10 ** 5)
			di.add_edge(h + j, h + w + 1, 10 ** 5)
ans = di.max_flow(h + w, h + w + 1)
if ans >= 10 ** 5:
	print(-1)
else:
	print(ans)


from collections import deque

class mf_graph:
	n = 1
	g = [[] for i in range(1)]
	pos = []

	def __init__(self, N):
		self.n = N
		self.g = [[] for i in range(N)]

	def add_edge(self, From, To, cap):
		assert 0 <= From and From < self.n
		assert 0 <= To and To < self.n
		assert 0 <= cap
		m = len(self.pos)
		self.pos.append((From, len(self.g[From])))
		self.g[From].append({'to': To, 'rev': len(self.g[To]), 'cap': cap})
		self.g[To].append({'to': From, 'rev': len(self.g[From]) - 1, 'cap': 0})
		return m

	def get_edge(self, i):
		m = len(self.pos)
		assert 0 <= i and i < m
		_e = self.g[self.pos[i][0]][self.pos[i][1]]
		_re = self.g[_e['to']][_e['rev']]
		return {'from': self.pos[i][0], 'to': _e['to'], 'cap': _e['cap'] + _re['cap'], 'flow': _re['cap']}

	def edges(self):
		m = len(self.pos)
		result = []
		for i in range(m):
			result.append(self.get_edge(i))
		return result

	def change_edge(self, i, new_cap, new_flow):
		m = len(self.pos)
		assert 0 <= i and i < m
		assert 0 <= new_flow and new_flow <= new_cap
		_e = self.g[self.pos[i][0]][self.pos[i][1]]
		_re = self.g[_e['to']][_e['rev']]
		_e['cap'] = new_cap - new_flow
		_re['cap'] = new_flow

	def flow(self, s, t, flow_limit=2 ** 31 - 1):
		assert 0 <= s and s < self.n
		assert 0 <= t and t < self.n
		level = [0 for i in range(self.n)]
		Iter = [0 for i in range(self.n)]
		que = deque([])

		def bfs():
			for i in range(self.n):
				level[i] = -1
			level[s] = 0
			que = deque([])
			que.append(s)
			while len(que) > 0:
				v = que.popleft()
				for e in self.g[v]:
					if e['cap'] == 0 or level[e['to']] >= 0:
						continue
					level[e['to']] = level[v] + 1
					if e['to'] == t:
						return
					que.append(e['to'])

		def dfs(func, v, up):
			if v == s:
				return up
			res = 0
			level_v = level[v]
			for i in range(Iter[v], len(self.g[v])):
				e = self.g[v][i]
				if level_v <= level[e['to']] or self.g[e['to']][e['rev']]['cap'] == 0:
					continue
				d = func(func, e['to'], min(up - res, self.g[e['to']][e['rev']]['cap']))
				if d <= 0:
					continue
				self.g[v][i]['cap'] += d
				self.g[e['to']][e['rev']]['cap'] -= d
				res += d
				if res == up:
					break
			return res
		flow = 0
		while flow < flow_limit:
			bfs()
			if level[t] == -1:
				break
			for i in range(self.n):
				Iter[i] = 0
			while flow < flow_limit:
				f = dfs(dfs, t, flow_limit - flow)
				if not f:
					break
				flow += f
		return flow

	def min_cut(self, s):
		visited = [False for i in range(self.n)]
		que = deque([])
		que.append(s)
		while len(que) > 0:
			p = que.popleft()
			visited[p] = True
			for e in self.g[p]:
				if e['cap'] and (not visited[e['to']]):
					visited[e['to']] = True
					que.append(e['to'])
		return visited
(H, W) = list(map(int, input().split()))
a = [list(input()) for i in range(H)]
G = mf_graph(H + W + 2)
INF = 10 ** 9
s = H + W
t = H + W + 1
for i in range(H):
	for j in range(W):
		if a[i][j] == 'S':
			G.add_edge(s, i, INF)
			G.add_edge(s, j + H, INF)
		if a[i][j] == 'T':
			G.add_edge(i, t, INF)
			G.add_edge(j + H, t, INF)
		if a[i][j] != '.':
			G.add_edge(i, j + H, 1)
			G.add_edge(j + H, i, 1)
ans = G.flow(s, t)
if ans >= INF:
	print(-1)
else:
	print(ans)


import collections

class Dinic:

	def __init__(self, n):
		self.n = n
		self.g = [[] for i in range(n)]

	def add_edge(self, fr, to, cap):
		self.g[fr].append([to, cap, len(self.g[to])])
		self.g[to].append([fr, 0, len(self.g[fr]) - 1])

	def add_multi_edge(self, v1, v2, cap1, cap2):
		self.g[v1].append([v2, cap1, len(self.g[v2])])
		self.g[v2].append([v1, cap2, len(self.g[v1]) - 1])

	def bfs(self, s):
		level = [-1] * self.n
		deq = collections.deque()
		level[s] = 0
		deq.append(s)
		while deq:
			v = deq.popleft()
			for e in self.g[v]:
				if e[1] > 0 and level[e[0]] < 0:
					level[e[0]] = level[v] + 1
					deq.append(e[0])
		self.level = level

	def dfs(self, v, t, f):
		if v == t:
			return f
		es = self.g[v]
		level = self.level
		for i in range(self.it[v], len(self.g[v])):
			e = es[i]
			if e[1] > 0 and level[v] < level[e[0]]:
				d = self.dfs(e[0], t, min(f, e[1]))
				if d > 0:
					e[1] -= d
					self.g[e[0]][e[2]][1] += d
					self.it[v] = i
					return d
		self.it[v] = len(self.g[v])
		return 0

	def max_flow(self, s, t):
		flow = 0
		while True:
			self.bfs(s)
			if self.level[t] < 0:
				break
			self.it = [0] * self.n
			while True:
				f = self.dfs(s, t, 10 ** 9 + 7)
				if f > 0:
					flow += f
				else:
					break
		return flow
(h, w) = list(map(int, input().split()))
A = [input() for i in range(h)]
dinic = Dinic(h + w + 2)
start = h + w
end = h + w + 1
INF = 10 ** 9 + 7
for i in range(h):
	for j in range(w):
		c = A[i][j]
		if c is 'o':
			dinic.add_multi_edge(i, h + j, 1, 1)
		elif c is 'S':
			dinic.add_edge(start, i, INF)
			dinic.add_edge(start, h + j, INF)
		elif c is 'T':
			dinic.add_edge(i, end, INF)
			dinic.add_edge(h + j, end, INF)
ans = dinic.max_flow(start, end)
if ans >= INF:
	print(-1)
else:
	print(ans)


import sys
sys.setrecursionlimit(10 ** 7)

def MI():
	return map(int, sys.stdin.readline().rstrip().split())

def LS2():
	return list(sys.stdin.readline().rstrip())
from collections import deque

class Dinic:

	def __init__(self, N, inf):
		self.N = N
		self.inf = inf
		self.G = [[] for _ in range(N)]
		self.level = [0] * N

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		forward[2] = backward = [fr, 0, forward]
		self.G[fr].append(forward)
		self.G[to].append(backward)

	def add_multi_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge1[2] = edge2 = [v1, cap2, edge1]
		self.G[v1].append(edge1)
		self.G[v2].append(edge2)

	def bfs(self, s):
		self.level = [-1] * self.N
		deq = deque([s])
		self.level[s] = 0
		while deq:
			v = deq.pop()
			lv = self.level[v] + 1
			for (w, cap, _) in self.G[v]:
				if cap > 0 and self.level[w] == -1:
					self.level[w] = lv
					deq.appendleft(w)

	def dfs(self, v, t, f):
		if v == t:
			return f
		for e in self.iter[v]:
			(w, cap, rev) = e
			if cap > 0 and self.level[v] < self.level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d > 0:
					e[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		while True:
			self.bfs(s)
			if self.level[t] == -1:
				return flow
			(*self.iter,) = map(iter, self.G)
			f = self.inf
			while f > 0:
				f = self.dfs(s, t, self.inf)
				flow += f
(H, W) = MI()
inf = 10 ** 5
Di = Dinic(H + W + 2, inf)
(s, t) = (H + W, H + W + 1)
for i in range(H):
	S = LS2()
	for j in range(W):
		if S[j] == 'S':
			Di.add_edge(s, i, inf)
			Di.add_edge(s, j + H, inf)
		elif S[j] == 'T':
			Di.add_edge(i, t, inf)
			Di.add_edge(j + H, t, inf)
		elif S[j] == 'o':
			Di.add_edge(i, j + H, 1)
			Di.add_edge(j + H, i, 1)
ans = Di.flow(s, t)
print(ans if ans < inf else -1)


from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
from pprint import pprint
from copy import deepcopy
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from pprint import pprint
sys.setrecursionlimit(2147483647)
INF = 10 ** 15

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def I():
	return int(sys.stdin.buffer.readline())

def LS():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()

def S():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8')

def IR(n):
	return [I() for i in range(n)]

def LIR(n):
	return [LI() for i in range(n)]

def SR(n):
	return [S() for i in range(n)]

def LSR(n):
	return [LS() for i in range(n)]

def SRL(n):
	return [list(S()) for i in range(n)]

def MSRL(n):
	return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007

class Dinic:

	def __init__(self, G, source, sink):
		self.G = G
		self.sink = sink
		self.source = source

	def add_edge(self, u, v, cap):
		self.G[u][v] = cap
		self.G[v][u] = 0

	def bfs(self):
		level = defaultdict(int)
		q = [self.source]
		level[self.source] = 1
		d = 1
		while q:
			if level[self.sink]:
				break
			qq = []
			d += 1
			for u in q:
				for (v, cap) in self.G[u].items():
					if cap == 0:
						continue
					if level[v]:
						continue
					level[v] = d
					qq += [v]
			q = qq
		self.level = level

	def dfs(self, u, f):
		if u == self.sink:
			return f
		for (v, cap) in self.iter[u]:
			if cap == 0 or self.level[v] != self.level[u] + 1:
				continue
			d = self.dfs(v, min(f, cap))
			if d:
				self.G[u][v] -= d
				self.G[v][u] += d
				return d
		return 0

	def max_flow(self):
		flow = 0
		while True:
			self.bfs()
			if self.level[self.sink] == 0:
				break
			self.iter = {u: iter(self.G[u].items()) for u in self.G}
			while True:
				f = self.dfs(self.source, INF)
				if f == 0:
					break
				flow += f
		return flow
(h, w) = LI()
s = SR(h)
G = defaultdict(lambda : defaultdict(int))
for i in range(h):
	for j in range(w):
		if s[i][j] == 'o':
			G[i][h + j] = 1
			G[h + j][i] = 1
		elif s[i][j] == 'S':
			G[h + w][i] = INF
			G[h + w][h + j] = INF
		elif s[i][j] == 'T':
			G[i][h + w + 1] = INF
			G[h + j][h + w + 1] = INF
ans = Dinic(G, h + w, h + w + 1).max_flow()
print(ans if ans < INF else -1)


def main():
	import sys
	input = sys.stdin.readline
	from collections import deque

	class Dinic:

		def __init__(self, N):
			self.N = N
			self.G = [[] for i in range(N)]

		def add_edge(self, fr, to, cap):
			forward = [to, cap, None]
			forward[2] = backward = [fr, 0, forward]
			self.G[fr].append(forward)
			self.G[to].append(backward)

		def add_multi_edge(self, v1, v2, cap1, cap2):
			edge1 = [v2, cap1, None]
			edge1[2] = edge2 = [v1, cap2, edge1]
			self.G[v1].append(edge1)
			self.G[v2].append(edge2)

		def bfs(self, s, t):
			self.level = level = [None] * self.N
			deq = deque([s])
			level[s] = 0
			G = self.G
			while deq:
				v = deq.popleft()
				lv = level[v] + 1
				for (w, cap, _) in G[v]:
					if cap and level[w] is None:
						level[w] = lv
						deq.append(w)
			return level[t] is not None

		def dfs(self, v, t, f):
			if v == t:
				return f
			level = self.level
			for e in self.it[v]:
				(w, cap, rev) = e
				if cap and level[v] < level[w]:
					d = self.dfs(w, t, min(f, cap))
					if d:
						e[1] -= d
						rev[1] += d
						return d
			return 0

		def flow(self, s, t):
			flow = 0
			INF = 10 ** 9 + 7
			G = self.G
			while self.bfs(s, t):
				(*self.it,) = map(iter, self.G)
				f = INF
				while f:
					f = self.dfs(s, t, INF)
					flow += f
			return flow
	(H, W) = map(int, input().split())
	grid = []
	for _ in range(H):
		line = input().rstrip('\n')
		grid.append(line)
	dinic = Dinic(H + W + 5)
	for h in range(H):
		for w in range(W):
			if grid[h][w] == 'o':
				dinic.add_edge(h + 1, H + w + 1, 1)
				dinic.add_edge(H + w + 1, h + 1, 1)
			elif grid[h][w] == 'S':
				dinic.add_edge(H + W + 1, h + 1, 10 ** 5)
				dinic.add_edge(H + W + 1, H + w + 1, 10 ** 5)
			elif grid[h][w] == 'T':
				dinic.add_edge(h + 1, H + W + 2, 10 ** 5)
				dinic.add_edge(H + w + 1, H + W + 2, 10 ** 5)
	ans = dinic.flow(H + W + 1, H + W + 2)
	if ans > 400:
		print(-1)
	else:
		print(ans)
main()


from collections import deque

class MF_graph(object):

	def __init__(self, n):
		self.n = n
		self.g = [[] for _ in range(n)]
		self.pos = []

	def add_edge(self, frm, to, cap):
		m = len(self.pos)
		self.pos.append((frm, len(self.g[frm])))
		self.g[frm].append([to, len(self.g[to]), cap])
		self.g[to].append([frm, len(self.g[frm]) - 1, 0])
		return m

	def get_edge(self, i):
		(e_to, e_rev, e_cap) = self.g[self.pos[i][0]][self.pos[i][1]]
		(re_to, _, re_cap) = self.g[e_to][e_rev]
		return (re_to, e_to, e_cap + re_cap, re_cap)

	def edges(self):
		m = len(self.pos)
		for i in range(m):
			yield self.get_edge(i)

	def change_edge(self, i, new_cap, new_flow):
		(f, s) = self.pos[i]
		(rf, rs, _) = self.g[f][s]
		self.g[f][s][2] = new_cap - new_flow
		self.g[rf][rs][2] = new_flow
		return

	def dfs(self, s, v, up):
		if v == s:
			return up
		res = 0
		level_v = self.level[v]
		for i in range(self.iter[v], len(self.g[v])):
			(u_to, u_rev, _) = self.g[v][i]
			if level_v <= self.level[u_to] or self.g[u_to][u_rev][2] == 0:
				continue
			d = self.dfs(s, u_to, min(up - res, self.g[u_to][u_rev][2]))
			if d <= 0:
				continue
			self.g[v][i][2] += d
			self.g[u_to][u_rev][2] -= d
			res += d
			if res == up:
				break
		return res

	def flow(self, s, t, flow_limit=10 ** 18):
		self.iter = [0] * self.n
		flow = 0
		while flow < flow_limit:
			self.level = [-1] * self.n
			self.level[s] = 0
			que = deque([s])
			while que:
				v = que.popleft()
				for (u_to, _, u_cap) in self.g[v]:
					if u_cap == 0 or self.level[u_to] >= 0:
						continue
					self.level[u_to] = self.level[v] + 1
					if u_to == t:
						break
					que.append(u_to)
			if self.level[t] == -1:
				break
			self.iter = [0] * self.n
			while flow < flow_limit:
				f = self.dfs(s, t, flow_limit - flow)
				if not f:
					break
				flow += f
		return flow

	def min_cut(self, s):
		visited = [False] * self.n
		que = deque([s])
		while que:
			v = que.popleft()
			visited[v] = True
			for (u_to, _, u_cap) in self.g[v]:
				if u_cap and (not visited[u_to]):
					visited[u_to] = True
					que.append(u_to)
		return visited
(H, W) = map(int, input().split())
S = [input() for _ in range(H)]
inf = 10 ** 18
g = MF_graph(H + W + 2)
source = H + W
sink = H + W + 1
for i in range(H):
	for j in range(W):
		if S[i][j] == 'S':
			g.add_edge(source, i, inf)
			g.add_edge(source, H + j, inf)
		elif S[i][j] == 'T':
			g.add_edge(i, sink, inf)
			g.add_edge(H + j, sink, inf)
		elif S[i][j] == 'o':
			g.add_edge(i, H + j, 1)
			g.add_edge(H + j, i, 1)
flow = g.flow(source, sink)
if flow >= inf:
	print(-1)
else:
	print(flow)


import networkx as nx
(H, W) = map(int, input().split())
a = [input() for _ in range(H)]
INF = 10 ** 20
G = nx.Graph()
G.add_nodes_from(range(0, H + W + 2))
for i in range(H):
	for j in range(W):
		if a[i][j] == 'o':
			G.add_edge(i + 1, j + H + 1, capacity=1)
		if a[i][j] == 'S':
			G.add_edge(0, i + 1, capacity=INF)
			G.add_edge(0, j + H + 1, capacity=INF)
		if a[i][j] == 'T':
			G.add_edge(H + W + 1, i + 1, capacity=INF)
			G.add_edge(H + W + 1, j + H + 1, capacity=INF)
(flow_value, flow_dict) = nx.maximum_flow(G, 0, H + W + 1)
print(flow_value if flow_value < INF else -1)


from collections import deque

class Dinic:

	def __init__(self, N):
		self.N = N
		self.G = [[] for i in range(N)]

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		forward[2] = backward = [fr, 0, forward]
		self.G[fr].append(forward)
		self.G[to].append(backward)

	def add_multi_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge1[2] = edge2 = [v1, cap2, edge1]
		self.G[v1].append(edge1)
		self.G[v2].append(edge2)

	def bfs(self, s, t):
		self.level = level = [None] * self.N
		deq = deque([s])
		level[s] = 0
		G = self.G
		while deq:
			v = deq.popleft()
			lv = level[v] + 1
			for (w, cap, _) in G[v]:
				if cap and level[w] is None:
					level[w] = lv
					deq.append(w)
		return level[t] is not None

	def dfs(self, v, t, f):
		if v == t:
			return f
		level = self.level
		for e in self.it[v]:
			(w, cap, rev) = e
			if cap and level[v] < level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d:
					e[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		INF = 10 ** 10
		G = self.G
		while self.bfs(s, t):
			(*self.it,) = list(map(iter, self.G))
			f = INF
			while f:
				f = self.dfs(s, t, INF)
				flow += f
		return flow
inf = 10 ** 9
(H, W) = list(map(int, input().split()))
a = [list(input()) for _ in range(H)]
D = Dinic(H + W + 2)
for i in range(H):
	for j in range(W):
		if a[i][j] == 'S':
			D.add_edge(0, i + 1, inf)
			D.add_edge(0, j + 1 + H, inf)
		elif a[i][j] == 'T':
			D.add_edge(i + 1, H + W + 1, inf)
			D.add_edge(j + 1 + H, H + W + 1, inf)
		elif a[i][j] == 'o':
			D.add_edge(i + 1, j + 1 + H, 1)
			D.add_edge(j + 1 + H, i + 1, 1)
ans = D.flow(0, H + W + 1)
print(ans if ans < inf else -1)


from collections import deque

class EDOMONDS_KARP:

	def __init__(self, N, s, t):
		self.N = N
		self.s = s
		self.t = t
		self.cap = [[0] * N for _ in range(N)]
		self.link = [[] for _ in range(N)]

	def add_edge(self, u, v, c):
		self.cap[u][v] = c
		self.link[u].append(v)
		self.link[v].append(u)

	def max_flow(self):
		N = self.N
		s = self.s
		t = self.t
		f = 0
		flow = [[0] * N for _ in range(N)]
		while True:
			(m, prev) = self.bfs(flow)
			if m == 0:
				break
			f += m
			v = t
			while v != s:
				u = prev[v]
				flow[u][v] += m
				flow[v][u] -= m
				v = u
		return (f, flow)

	def bfs(self, flow):
		N = self.N
		s = self.s
		t = self.t
		cap = self.cap
		link = self.link
		prev = [-1] * N
		prev[s] = -2
		m = [0] * N
		m[s] = float('inf')
		q = deque([s])
		while q:
			u = q.popleft()
			for v in link[u]:
				if cap[u][v] - flow[u][v] > 0 and prev[v] == -1:
					prev[v] = u
					m[v] = min(m[u], cap[u][v] - flow[u][v])
					if v != t:
						q.append(v)
					else:
						return (m[t], prev)
		return (0, prev)
(H, W) = list(map(int, input().split()))
board = [input() for _ in range(H)]
EK = EDOMONDS_KARP(H + W + 2, 0, H + W + 1)
for h in range(H):
	for w in range(W):
		if board[h][w] == 'o':
			EK.add_edge(h + 1, w + H + 1, 1)
			EK.add_edge(w + H + 1, h + 1, 1)
		if board[h][w] == 'S':
			EK.add_edge(0, h + 1, float('inf'))
			EK.add_edge(0, w + H + 1, float('inf'))
		if board[h][w] == 'T':
			EK.add_edge(h + 1, H + W + 1, float('inf'))
			EK.add_edge(w + H + 1, H + W + 1, float('inf'))
(f, _) = EK.max_flow()
print(f if f < float('inf') else -1)


def main():
	import sys
	sys.setrecursionlimit(1000000)

	def add_edge(From, to, cap):
		g[From][to] = cap
		g[to][-From - 1] = 0

	def max_flow(s, t):

		def dfs(v, t, f):
			q.append(v)
			if v == t:
				return f
			used[v] += 1
			for i in range(len(gkey[v])):
				to = gkey[v][i]
				cap = g[v][to]
				if to < 0:
					to2 = -to - 1
				else:
					to2 = to
				if used[to2] or cap == 0:
					continue
				d = dfs(to2, t, min(f, cap))
				if d > 0:
					g[v][to] -= d
					g[to2][-v - 1] += d
					return d
			q.pop()
			return 0
		flow = 0
		while True:
			used = [0] * n
			q = []
			f = dfs(s, t, 10 ** 100)
			if not q:
				return flow
			flow += f
	(h, w) = list(map(int, input().split()))
	n = h + w + 2
	g = [dict() for _ in range(n)]
	for i in range(h):
		A = input()
		for j in range(w):
			if A[j] == 'o':
				add_edge(i, j + h, 1)
				add_edge(j + h, i, 1)
			elif A[j] == 'S':
				add_edge(h + w, i, 10 ** 6)
				add_edge(h + w, j + h, 10 ** 6)
			elif A[j] == 'T':
				add_edge(i, h + w + 1, 10 ** 6)
				add_edge(j + h, h + w + 1, 10 ** 6)
	gkey = [list(i.keys()) for i in g]
	ans = max_flow(h + w, h + w + 1)
	if ans >= 10 ** 6:
		print(-1)
	else:
		print(ans)
main()


def dfs(v, t, f, used, graph):
	if v == t:
		return f
	used[v] = True
	for to in graph[v]:
		c = graph[v][to]
		if used[to] or c == 0:
			continue
		d = dfs(to, t, min(f, c), used, graph)
		if d > 0:
			graph[v][to] -= d
			graph[to][v] += d
			return d
	return 0

def max_flow(s, t, graph):
	flow = 0
	while True:
		used = [False] * len(graph)
		f = dfs(s, t, float('inf'), used, graph)
		flow += f
		if f == 0 or f == float('inf'):
			return flow
(H, W) = map(int, input().split())
a = [input() for _ in range(H)]
a = [[s for s in a[i]] for i in range(H)]
graph = [{} for _ in range(H + W + 2)]
for h in range(H):
	for w in range(W):
		if a[h][w] == 'o':
			graph[h][H + w] = 1
			graph[H + w][h] = 1
		if a[h][w] == 'S':
			graph[H + W][h] = float('inf')
			graph[H + W][H + w] = float('inf')
			graph[h][H + W] = 0
			graph[H + w][H + W] = 0
		if a[h][w] == 'T':
			graph[H + W + 1][h] = 0
			graph[H + W + 1][H + w] = 0
			graph[h][H + W + 1] = float('inf')
			graph[H + w][H + W + 1] = float('inf')
ans = max_flow(H + W, H + W + 1, graph)
if ans == float('inf'):
	ans = -1
print(ans)


def examC():
	ans = 0
	print(ans)
	return

def examD():
	ans = 0
	print(ans)
	return

def examE():
	ans = 0
	print(ans)
	return

def examF():

	class Dinic:

		def __init__(self, n):
			self.n = n
			self.links = [[] for _ in range(n)]
			self.depth = None
			self.progress = None

		def add_link(self, _from, to, cap):
			self.links[_from].append([cap, to, len(self.links[to])])
			self.links[to].append([0, _from, len(self.links[_from]) - 1])

		def bfs(self, s):
			depth = [-1] * self.n
			depth[s] = 0
			q = deque([s])
			while q:
				v = q.popleft()
				for (cap, to, rev) in self.links[v]:
					if cap > 0 and depth[to] < 0:
						depth[to] = depth[v] + 1
						q.append(to)
			self.depth = depth

		def dfs(self, v, t, flow):
			if v == t:
				return flow
			links_v = self.links[v]
			for i in range(self.progress[v], len(links_v)):
				self.progress[v] = i
				(cap, to, rev) = link = links_v[i]
				if cap == 0 or self.depth[v] >= self.depth[to]:
					continue
				d = self.dfs(to, t, min(flow, cap))
				if d == 0:
					continue
				link[0] -= d
				self.links[to][rev][0] += d
				return d
			return 0

		def max_flow(self, s, t):
			flow = 0
			while True:
				self.bfs(s)
				if self.depth[t] < 0:
					return flow
				self.progress = [0] * self.n
				current_flow = self.dfs(s, t, inf)
				while current_flow > 0:
					flow += current_flow
					current_flow = self.dfs(s, t, inf)
	(H, W) = LI()
	A = [SI() for _ in range(H)]
	din = Dinic(H + W + 2)
	for h in range(H):
		for w in range(W):
			if A[h][w] == 'S':
				din.add_link(0, h + W + 1, inf)
				din.add_link(0, w + 1, inf)
			elif A[h][w] == 'T':
				din.add_link(h + W + 1, H + W + 1, inf)
				din.add_link(w + 1, H + W + 1, inf)
			elif A[h][w] == 'o':
				din.add_link(h + W + 1, w + 1, 1)
				din.add_link(w + 1, h + W + 1, 1)
	ans = din.max_flow(0, H + W + 1)
	if ans >= inf:
		ans = -1
	print(ans)
	return
from decimal import getcontext, Decimal as dec
import sys, bisect, itertools, heapq, math, random
from copy import deepcopy
from heapq import heappop, heappush, heapify
from collections import Counter, defaultdict, deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

def I():
	return int(input())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def DI():
	return dec(input())

def LDI():
	return list(map(dec, sys.stdin.readline().split()))

def LSI():
	return list(map(str, sys.stdin.readline().split()))

def LS():
	return sys.stdin.readline().split()

def SI():
	return sys.stdin.readline().strip()
global mod, mod2, inf, alphabet, _ep
mod = 10 ** 9 + 7
mod2 = 998244353
inf = 10 ** 18
_ep = dec('0.000000000001')
alphabet = [chr(ord('a') + i) for i in range(26)]
alphabet_convert = {chr(ord('a') + i): i for i in range(26)}
getcontext().prec = 28
sys.setrecursionlimit(10 ** 7)
examF()


from collections import defaultdict
from collections import deque

def Ford_Fulkerson_Func(s, g, lines, cost):
	N = len(cost)
	ans = 0
	queue = deque([[s, float('inf')]])
	ed = [True] * N
	ed[s] = False
	route = [0] * N
	route[s] = -1
	while queue:
		(now, flow) = queue.pop()
		for nex in lines[now]:
			if ed[nex]:
				flow = min(cost[now][nex], flow)
				route[nex] = now
				queue.append([nex, flow])
				ed[nex] = False
				if nex == g:
					ans += flow
					break
		else:
			continue
		break
	else:
		return (False, ans)
	t = g
	s = route[t]
	while s != -1:
		cost[s][t] -= flow
		if cost[s][t] == 0:
			lines[s].remove(t)
		if cost[t][s] == 0:
			lines[t].add(s)
		cost[t][s] += flow
		t = s
		s = route[t]
	return (True, ans)

def Ford_Fulkerson(s, g, lines, cost):
	ans = 0
	while True:
		(fl, nans) = Ford_Fulkerson_Func(s, g, lines, cost)
		if fl:
			ans += nans
			continue
		else:
			break
	return ans
(H, W) = map(int, input().split())
lines = defaultdict(set)
cost = [[0] * 202 for i in range(202)]
for i in range(H):
	a = input()
	for j in range(W):
		if a[j] == 'S':
			lines[200].add(i)
			cost[200][i] = 20000
			lines[200].add(100 + j)
			cost[200][100 + j] = 20000
		elif a[j] == 'T':
			lines[i].add(201)
			cost[i][201] = 20000
			lines[100 + j].add(201)
			cost[j + 100][201] = 20000
		elif a[j] == 'o':
			lines[i].add(j + 100)
			cost[i][j + 100] = 1
			lines[j + 100].add(i)
			cost[j + 100][i] = 1
ans = Ford_Fulkerson(200, 201, lines, cost)
if ans >= 20000:
	print(-1)
else:
	print(ans)


from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
import math
import bisect
import random
from itertools import permutations, accumulate, combinations, product
import sys
from pprint import pprint
from copy import deepcopy
import string
from bisect import bisect_left, bisect_right
from math import factorial, ceil, floor
from operator import mul
from functools import reduce
from pprint import pprint
sys.setrecursionlimit(2147483647)
INF = 10 ** 15

def LI():
	return list(map(int, sys.stdin.buffer.readline().split()))

def I():
	return int(sys.stdin.buffer.readline())

def LS():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8').split()

def S():
	return sys.stdin.buffer.readline().rstrip().decode('utf-8')

def IR(n):
	return [I() for i in range(n)]

def LIR(n):
	return [LI() for i in range(n)]

def SR(n):
	return [S() for i in range(n)]

def LSR(n):
	return [LS() for i in range(n)]

def SRL(n):
	return [list(S()) for i in range(n)]

def MSRL(n):
	return [[int(j) for j in list(S())] for i in range(n)]
mod = 1000000007

class Dinic:

	def __init__(self, n):
		self.n = n
		self.G = [[] for _ in range(n)]
		self.level = None
		self.it = None

	def add_edge(self, fr, to, cap):
		forward = [to, cap, None]
		forward[2] = backward = [fr, 0, forward]
		self.G[fr].append(forward)
		self.G[to].append(backward)

	def add_multi_edge(self, v1, v2, cap1, cap2):
		edge1 = [v2, cap1, None]
		edge1[2] = edge2 = [v1, cap2, edge1]
		self.G[v1].append(edge1)
		self.G[v2].append(edge2)

	def bfs(self, s, t):
		self.level = level = [-1] * self.n
		deq = deque([s])
		level[s] = 0
		G = self.G
		while deq:
			v = deq.popleft()
			lv = level[v] + 1
			for (w, cap, _) in G[v]:
				if cap and level[w] == -1:
					level[w] = lv
					deq.append(w)
		return level[t] != -1

	def dfs(self, v, t, f):
		if v == t:
			return f
		for e in self.it[v]:
			(w, cap, rev) = e
			if cap and self.level[v] < self.level[w]:
				d = self.dfs(w, t, min(f, cap))
				if d:
					e[1] -= d
					rev[1] += d
					return d
		return 0

	def flow(self, s, t):
		flow = 0
		INF = 10 ** 18
		while self.bfs(s, t):
			(*self.it,) = map(iter, self.G)
			f = INF
			while f:
				f = self.dfs(s, t, INF)
				flow += f
		return flow
(h, w) = LI()
dinic = Dinic(h + w + 2)
s = SR(h)
for i in range(h):
	for j in range(w):
		if s[i][j] == 'o':
			dinic.add_multi_edge(i, h + j, 1, 1)
		elif s[i][j] == 'S':
			dinic.add_edge(h + w, i, INF)
			dinic.add_edge(h + w, h + j, INF)
		elif s[i][j] == 'T':
			dinic.add_edge(i, h + w + 1, INF)
			dinic.add_edge(h + j, h + w + 1, INF)
ans = dinic.flow(h + w, h + w + 1)
print(ans if ans < INF else -1)