// ACM-ICPCà\I2007 D. Roè

#include <iostream>
#include <queue>
#include <cstring>

using namespace std;

const int INF = 999999;

class Node{
public:
	int x, y, foot, cost;
	Node(int x, int y, int foot, int cost) : x(x), y(y), foot(foot), cost(cost) {}
	bool operator < (const Node &n) const { return cost > n.cost; }
};

int main(){
	int w, h;
	char b[60][30];
	bool visit[2][60][30];
	int dist[2][60][30];
	while(cin >> w >> h, w){
		int ans = INF;
		priority_queue<Node> qu;
		memset(visit, false, sizeof(visit));
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				cin >> b[i][j];
				if(b[i][j] == 'S'){
					qu.push(Node(j,i,0,0));
					qu.push(Node(j,i,1,0));
					dist[0][i][j] = dist[1][i][j] = 0;
				} else {
					dist[0][i][j] = dist[1][i][j] = INF;
				}
			}
		}
		while(!qu.empty()){
			Node e = qu.top(); qu.pop();
			if(visit[e.foot][e.y][e.x]) continue;
			if(b[e.y][e.x]=='T'){
				ans = e.cost;
				break;
			}
			visit[e.foot][e.y][e.x] = true;
			for(int dx=1;dx<=3;dx++){
				for(int dy=dx-3;dy<=3-dx;dy++){
					int x = e.x + (e.foot ? -dx : dx);
					int y = e.y + dy;
					if(x<0||w<=x||y<0||h<=y||visit[1-e.foot][y][x]) continue;
					if(b[y][x]=='X'||b[y][x]=='S') continue;
					if(dist[1-e.foot][y][x] > e.cost + (b[y][x]!='T'?b[y][x]-'0':0)){
						dist[1-e.foot][y][x] = e.cost + (b[y][x]!='T'?b[y][x]-'0':0);
						qu.push(Node(x, y, 1-e.foot, dist[1-e.foot][y][x]));
					}   
				}   
			}
		}
		cout << (ans == INF ? -1 : ans) << endl;  
	}
}