#include <bits/stdc++.h>
#define PB push_back
#define MP make_pair
#define REP(i,n) for (int i=0;i<(n);i++)
#define FOR(i,a,b) for(int i=(a);i<(b);i++)
#define ALL(a) (a).begin(),(a).end()
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> P;
double EPS=1e-8;
int INF=1e9;
int txr[] = {1,1,1,1,1,2,2,2,3};
int tyr[] = {-2,-1,0,1,2,-1,0,1,0};
int txl[] = {-1,-1,-1,-1,-1,-2,-2,-2,-3};
int tyl[] = {-2,-1,0,1,2,-1,0,1,0};
char stage[60][30];
int cost[1800][1800];
int d[60][30][2];
struct dat{
public:
    int cost;
    int rhs;
    int lhs;
    bool turn;
    dat(){}
    dat(int cost,int lhs,int rhs,bool turn):cost(cost),lhs(lhs),rhs(rhs),turn(turn){
    }

    bool operator>(const dat& d) const{
        return cost > d.cost;
    }
};
int main(){
    int w,h;
    while(scanf("%d %d",&w,&h)&&(w||h)){
	  REP(i,1800)REP(j,1800)cost[i][j]=INF;
        vector<P> S;
        vector<P> T;
        for(int y=0;y<h;y++){
            for(int x=0;x<w;x++){
                scanf("%s",&stage[y][x]);
                if(stage[y][x]=='S') S.push_back(P(x,y));
                if(stage[y][x]=='T') T.push_back(P(x,y));
            }
        }
        priority_queue<dat,vector<dat>,greater<dat> > que;
        for(int i=0;i<S.size();i++){
            int x = S[i].first;
            int y = S[i].second;
            que.push(dat(0,y*w+x,y*w+x,false));
            que.push(dat(0,y*w+x,y*w+x,true));
        }
        int res = INF;
        while(!que.empty()){
            dat d = que.top();
            int srx = d.rhs % w;
            int sry = d.rhs / w;
            int slx = d.lhs % w;
            int sly = d.lhs / w;
            que.pop();
            if(d.cost >= res) continue;
            if(d.turn){
                for(int i=0;i<9;i++){
                    int dx = txl[i] + srx;
                    int dy = tyl[i] + sry;
                    if(dx < 0 || dx >= w || dy < 0 || dy >= h) continue;
                    if(dx>=srx) continue;
                    if(abs(dx - srx) + abs(dy - sry) > 3) continue;
                    if(stage[dy][dx] == 'X') continue;
                    if(stage[dy][dx] == 'T'){
                        res = cost[dy*w+dx][d.rhs] = min(cost[dy*w+dx][d.rhs],d.cost);
                        continue;
                    }
                    if(cost[dy*w+dx][d.rhs] <= d.cost + stage[dy][dx]-'0') continue;
                    cost[dy*w+dx][d.rhs] = d.cost + stage[dy][dx]-'0';
                    que.push(dat(d.cost + stage[dy][dx]-'0',dy*w+dx,d.rhs,false));
                }
            }
            else{
                for(int i=0;i<9;i++){
                    int dx = txr[i] + slx;
                    int dy = tyr[i] + sly;
                    if(dx < 0 || dx >= w || dy < 0 || dy >= h) continue;
                    if(slx>=dx) continue;
                    if(abs(dx - slx) + abs(dy - sly) > 3) continue;
                    if(stage[dy][dx] == 'X') continue;
                    if(stage[dy][dx] == 'T'){
                        res = cost[d.lhs][dy*w+dx] = min(cost[d.lhs][dy*w+dx],d.cost);
                        continue;
                    }
                    if(cost[d.lhs][dy*w+dx] <= d.cost + stage[dy][dx]-'0') continue;
                    cost[d.lhs][dy*w+dx] = d.cost + stage[dy][dx]-'0';
                    que.push(dat(d.cost + stage[dy][dx]-'0',d.lhs,dy*w+dx,true));
                }
            }
        }
        printf("%d\n",res >= INF ? -1 : res);
    }
}

Measured memory_bytes: 13916