#include<iostream>
#include<queue>
#include<vector>
#include<algorithm>
#include<functional>
#include<tuple>

using namespace std;
typedef tuple<int, int, int, int, int, int> t6i;

int w, h;

char gake[60][30];
int d[60][30][60][30][2];

int ans = 999999999;

int vx[9] = { -2,-1,-1,0,0,0,1,1,2 };
int vy[9] = { -1,-2,-1,-3,-2,-1,-2,-1,-1 };
//上の差分ベクトルは左足用、右足の場合は-1倍すること

void djkstra() {
	priority_queue<t6i, vector<t6i>, greater<t6i>> pq;
	for (int i = 0; i < w; i++) {
		if (gake[h - 1][i] == 'S') {
			for (int j = 0; j < 9; j++) {
				//右足スタート 
				int nxtx = h - 1 + vx[j], nxty = i + vy[j];
				int tmp = gake[nxtx][nxty] - '0';
				if (nxtx < 0 || nxty < 0 || nxtx >= h || nxty >= w)goto left;
				if (gake[nxtx][nxty] == 'X')goto left;
				if (gake[nxtx][nxty] == 'S')goto left;
				if (gake[nxtx][nxty] == 'T')tmp = 0;
				pq.push(make_tuple(tmp, nxtx, nxty, h - 1, i, 0));
				d[nxtx][nxty][h - 1][i][0] = tmp;

			left:;

				//左足スタート 
				nxtx = h - 1 + vx[j] * -1, nxty = i + vy[j] * -1;
				tmp = gake[nxtx][nxty] - '0';
				if (nxtx < 0 || nxty < 0 || nxtx >= h || nxty >= w)continue;
				if (gake[nxtx][nxty] == 'X')continue;
				if (gake[nxtx][nxty] == 'S')continue;
				if (gake[nxtx][nxty] == 'T')tmp = 0;
				pq.push(make_tuple(tmp, h - 1, i, nxtx, nxty, 1));
				d[h - 1][i][nxtx][nxty][1] = tmp;
			}
		}
	}
	
	while(pq.size()){
		auto now = pq.top(); pq.pop();
		int lx = get<1>(now), ly = get<2>(now), rx = get<3>(now), ry = get<4>(now);
		int type = get<5>(now);

		if (get<0>(now) > d[lx][ly][rx][ry][type])continue;
		
		//ゴールに到達したのなら、その時点でansを更新
		if (gake[lx][ly] == 'T' || gake[rx][ry] == 'T') {
			ans = min(ans, get<0>(now));
			continue;
		}

		for (int i = 0; i < 9; i++) {
			if (type == 0) {
				//右足を出す番
				int nx = lx + vx[i] * -1, ny = ly + vy[i] * -1;
				if (nx < 0 || ny < 0 || nx >= h || ny >= w)continue;
				if (gake[nx][ny] == 'X')continue;
				if (gake[nx][ny] == 'S')continue;

				//ゴールに到達したのなら、その時点でansを更新
				if (gake[nx][ny] == 'T') {
					ans = min(ans, get<0>(now));
				}

				if (d[lx][ly][nx][ny][1] > d[lx][ly][rx][ry][0] + gake[nx][ny] - '0') {
					d[lx][ly][nx][ny][1] = d[lx][ly][rx][ry][0] + gake[nx][ny] - '0';
					pq.push(make_tuple(d[lx][ly][nx][ny][1], lx, ly, nx, ny, 1));
				}
			}
			else {
				//左足を出す番
				int nx = rx + vx[i] , ny = ry + vy[i];
				if (nx < 0 || ny < 0 || nx >= h || ny >= w)continue;
				if (gake[nx][ny] == 'X')continue;
				if (gake[nx][ny] == 'S')continue;

				//ゴールに到達したのなら、その時点でansを更新
				if (gake[nx][ny] == 'T') {
					ans = min(ans, get<0>(now));
				}

				if (d[nx][ny][rx][ry][0] > d[lx][ly][rx][ry][1] + gake[nx][ny] - '0') {
					d[nx][ny][rx][ry][0] = d[lx][ly][rx][ry][1] + gake[nx][ny] - '0';
					pq.push(make_tuple(d[nx][ny][rx][ry][0], nx, ny, rx, ry, 0));
				}
			}
		}

	}

}

int main() {

	while (1) {
	
		cin >> w >> h;
		if (w + h == 0)return 0;
		for (int i = 0; i < h; i++)for (int j = 0; j < w; j++) {
			cin >> gake[i][j];
		}

		for (int a = 0; a < h; a++)for (int b = 0; b < w; b++)for (int c = 0; c < h; c++)for (int d_ = 0; d_ < w; d_++)
			d[a][b][c][d_][0] = 999999999, d[a][b][c][d_][1] = 999999999;

		djkstra();

		if (ans == 999999999)cout << "-1" << endl;
		else cout << ans << endl;

		ans = 999999999;
	}

	return 0;
}


Measured memory_bytes: 28436