#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll, ll> l_l;
typedef pair<int, int> i_i;

#define EPS (1e-7)
#define PI (acos(-1))
//const ll mod = 1000000007;
const int INF = 1e9;
char field[65][65];
int dp[65][65][65][65];

struct query {
    int lh, lw, rh, rw, dist;
    query(int a, int b, int c, int d, int e) {
        lh = a;
        lw = b;
        rh = c;
        rw = d;
        dist = e;
    }
};

bool operator> (const query &a, const query &b) {
    return a.dist > b.dist;
}

int main() {
    //cout.precision(10);
    cin.tie(0);
    ios::sync_with_stdio(false);
    while(true) {
        int W, H;
        cin >> W >> H;
        if(H == 0) break;
        int ans = INF;
        for(int h = 1; h <= H; h++) {
            for(int w = 1; w <= W; w++) {
                cin >> field[h][w];
            }
        }
        for(int i = 0; i <= 60; i++) {
            for(int j = 0; j <= 60; j++) {
                for(int k = 0; k <= 60; k++) {
                    for(int l = 0; l <= 60; l++) dp[i][j][k][l] = INF;
                }
            }
        }
        priority_queue<query, vector<query>, greater<query>> que;
        for(int w = 1; w <= W; w++) {
            if(field[H][w] == 'S') {
                que.emplace(H, w, H, w, 0);
            }
        }
        while(!que.empty()) {
            query now = que.top();
            que.pop();
            for(int lw = now.rw - 3; lw < now.rw; lw++) {
                if(lw <= 0) continue;
                int delta = 3 - (now.rw - lw);
                for(int lh = now.rh - delta; lh <= now.rh + delta; lh++) {
                    if(lh <= 0 || lh > H) continue;
                    if(field[lh][lw] == 'T') {
                        ans = min(ans, now.dist);
                        continue;
                    }
                    if(field[lh][lw] == 'X' || field[lh][lw] == 'S') continue;
                    int newdist = now.dist + (int)(field[lh][lw] - '0');
                    if(dp[lh][lw][now.rh][now.rw] > newdist) {
                        dp[lh][lw][now.rh][now.rw] = newdist;
                        que.emplace(lh, lw, now.rh, now.rw, newdist);
                        //cerr << "FROM1: " << now.lh << " " << now.lw << " " << now.rh << " " << now.rw << " TO: " << lh << " " << lw << " " << now.rh << " " << now.rw << " " << endl;
                    }
                }
            }
            for(int rw = now.lw + 1; rw <= now.lw + 3; rw++) {
                if(rw > W) continue;
                int delta = 3 - (rw - now.lw);
                for(int rh = now.lh - delta; rh <= now.lh + delta; rh++) {
                    if(rh <= 0 || rh > H) continue;
                    if(field[rh][rw] == 'T') {
                        ans = min(ans, now.dist);
                        continue;
                    }
                    if(field[rh][rw] == 'X' || field[rh][rw] == 'S') continue;
                    int newdist = now.dist + (int)(field[rh][rw] - '0');
                    if(dp[now.lh][now.lw][rh][rw] > newdist) {
                        dp[now.lh][now.lw][rh][rw] = newdist;
                        que.emplace(now.lh, now.lw, rh, rw, newdist);
                        //cerr << "FROM2: " << now.lh << " " << now.lw << " " << now.rh << " " << now.rw << " TO: " << now.lh << " " << now.lw << " " << rh << " " << rw << " " << endl;
                    }
                }
            }
        }
        if(ans == INF) ans = -1;
        cout << ans << endl;
    }
    return 0;
}


Measured memory_bytes: 64664