class Heap
	require 'forwardable'
	extend Forwardable

	def initialize
		@array = []
		@index = {}
	end

	def add(obj, key)
		@array << [obj, key]
		@index[obj] = @array.size - 1
		lift_up(@array.size - 1)
	end

	def swap(i, j)
		u = @array[i]
		v = @array[j]
		@index[u[0]], @index[v[0]] = j, i
		@array[i], @array[j] = v, u
	end

	def lift_up(i)
		return if i == 0
		j = (i - 1) / 2
		if @array[i][1] < @array[j][1]
			swap(i, j)
			lift_up(j)
		end
	end

	def del_min
		raise "heap is empty!" if empty?
		min = @array[0]
		if size > 1
			swap(0, @array.size-1)
			@array.pop
			lift_down(0)
		else
			@array.pop
		end
		@index.delete(min[0])
		min
	end

	def inc_key(obj, diff)
		i = @index[obj]
		@array[i][1] += diff
		lift_down(i)
	end

	def dec_key(obj, diff)
		i = @index[obj]
		@array[i][1] -= diff
		lift_up(i)
	end

	def update_key(obj, new_key)
		i = @index[obj]
		return unless i
		return if new_key >= @array[i][1]
		@array[i][1] = new_key
		lift_up(i)
	end

	def min_obj
		@array[0][0]
	end

	def min_key
		@array[0][1]
	end

	def lift_down(i)
		j = 2 * i + 1
		k = j + 1
		if k >= size
			return if j >= size
			if @array[i][1] > @array[j][1]
				swap(i, j)
				lift_down(j)
			end
		else
			l = (@array[j][1] < @array[k][1] ? j : k)
			if @array[i][1] > @array[l][1]
				swap(i, l)
				lift_down(l)
			end
		end
	end

	def_delegators :@array, :empty?, :size
end

module Graphical
	require 'set'

	def reachable_from(s, max_depth = nil)
		reached = Set[s]
		queue = [s]
		depth = 0
		loop {
			break if max_depth && depth >= max_depth
			next_queue = []
			until queue.empty?
				u = queue.shift
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
			depth += 1
		}
		return reached
	end

	def bfs(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		reached = Set[*start.to_a]
		queue = []
		start.each{|s| queue << s}
		dist = {}
		loop.with_index {|_, depth|
			next_queue = []
			until queue.empty?
				u = queue.shift
				dist[u] = depth
				each_out_connection_of(u){|v, _|
					next if reached.include?(v)
					reached << v
					next_queue << v
				}
			end
			break if next_queue.empty?
			queue = next_queue
		}
		return dist
	end
	
	def dijkstra(start)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		h = Heap.new
		reached = Set[*start.to_a]
		start.each{|s| h.add(s, 0)}

		dist = {}
		until h.empty?
			u, key = h.del_min
			return key if block_given? && yield(u, key)
			dist[u] = key
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	def bidir_dijkstra(start, goal)
		raise "start must be Enumerable" if !start.kind_of?(Enumerable)
		raise "goal must be Enumerable" if !goal.kind_of?(Enumerable)
		f_dist = {}
		b_dist = {}

		f_heap = Heap.new
		b_heap = Heap.new

		start.each{|s| f_heap.add(s, 0)}
		goal.each{|t| b_heap.add(t, 0)}

		f_reached = Set[*start.to_a]
		b_reached = Set[*goal.to_a]

		f_current_dist = b_current_dist = 0
		best = Float::INFINITY

		loop {
			if !f_heap.empty?
				u, key = f_heap.del_min
				f_dist[u] = key
				f_current_dist = key
				each_out_connection_of(u){|v, l|
					d = f_dist[u] + l
					if b_dist[v]
						path_len = d + b_dist[v]
						best = path_len if path_len < best
					end
					if f_reached.include?(v)
						f_heap.update_key(v, d)
					else
						f_heap.add(v, d)
						f_reached << v
					end
				}
			end

			if !b_heap.empty?
				u, key = b_heap.del_min
				b_dist[u] = key
				b_current_dist = key
				each_in_connection_of(u){|v, l|
					d = b_dist[u] + l
					if f_dist[v]
						path_len = d + f_dist[v]
						best = path_len if path_len < best
					end
					if b_reached.include?(v)
						b_heap.update_key(v, d)
					else
						b_heap.add(v, d)
						b_reached << v
					end
				}
			end

			return best if f_current_dist + b_current_dist >= best
			return nil if f_heap.empty? && b_heap.empty?
		}
	end

	def a_star(start)
		raise "a_star need termination condition" unless block_given?
		h = Heap.new
		reached = Set[start]
		h.add(start, [a_star_heuristic(start), 0])

		dist = {}
		until h.empty?
			u, (e, d) = h.del_min
			return d if yield(u, dist)
			dist[u] = d
			each_out_connection_of(u){|v, l|
				d = dist[u] + l
				e = d + a_star_heuristic(v)
				if reached.include?(v)
					h.update_key(v, [e, d])
				else
					h.add(v, [e, d])
					reached << v
				end
			}
		end
		block_given? ? nil : dist
	end

	#make_variations :bidir_dijkstra

	def prim(start)
		h = Heap.new
		h.add(start, 0)
		reached = Set[start]
		tree_len = 0

		until h.empty?
			u, key = h.del_min
			tree_len += key

			each_connection_of(u){|v, d|
				if reached.include?(v)
					h.update_key(v, d)
				else
					h.add(v, d)
					reached << v
				end
			}
		end
		tree_len
	end
end

module Grid
	def each_neighbour_of(u)
		y, x = u
		[[-1,0],[1,0],[0,-1],[0,1]].each{|dy, dx|
			i, j = y+dy, x+dx
			yield [i, j] if (0..self.size-1) === i && (0..self[0].size-1) === j
		}
	end
end


loop {
	w, h = gets.split.map &:to_i
	break if w == 0
	$a = (1..h).map { gets.chomp.split }
	$a.extend Graphical
	$a.extend Grid
	def $a.each_out_connection_of(u)
		each_neighbour_of(u){|v|
			yield [v, 1]
		}
	end

	extend Graphical
	def each_out_connection_of(legs)
		left, right = legs
		if left
			$a.reachable_from(left, 3).each{|v|
				y, x = v
				yield [[nil, v], $a[y][x].to_i] if left[1] < x && $a[v[0]][v[1]] != ?X
			}
		else 
			$a.reachable_from(right, 3).each{|v|
				y, x = v
				yield [[v, nil], $a[y][x].to_i] if x < right[1] && $a[v[0]][v[1]] != ?X
			}
		end
	end

	def each_in_connection_of(legs)
		left, right = legs
		if left
			$a.reachable_from(left, 3).each{|v|
				y, x = v
				yield [[nil, v], $a[left[0]][left[1]].to_i] if left[1] < x && $a[v[0]][v[1]] != ?X
			}
		else 
			$a.reachable_from(right, 3).each{|v|
				y, x = v
				yield [[v, nil], $a[right[0]][right[1]].to_i] if x < right[1] && $a[v[0]][v[1]] != ?X
			}
		end
	end

	starts = Set.new
	goals = Set.new
	(0..h-1).each{|i|
		(0..w-1).each{|j|
			starts << [i,j] if $a[i][j] == ?S
			goals << [i,j] if $a[i][j] == ?T
		}
	}

	p bidir_dijkstra(
		starts.map{|y, x|
			[ [[y,x], nil], [nil, [y,x]] ]
		}.flatten(1),
		goals.map{|y, x|
			[ [[y,x], nil], [nil, [y,x]] ]
		}.flatten(1)
	) || -1
}

Measured memory_bytes: 8632