#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
const int INF = 1000000000;
#define REP(i,s,n) for(int i=(int)(s);i<(int)(n);i++)
#define rep(i,n) REP(i, 0, n)
struct Node{
    int x, y, cost, pos;
    bool nxt;//?¬????????¶???????true, ????¶???????false
    Node(int x, int y, int c, int p, bool n)
         : x(x), y(y), cost(c), pos(p), nxt(n){}
    bool operator> (const Node& N) const{
        return cost > N.cost;
    }
};
int W, H;
char fld[61][31];
int dist[61][31][9][2];//????¶????????????¨?????????????????????????¶????????????¨?¬??????????????¶?
const int dx[9] = {1, 1, 2, 1, 2, 3, 1, 2, 1}, dy[9] = {-2, -1, -1, 0, 0, 0, 1, 1, 2};
const int dx2[9] = {-1, -1, -2, -1, -2, -3, -1, -2, -1}, dy2[9] = {2, 1, 1, 0, 0, 0, -1, -1, -2};
bool cant_go(int cx, int cy){
    return cx < 0 || cy < 0 || W <= cx || H <= cy || fld[cy][cx] == 'X';
}
typedef pair<int, int> pint;
int solve(){
    rep(i, 61) rep(j, 31) rep(k, 9) rep(l, 2) dist[i][j][k][l] = INF;
    priority_queue<Node, vector<Node>, greater<Node>> que;
    vector<int> goal;
    rep(i, W) if(fld[0][i] == 'T'){
        goal.push_back(i);
        fld[0][i] = '0';
    }
    rep(i, W) if(fld[H - 1][i] == 'S'){
        if(i != 0){//????¶??????????
            que.push(Node(i - 1, H, 0, 1, false));
            dist[H][i - 1][1][0] = 0;
        }
        if(i != W - 1){//????¶??????????
            que.push(Node(i, H - 1, 0, 6, true));
            dist[H - 1][i][6][1] = 0;
        }
        fld[H - 1][i] = '0';
    }
    while(!que.empty()){
        Node cr = que.top(); que.pop();
        if(dist[cr.y][cr.x][cr.pos][cr.nxt] < cr.cost) continue;
        if(cr.nxt){
            rep(i, 9){
                if(i == cr.pos) continue;
                int rx = cr.x + dx[i], ry = cr.y + dy[i];
                if(cant_go(rx, ry)) continue;
                int ncos = fld[ry][rx] - '0';
                if(dist[cr.y][cr.x][i][0] > dist[cr.y][cr.x][cr.pos][1] + ncos){
                    dist[cr.y][cr.x][i][0] = dist[cr.y][cr.x][cr.pos][1] + ncos;
                    que.push(Node(cr.x, cr.y, dist[cr.y][cr.x][i][0], i, false));
                }
            }
        }else{
            int rx = cr.x + dx[cr.pos], ry = cr.y + dy[cr.pos];
            rep(i, 9){
                if(i == cr.pos) continue;
                int lx = rx + dx2[i], ly = ry + dy2[i];
                if(cant_go(lx, ly)) continue;
                int ncos = fld[ly][lx] - '0';
                if(dist[ly][lx][i][1] > dist[cr.y][cr.x][cr.pos][0] + ncos){
                    dist[ly][lx][i][1] = dist[cr.y][cr.x][cr.pos][0] + ncos;
                    que.push(Node(lx, ly, dist[ly][lx][i][1], i, true));
                }
            }
        }
    }
    int ans = INF;
    for(int k : goal){
        rep(i, 9) rep(j, 2) ans = min(ans, dist[0][k][i][j]);
        rep(i, 9){
            int gx = k + dx2[i], gy = 0 + dy2[i];
            if(cant_go(gx, gy)) continue;
            rep(j, 2) ans = min(ans, dist[gy][gx][i][j]);
        }
    }
    return ans == INF ? -1 : ans;
}
int main(){
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(cin >> W >> H && W){
        rep(i, H) rep(j, W) cin >> fld[i][j];
        cout << solve() << endl;
    }
    return 0;
}

Measured memory_bytes: 3280