#include <algorithm>
#include <cmath>
#include <climits>
#include <cstdio>
#include <cstring>
#include <fstream>
#include <iostream>
#include <list>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <vector>
#include <functional>

using namespace std;

#define LOG(...) printf(__VA_ARGS__)
//#define LOG(...)
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) for(int i=0;i<(int)(n);++i)
#define ALL(a) (a).begin(),(a).end()
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define SORT(c) sort((c).begin(),(c).end())

typedef long long ll;
typedef unsigned long long ull;
typedef vector<bool> vb;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<vb> vvb;
typedef vector<vi> vvi;
typedef vector<vll> vvll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;

#define INF INT_MAX
#define MAX_W 30
#define MAX_H 60
char field[MAX_H][MAX_W];

struct P
{
    int x,y,cost,w;
    bool operator >(const P &p) const{
        return cost>p.cost;
    }
};

int dx[]={
    1,1,1,1,1,2,2,2,3
};
int dy[]={
    -2,-1,0,1,2,-1,0,1,0
};

int main() {
    int w, h;
    while(cin >> w >> h, w|h){
        fill_n((char *)field, MAX_W*MAX_H, 'X');

        priority_queue<P, vector<P>, greater<P> >que;

        REP(y,h)REP(x,w){
            cin >> field[y][x];
            if(field[y][x]=='S'){
                que.push({x, y, 0, 1});
                que.push({x, y, 0,-1});
            }
        }

        vvi GL(h, vi(w, INF));
        vvi GR(h, vi(w, INF));

        int res=-1;
        while(!que.empty()){
            P p=que.top(); que.pop();

            if(field[p.y][p.x]=='T'){
                res=p.cost;
                break;
            }

            REP(i, 9){
                int sx=p.x+dx[i]*p.w;
                int sy=p.y+dy[i];
                if(0<=sx&&sx<w&&0<=sy&&sy<h){
                    int cost=p.cost;
                    switch(field[sy][sx]){
                    case 'T':
                    case 'S':
                        break;
                    case 'X':
                        continue;
                    default:
                        cost+=field[sy][sx]-'0';
                        break;
                    }
                    bool t=true;
                    if(p.w>0&&GL[sy][sx]>cost){
                        GL[sy][sx]=cost;
                        t=false;
                    }else if(p.w<0&&GR[sy][sx]>cost){
                        GR[sy][sx]=cost;
                        t=false;
                    }
                    if(t)continue;
                    que.push({sx, sy, cost, -p.w});
                }
            }
        }

        cout << res << endl;
    }
}
 