#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <string>
#include <vector>
#include <list>
#include <set>
#include <map>
#include <queue>

using namespace std;
#define DEBUG(x) cout<<#x<<": "<<x<<endl

#define PB push_back
#define MP make_pair
#define F first
#define S second
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n)  FOR(i,0,n)
#define INT(a) int((a)+1e-9)
int DX[9]={1,1,1,1,1,2,2,2,3};
int DY[9]={-2,-1,0,1,2,-1,0,1,0};

typedef pair<int,int> Pii;
typedef pair<Pii,Pii> G;  //.F.F=cost, .F.S=0:hidari;1:migi, .S.F=y, .S.S=x

#define INF 100000
#define SUPxl 30
#define SUPyl 60

int xl,yl;
char tizu[SUPyl][SUPxl];
int isVisiteds[2][SUPyl][SUPxl];
priority_queue< G, vector<G>, greater<G> > que;

int isIkisugi(int y, int x){
	return (y<0 || yl<=y || x<0 || xl<=x);
}

int dijkstra(){
	while(!que.empty()){
		G g = que.top(); que.pop();
		int cost=g.F.F, turn=g.F.S, y=g.S.F, x=g.S.S;
		//DEBUG(cost); DEBUG(turn); DEBUG(y); DEBUG(x);
		if(tizu[y][x]=='T') return cost;
		if(isVisiteds[turn][y][x]) continue;
		isVisiteds[turn][y][x]=true;
		FOR(di,0,9){
			int ny = y + DY[di];
			int nx = x + (turn ? -DX[di] : DX[di]);
			if(isIkisugi(ny,nx)||tizu[ny][nx]=='X') continue;
			que.push( MP(MP( cost+((tizu[ny][nx]=='T')?0:(tizu[ny][nx]-'0')) , 1-turn ),MP( ny , nx )) );
		}
	}
	return -1;
}




int main(){
	while(true){
		cin >> xl >> yl;			if(!xl) return 0;
		que = priority_queue< G, vector<G>, greater<G> >();
		FOR(yi,0,yl) FOR(xi,0,xl){ isVisiteds[0][yi][xi]=false; isVisiteds[1][yi][xi]=false;}
		FOR(yi,0,yl) FOR(xi,0,xl){
			cin>>tizu[yi][xi];
			if(tizu[yi][xi]=='S'){
				que.push(MP(MP(0,0),MP(yi,xi)));
				que.push(MP(MP(0,1),MP(yi,xi)));
			}
		}
		cout<<dijkstra()<<endl;
	}
}