#include <bits/stdc++.h>

class Solve {
private:
	using vc = std::vector<char>;
	using vvc = std::vector<vc>;

	using i3 = std::array<int, 3>;
	using i4 = std::array<int, 4>;

	int W, H;
	int calcNum(const i3 &arr)
	{
		return (arr[0] * W + arr[1]) * 2 + arr[2];
	}
	bool isIn(const i4 &arr)
	{
		return 0 <= arr[1] && arr[1] < H && 0 <= arr[2] && arr[2] < W;
	}

public:
	bool is_last_query{};
	Solve()
	{
		scanf("%d%d", &W, &H);
		if (W == 0)
		{
			is_last_query = true;
			return;
		}

		vvc cliff(H, vc(W));
		for (int i{}; i < H; i++)
			for (int j{}; j < W; j++)
				scanf(" %c", &cliff[i][j]);
		
		std::vector<int> distance(H * W * 2, 1 << 30);
		std::priority_queue<i4, std::vector<i4>, std::greater<i4>> dij;
		for (int i{}; i < W; i++)
			if (cliff[H - 1][i] == 'S')
			{
				distance[calcNum({H - 1, i, 0})] = distance[calcNum({H - 1, i, 1})] = 0;
				dij.push({0, H - 1, i, 0});
				dij.push({0, H - 1, i, 1});
			}
		
		while (!dij.empty())
		{
			i4 now{dij.top()};
			dij.pop();
			if (now[0] > distance[calcNum({now[1], now[2], now[3]})])
				continue;
			if (cliff[now[1]][now[2]] == 'T') break;
			for (int h_i{-2}; h_i <= 2; h_i++)
				for (int w_i{1}; w_i + std::abs(h_i) <= 3; w_i++)
				{
					i4 next{now};
					next[1] += h_i;
					if (next[3])
						next[2] += w_i;
					else
						next[2] -= w_i;
					if (!isIn(next)) continue;
					if (cliff[next[1]][next[2]] == 'X' || cliff[next[1]][next[2]] == 'S') continue;
					if (cliff[next[1]][next[2]] != 'T')
						next[0] += cliff[next[1]][next[2]] - '0';
					next[3] ^= 1;
					int id{calcNum({next[1], next[2], next[3]})};
					if (next[0] >= distance[id]) continue;
					distance[id] = next[0];
					dij.push(next);
				}
		}
		int min{1 << 30};
		for (int i{}; i < W; i++)
			if (cliff[0][i] == 'T')
				min = std::min({min, distance[calcNum({0, i, 0})], distance[calcNum({0, i, 1})]});
		if (min == (1 << 30)) puts("-1");
		else printf("%d\n", min);
	}
};

int main()
{
	while (!Solve().is_last_query);

	return 0;
}
