#include <bits/stdc++.h>
using namespace std;

#define rep(i,x,y) for(int i=(x);i<(y);++i)
#define debug(x) #x << "=" << (x)

#ifdef DEBUG
#define _GLIBCXX_DEBUG
#define dump(x) std::cerr << debug(x) << " (L:" << __LINE__ << ")" << std::endl
#else
#define dump(x)
#endif

typedef long long int ll;
typedef pair<int,int> pii;
//template<typename T> using vec=std::vector<T>;

const int inf=1<<30;
const long long int infll=1LL<<58;
const double eps=1e-9;
const int dx[]={1,0,-1,0},dy[]={0,1,0,-1};

template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec){
	os << "[";
	for (const auto &v : vec) {
		os << v << ",";
	}
	os << "]";
	return os;
}

int dist[1800][1800][2],s[100][100],w,h;

int encode(int x,int y){
    return x+w*y;
}

pii decode(int pos){
    return make_pair(pos%w,pos/w);
}

bool verify(int lp,int rp){
    int lx=decode(lp).first,ly=decode(lp).second;
    int rx=decode(rp).first,ry=decode(rp).second;
    return lx<rx and abs(lx-rx)+abs(ly-ry)<=3 and s[lx][ly]!=inf and s[rx][ry]!=inf;
}

void solve(){
    typedef tuple<int,int,int> state;
    while(true){
        cin >> w >> h;
        if(w==0 and h==0) break;
        vector<int> start_points,end_points;
        rep(y,0,h) rep(x,0,w) s[x][y]=0;
        rep(y,0,h) rep(x,0,w){
            char tmp;
            cin >> tmp;
            if(tmp=='S') start_points.push_back(encode(x,y));
            else if(tmp=='T') end_points.push_back(encode(x,y));
            else if(tmp=='X') s[x][y]=inf;
            else s[x][y]=tmp-'0';
        }

        rep(i,0,w*h) rep(j,0,w*h) rep(k,0,2) dist[i][j][k]=inf;
        priority_queue<pair<int,state>,vector<pair<int,state>>,greater<pair<int,state>>> que;
        for(int sp:start_points) rep(i,0,w*h){
            auto push=[&](int lp,int rp,int c){
                if(!verify(lp,rp)) return;
                dist[lp][rp][c]=s[decode(i).first][decode(i).second];
                que.push(make_pair(dist[lp][rp][c],make_tuple(lp,rp,c)));
            };
            push(sp,i,0);
            push(i,sp,1);
        }

        while(!que.empty()){
            int d=que.top().first;
            state st=que.top().second;
            que.pop();
            int lp=get<0>(st),rp=get<1>(st),c=get<2>(st);
            if(d>dist[lp][rp][c]) continue;

            int lx=decode(lp).first,ly=decode(lp).second;
            int rx=decode(rp).first,ry=decode(rp).second;
            rep(dx,-5,5) rep(dy,-5,5){
                auto renew=[&](int nlp,int nrp,int nc,int cost){
                    if(verify(nlp,nrp) and d+cost<dist[nlp][nrp][nc]){
                        dist[nlp][nrp][nc]=d+cost;
                        que.push(make_pair(dist[nlp][nrp][nc],make_tuple(nlp,nrp,nc)));
                    }
                };
                if(c==0){
                    if(0<=lx+dx and lx+dx<w and 0<=ly+dy and ly+dy<h) renew(encode(lx+dx,ly+dy),rp,1-c,s[lx+dx][ly+dy]);
                }else{
                    if(0<=rx+dx and rx+dx<w and 0<=ry+dy and ry+dy<h) renew(lp,encode(rx+dx,ry+dy),1-c,s[rx+dx][ry+dy]);
                }
            }
        }

        int ans=inf;
        rep(i,0,w*h) rep(j,0,2){
            for(int ep:end_points){
                ans=min(ans,dist[ep][i][j]);
                ans=min(ans,dist[i][ep][j]);
            }
        }
        if(ans==inf) cout << -1 << endl;
        else cout << ans << endl;
    }
}

int main(){
	std::ios::sync_with_stdio(false);
	std::cin.tie(0);
	solve();
	return 0;
}

Measured memory_bytes: 28516