#include <iostream>
#include <stdio.h>
#include <vector>
#include <queue>
#include <functional>
#include <algorithm>
#include <utility>
using namespace std;


struct node_t {
	pair<int, int> p[2];
	node_t(int x1, int y1, int x2, int y2) { 
		p[0].first = y1;
		p[0].second = x1;
		p[1].first = y2;
		p[1].second = x2;
	}
};

int solve(void);
bool isValid(int y, int x, int h, int w) {
	return 0 <= y && y < h && 0 <= x && x < w;
}

int main(void) {
		
//	FILE *fpin = freopen("data.txt", "r", stdin);
	while (solve());

	return 0;

}

int solve(void) {

	//	input
	int w, h;

	cin >> w >> h;
	if (!(w | h)) { return 0; }

	typedef vector<int> v1;
	typedef vector<v1> v2;
	typedef vector<v2> v3;
	typedef vector<v3> v4;
	typedef pair<int, int> pii;

	vector< vector< char > > s(h, vector<char>(w));
	v4 costs(h, v3(w, v2(h, v1(w, (1 << 30)))));

	for (int i = 0; i < h; i++)
		for (int j = 0; j < w; j++)
			cin >> s[i][j];
		
	// right, down, left, up
	vector< vector< pii > > foot(2);

	//	right foot
	//	????¶????0,0???????????¨????????????
	for (int i = -2; i <= 2; i++)
		for (int j = 1; j < 4; j++)
			if (abs(i) + abs(j) <= 3) {
				foot[0].push_back(pii(-i, -j));
			}

	for (int i = 0; i < foot[0].size(); i++)
		foot[1].push_back(pair<int, int>(-foot[0][i].first, -foot[0][i].second));

	vector< pii > startNode;

	for (int i = 0; i < h; i++) 
		for (int j = 0; j < w; j++) 
			if (s[i][j] == 'S') 
				startNode.push_back(pii(i, j));
			
	queue< node_t > q;

	for (int j = 0; j < 2; j++) {
		for (int i = 0; i < startNode.size(); i++) {
			pii pp[2];
			pp[j] = startNode[i];
			for (int k = 0; k < foot[1 - j].size(); k++) {
				pp[1 - j].first = pp[j].first + foot[1 - j][k].first;
				pp[1 - j].second = pp[j].second + foot[1 - j][k].second;
				if (isValid(pp[0].first, pp[0].second, h, w) & isValid(pp[1].first, pp[1].second, h, w)) {
					int weight = 0;
					if (pp[0].second >= pp[1].second) { continue; }
					if (s[pp[1 - j].first][pp[1 - j].second] == 'X') { continue; }
					if (s[pp[1 - j].first][pp[1 - j].second] != 'S') weight = s[pp[1 - j].first][pp[1 - j].second] - '0';
					costs[pp[0].first][pp[0].second][pp[1].first][pp[1].second] = weight;
					q.push(node_t(pp[0].second,pp[0].first, pp[1].second, pp[1].first));
				}
			}
		}
	}

	while (!q.empty()) {

		node_t doneNode = q.front();
		q.pop();

		for (int i = 0; i < 2; i++) {
			for (int j = 0; j < foot[i].size(); j++) {
				node_t next(doneNode);
				int weight = costs[next.p[0].first][next.p[0].second][next.p[1].first][next.p[1].second];
				next.p[i].first = next.p[1-i].first + foot[i][j].first;
				next.p[i].second = next.p[1 - i].second + foot[i][j].second;
				if (isValid(next.p[i].first, next.p[i].second, h, w) && next.p[0].second < next.p[1].second) {
					char ch = s[next.p[i].first][next.p[i].second];
					if (ch >= '0' && ch <= '9') weight += ch - '0';
					if (ch == 'X') { continue; }
					if (weight < costs[next.p[0].first][next.p[0].second][next.p[1].first][next.p[1].second]) {
						costs[next.p[0].first][next.p[0].second][next.p[1].first][next.p[1].second] = weight;
						q.push(next);
					}
				}

			}
		}
	}
	
	int ans = (1 << 30);
	for (int i = 0; i < h; i++) {
		for (int j = 0; j < w; j++) {
			for (int k = 0; k < h; k++) {
				for (int l = 0; l < w; l++) {
					if (s[i][j] == 'T' || s[k][l] == 'T')
					ans = min(ans, costs[i][j][k][l]);
				}
			}
		}
	}
	if (ans == (1 << 30)) { ans = -1; }
	cout << ans << endl;

	return 1;

}

Measured memory_bytes: 19268