Problem:
Score : 800 points

Problem Statement

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 1

3 3
S.o
.o.
o.T

Sample Output 1

2

Remove the upper-right and lower-left leaves.

Sample Input 2

3 4
S...
.oo.
...T

Sample Output 2

0

Sample Input 3

4 3
.S.
.o.
.o.
.T.

Sample Output 3

-1

Sample Input 4

10 10
.o...o..o.
....o.....
....oo.oo.
..oooo..o.
....oo....
..o..o....
o..o....So
o....T....
....o.....
........oo

Sample Output 4

5

Solution in LuaJIT (2.0.4) (judge verdict: Accepted)

local mma = math.max
local mfl, mce, mmi = math.floor, math.ceil, math.min
local SegTree = {}
SegTree.updateAll = function(self)
  for i = self.stagenum - 1, 1, -1 do
    for j = 1, self.cnt[i] do
      self.stage[i][j] = self.func(self.stage[i + 1][j * 2 - 1], self.stage[i + 1][j * 2])
    end
  end
end
SegTree.create = function(self, n, func)
  self.func = func
  local stagenum, mul = 1, 1
  self.cnt, self.stage, self.size = {1}, {{}}, {}
  while mul < n do
    mul, stagenum = mul * 2, stagenum + 1
    self.cnt[stagenum], self.stage[stagenum] = mul, {}
  end
  for i = 1, stagenum do self.size[i] = self.cnt[stagenum + 1 - i] end
  self.stagenum = stagenum
  for i = 1, n do self.stage[stagenum][i] = i end
  for i = n + 1, mul do self.stage[stagenum][i] = n + 1 end
  self:updateAll()
end
SegTree.update = function(self, idx)
  for i = self.stagenum - 1, 1, -1 do
    local dst = mce(idx / 2)
    local rem = dst * 4 - 1 - idx
    self.stage[i][dst] = self.func(self.stage[i + 1][idx], self.stage[i + 1][rem])
    idx = dst
  end
end
SegTree.new = function(n, func)
  local obj = {}
  setmetatable(obj, {__index = SegTree})
  obj:create(n, func)
  return obj
end

local h, w = io.read("*n", "*n", "*l")
local idxedges = {}
local sidx, gidx = 0, 0

--[[
1, ..., w: column i
w + 1, ..., w + h: row i
w + h + 1: startpos
w + h + 2: goalpos
]]
local snode = w + h + 1
local gnode = w + h + 2
local edge = {}
for i = 1, gnode do
  edge[i] = {}
end

for i = 1, h do
  local str = io.read()
  for j = 1, w do
    local idx = (i - 1) * w + j
    local s = str:sub(j, j)
    if s == "S" then
      sidx = idx
    elseif s == "T" then
      gidx = idx
    elseif s == "o" then
      table.insert(idxedges, idx)
    end
  end
end
local function getrowcol(idx)
  local r = 1 + mfl((idx - 1) / w)
  local c = idx % w
  if c == 0 then c = w end
  return r, c
end

local len, stlen = {}, {}
for i = 1, gnode + 1 do
  len[i] = gnode
  stlen[i] = gnode
end
local seg = SegTree.new(gnode, function(x, y) return stlen[x] < stlen[y] and x or y end)

local function runDijkstra()
  for i = 1, gnode + 1 do
    len[i] = gnode
    stlen[i] = gnode
  end
  len[snode] = 0
  stlen[snode] = 0
  seg:updateAll()
  for i = 1, gnode do
    local node = seg.stage[1][1]
    if gnode <= stlen[node] then
      break
    end
    for dst, v in pairs(edge[node]) do
      if len[node] + 1 < len[dst] then
        len[dst] = len[node] + 1
        stlen[dst] = stlen[node] + 1
        seg:update(dst)
      end
    end
    stlen[node] = gnode
    seg:update(node)
  end
  if gnode <= len[gnode] then
    return false
  else
    -- reverse walk
    local cur = gnode
    while cur ~= snode do
      for dst, v in pairs(edge[cur]) do
        if v and len[dst] + 1 == len[cur] then
          edge[cur][dst] = edge[cur][dst] - 1
          edge[dst][cur] = edge[dst][cur] - 1
          if edge[cur][dst] == 0 then
            edge[cur][dst] = nil
            edge[dst][cur] = nil
          end
          cur = dst
          break
        end
      end
    end
    return true
  end
end

local function solve()
  local sr, sc = getrowcol(sidx)
  local gr, gc = getrowcol(gidx)
  if sr == gr or sc == gc then
    return -1
  end
  local idxedgenum = #idxedges
  local function addedge(a, b)
    if not edge[a][b] then edge[a][b] = 1
    else edge[a][b] = edge[a][b] + 1 end
    if not edge[b][a] then edge[b][a] = 1
    else edge[b][a] = edge[b][a] + 1 end
  end
  for i = 1, idxedgenum do
    local r, c = getrowcol(idxedges[i])
    if r == sr then
      if c == gc then
        addedge(snode, gnode)
      else
        addedge(snode, c)
      end
    elseif r == gr then
      if c == sc then
        addedge(snode, gnode)
      else
        addedge(gnode, c)
      end
    else
      if c == sc then
        addedge(snode, r + w)
      elseif c == gc then
        addedge(gnode, r + w)
      else
        addedge(c, r + w)
      end
    end
  end
  local cnt = 0
  while true do
    if runDijkstra() then
      cnt = cnt + 1
    else
      break
    end
  end
  return cnt
end
print(solve())