//http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=1150&lang=jp

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<queue>
#include<algorithm>
#include<cstring>
#include<string>
#include<vector>
#define mp make_pair
#define pb push_back
#define rep(i,n) for(int i = 0;i < n;i++)
#define INF 100000009
#define N 20005
using namespace std;

typedef pair<int,int> PI;//cost to;

int map[65][35];
int w,h;

bool checkin(int i,int j){
    if(i>=0&&j>=0&&i<h&&j<w&&map[i][j]!=INF){
        return true;
    }else{
        return false;
    }
}
int retc(int i,int j){
    if(map[i][j]==-1){
        return 0;
    }else{
        return map[i][j];
    }
}

int make(int foot,int state,int i,int j){
    return foot*w*h*9+state*w*h+i*w+j;
}

int main(){
    int cango[9][2];//where right is from left,yx
    int hoge = 0;
    for(int y = 0;y<=2;y++){
        for(int x = 1;x<=3-abs(y);x++){
            cango[hoge][0]=y;
            cango[hoge++][1]=x;
        }
    }
    for(int y = -2;y<=-1;y++){
        for(int x = 1;x<=3-abs(y);x++){
            cango[hoge][0]=y;
            cango[hoge++][1]=x;
        }
    }
    while(1){
        vector<PI> G[3600*9+5];//0???????¶? 1???????¶? to,cost
        bool flag[3600*9+5];
        bool goal[3600*9+5];
        rep(i,3600*9+5){
            flag[i]=0;
            goal[i]=0;
        }
        cin>>w>>h;
        if(w==0){
            return 0;
        }
        char c;
        rep(i,h){
            rep(j,w){
                cin>>c;
                if(c=='S')        map[i][j]=0;
                else if(c=='T')   map[i][j]=-1;
                else if(c=='X')   map[i][j]=INF;
                else map[i][j]=c-'0';
            }
        }
        rep(i,h){
            rep(j,w){
                if(!checkin(i,j))continue;
                rep(state1,9){
                    int y=i+cango[state1][0],x=j+cango[state1][1];
                    if(!checkin(y,x))continue;
                    if(map[i][j]==-1||map[y][x]==-1){
                        goal[make(0,state1,i,j)]=true;
                        goal[make(1,state1,i,j)]=true;
                    }
                    rep(state2,9){
                        if(state1==state2)
                            continue;
                        int ny=i+cango[state2][0],nx=j+cango[state2][1];
                        if(checkin(ny,nx)){
                            G[make(0,state1,i,j)].pb(mp(make(1,state2,i,j),retc(ny,nx)));
                        }
                        ny=y-cango[state2][0],nx=x-cango[state2][1];
                        if(checkin(ny,nx)){
                            G[make(1,state1,i,j)].pb(mp(make(0,state2,ny,nx),retc(ny,nx)));
                        }
                        
                    }
                }
            }
        }
        //        rep(i,3600*9+5){
        //            if(!G[i].empty()){
        //                rep(j,G[i].size()){
        //                    cout<<"from:"<< " foot:" <<i/(w*h*9) <<" state:"<<i/w/h%9<<" i j:("<< i/w%h<< " "<<i%w<< ")"<<endl;
        //
        //                    cout<<"to  :"<< " foot:" <<G[i][j].first/(w*h*9) <<" state:"<<G[i][j].first/w/h%9<<" i j:("<< G[i][j].first/w%h<< " "<<G[i][j].first%w <<") cost:"<<G[i][j].second<<endl<<endl;
        //                }
        //            }
        //        }
        priority_queue<PI, vector<PI> ,greater<PI> > pq;
        rep(j,w){
            if(map[h-1][j]!=0){continue;}
            rep(st,9){
                int y = h-1+cango[st][0],x = j+cango[st][1];
                if(checkin(y,x)){pq.push(mp(retc(y,x),(make(1,st,h-1,j))));}
                y = h-1-cango[st][0],x = j-cango[st][1];
                if(checkin(y,x)){pq.push(mp(retc(y,x),(make(0,st,y,x))));}
            }
        }
        int ans = -1;
        while(!pq.empty()){
            PI now = pq.top();
            int cost = now.first;
            int from = now.second;
            pq.pop();
            if(flag[from]){
                continue;
            }
            flag[from]=true;
            if(goal[from]){
                ans = cost;
                break;
            }
            rep(i,G[from].size()){
                if(!flag[G[from][i].first])
                    pq.push(mp(G[from][i].second+cost,G[from][i].first));
            }
        }
        cout<<ans<<endl;
    }
    return 0;
    
}

Measured memory_bytes: 4416