#include<iostream>
#include<queue>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define INF (1<<29)
using namespace std;

struct Node{
	int y,x,foot,cost;
	Node(){}
	Node(int a,int b,int c,int d):y(a),x(b),foot(c),cost(d){}
	bool operator <(const Node &a)const{return cost>a.cost;}
};

int main(){
	int w,h;
	char map[60][30];
	int dp[60][30][2];
	priority_queue<Node> pq;
	Node a,b;
	while(cin>>w>>h&&(w||h)){
		int ans = -1;
		while(!pq.empty())pq.pop();
		fill_n((int*)dp,sizeof(dp)/sizeof(int),INF);
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				cin>>map[i][j];
				if(map[i][j]=='S'){
					pq.push(Node(i,j,0,0));
					pq.push(Node(i,j,1,0));
					dp[i][j][0]=dp[i][j][1]=0;
				}
			}
		}
		while(!pq.empty()){
			int sx,ddx;
			a=pq.top();
			pq.pop();
			if(dp[a.y][a.x][a.foot] < a.cost)continue;
			if(map[a.y][a.x]=='T'){
				ans = a.cost;
				break;
			}
			if(a.foot==0){
				sx=ddx=1;
			}
			else{
				sx=ddx=-1;
			}
			for(int dx=sx;abs(dx)<=3;dx+=ddx){
				for(int dy=-2;dy<=2;dy++){
					if(3<abs(dy)+abs(dx))continue;
					int cost;
					b = Node(a.y+dy,a.x+dx,a.foot^1,a.cost);
					if(b.y<0||h<=b.y||b.x<0||w<=b.x||map[b.y][b.x]=='X')continue;
					if(map[b.y][b.x]=='S'||map[b.y][b.x]=='T')cost = 0;
					else cost = map[b.y][b.x]-'0';
					b.cost += cost;
					if(b.cost < dp[b.y][b.x][b.foot]){
						dp[b.y][b.x][b.foot] = b.cost;
						pq.push(b);
					}
				}
			}
		}
		cout<<ans<<endl;
	}
}