#include<iostream>
#include<algorithm>
#include<queue>
#include<functional>
#include<tuple>
#include<string>
#include<vector>
using namespace std;

#define WHITE 0
#define GRAY 1
#define BLACK 2
#define MAX_DIR 9
#define MAX_N 100
#define INF 1 << 30

string C;
int X[MAX_N][MAX_N];
int S[MAX_N][MAX_N];
int G[MAX_N][MAX_N];
int DIST[MAX_N][MAX_N][MAX_DIR];//Left,DY-DX
int dx[MAX_DIR] = { 1,1,1,1,1,2,2,2,3 };
int dy[MAX_DIR] = { -2,-1,0,1,2,-1,0,1,0 };
int dz[MAX_DIR] = { 4,3,2,1,0,7,6,5,8 };
int H, W;
char U[11] = "0123456789";

priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>, greater<tuple<int, int, int, int>> > Q;

void MEMSET() {
	while (!Q.empty()) {
		Q.pop();
	}
	for (int i = 0; i < MAX_N; i++) {
		for (int j = 0; j < MAX_N; j++) {
			X[i][j] = INF;
			S[i][j] = 0;
			G[i][j] = 0;
			for (int k = 0; k < MAX_DIR; k++) {
				DIST[i][j][k] = INF;
			}
		}
	}
}

int DIJKSTRA() {
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			if (S[i][j] == 1) {
				for (int k = 0; k < MAX_DIR; k++) {
					int Y1 = i + dy[k];
					int X1 = j + dx[k];
					if (S[Y1][X1] == 1) {
						DIST[i][j][k] = 0;
						Q.push(make_tuple(0, i, j, k));
					}
				}
			}
		}
	}
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			if (S[i][j] == 1) {
				for (int k = 0; k < MAX_DIR; k++) {
					int Y1 = i + dy[k];
					int X1 = j - dx[k];
					if (S[Y1][X1] == 1) {
						DIST[Y1][X1][dz[k]] = 0;
						Q.push(make_tuple(0, Y1, X1, dz[k]));
					}
				}
			}
		}
	}
	while (!Q.empty()) {
		tuple<int, int, int, int>tup = Q.top();
		Q.pop();
		int a1 = get<0>(tup);
		int a2 = get<1>(tup);
		int a3 = get<2>(tup);
		int a4 = get<3>(tup);
		int LY = a2, LX = a3;
		int RY = a2 + dy[a4], RX = a3 + dx[a4];

		//hidari.
		for (int k = 0; k < MAX_DIR; k++)
		{
			int cy = RY + dy[k];
			int cx = RX - dx[k];
			if (cy < 1 || cy > H) {
				goto H;
			}
			if (cx < 1 || cx > W) {
				goto H;
			}
			if (RY < 1 || RY > H) {
				goto H;
			}
			if (RX < 1 || RX > W) {
				goto H;
			}

			if (X[cy][cx] < INF) {
				int dis = X[cy][cx];
				int pos = DIST[LY][LX][a4];
				if (DIST[cy][cx][dz[k]] > dis + pos) {
					DIST[cy][cx][dz[k]] = dis + pos;
					Q.push(make_tuple(DIST[cy][cx][dz[k]], cy, cx, dz[k]));
				}
			}
		H:;
		}
		//migi.
		for (int k = 0; k < MAX_DIR; k++) {
			int cy = LY + dy[k];
			int cx = LX + dx[k];
			if (cy < 1 || cy > H) {
				goto I;
			}
			if (cx < 1 || cx > W) {
				goto I;
			}
			if (LY < 1 || LY > H) {
				goto I;
			}
			if (LX < 1 || LX > W) {
				goto I;
			}

			if (X[cy][cx] < INF) {
				int dis = X[cy][cx];
				int pos = DIST[LY][LX][a4];
				if (DIST[LY][LX][k] > dis + pos) {
					DIST[LY][LX][k] = dis + pos;
					Q.push(make_tuple(DIST[LY][LX][k], LY, LX, k));
				}
			}
		I:;
		}
	}
	int res = INF;
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			if (G[i][j] == 1) {
				for (int k = 0; k < MAX_DIR; k++) {
					res = min(res, DIST[i][j][k]);
				}
			}
			else {
				for (int k = 0; k < MAX_DIR; k++) {
					int ey = i + dy[k];
					int ex = j + dx[k];
					if (ey < 1 || ey > H) {
						continue;
					}
					if (ex < 1 || ex > W) {
						continue;
					}
					if (G[ey][ex] == 1) {
						res = min(res, DIST[i][j][k]);
					}
				}
			}
		}
	}
	if (res >= INF) {
		return -1;
	}
	return res;
}

int power(int a, int b) {
	int R = 1;
	for (int i = 0; i < b; i++) {
		R *= b;
	}
	return R;
}

void CIN() {
	for (int i = 1; i <= H; i++) {
		for (int j = 1; j <= W; j++) {
			cin >> C;
			if (C == "X") {
				X[i][j] = INF;
			}
			else if (C == "S") {
				X[i][j] = 0;
				S[i][j] = 1;
			}
			else if (C == "T") {
				X[i][j] = 0;
				G[i][j] = 1;
			}
			else {
				int cnt1 = 0;
				int D = C.size();
				for (int k = 0; k < D; k++) {
					for (int l = 0; l < 10; l++) {
						if (C[k] == U[l]) {
							cnt1 += power(10, D - k - 1)*l;
						}
					}
				}
				X[i][j] = cnt1;
			}
		}
	}
	for (int i = 1; i <= W; i++) {
		S[H + 1][i] = 1;
		X[H + 1][i] = 0;
	}
}

int main() {
	while (true) {
		MEMSET();
		//cin.
		cin >> W >> H;
		if (H == 0 && W == 0) {
			break;
		}
		CIN();
		cout << DIJKSTRA() << endl;
	}
	return 0;
}

Measured memory_bytes: 3636