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())


Measured memory_bytes: 896