#include <bits/stdc++.h>

using namespace std;

inline int toInt(string s) {int v; istringstream sin(s);sin>>v;return v;}
template<class T> inline string toString(T x) {ostringstream sout;sout<<x;return sout.str();}
template<class T> inline T sqr(T x) {return x*x;}

typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;

#define all(a)  (a).begin(),(a).end()
#define rall(a) (a).rbegin(), (a).rend()
#define pb push_back
#define mp make_pair
#define each(i,c) for(typeof((c).begin()) i=(c).begin(); i!=(c).end(); ++i)
#define exist(s,e) ((s).find(e)!=(s).end())
#define range(i,a,b) for(int i=(a);i<(b);++i)
#define rep(i,n)  range(i,0,n)
#define clr(a,b) memset((a), (b) ,sizeof(a))
#define dump(x)  cerr << #x << " = " << (x) << endl;
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl;

const double eps = 1e-10;
const double pi  = acos(-1.0);
const ll INF =1LL << 62;
const int inf =1 << 29;

//((コスト, 次動かす足), (left(y, x), right(y, x)))
typedef pair<pii, pair<pii, pii>> State;
#define F first
#define S second

enum {kLeft = 0, kRight};

const vi dx = { 1, 1, 1, 1, 1, 2, 2, 2, 3};
const vi dy = {-2,-1, 0, 1, 2,-1, 0, 1, 0};

int main(void){
    for(int w, h; cin >> w >> h, w;){
        vector<vector<char>> field(h, vector<char>(w));

        priority_queue<State, vector<State>, greater<State>> q;

        rep(y, h){
            rep(x, w){
                cin >> field[y][x];

                if(field[y][x] == 'S'){
                    q.push(mp(mp(0, kLeft),  mp(mp(y, x), mp(y, x))));
                    q.push(mp(mp(0, kRight), mp(mp(y, x), mp(y, x))));

                    field[y][x] = '0';
                }
            }
        }

        map<pair<int, pair<pii, pii>>, int> min_dist;
        int res = -1;
        while(!q.empty()){
            int cur_cost = q.top().F.F;
            int cur_foot = q.top().F.S;
            pair<pii, pii> cur_pos = q.top().S;
            q.pop();

            if(min_dist.find(mp(cur_foot, cur_pos)) != min_dist.end()) continue;
            
            min_dist[mp(cur_foot, cur_pos)] = cur_cost;

            if(field[cur_pos.F.F][cur_pos.F.S] == 'T' || 
               field[cur_pos.S.F][cur_pos.S.S] == 'T'){
                res = cur_cost;
                break;
            }

            int next_foot = cur_foot == kLeft ? kRight:kLeft;
            rep(i, dx.size()){
                pair<pii, pii> next_pos = cur_pos;

                if(cur_foot == kLeft){
                    next_pos.F.F = cur_pos.S.F + dy[i];
                    next_pos.F.S = cur_pos.S.S - dx[i];
                }
                else{
                    next_pos.S.F = cur_pos.F.F + dy[i];
                    next_pos.S.S = cur_pos.F.S + dx[i];
                }

                if(next_pos.F.F < 0 || h <= next_pos.F.F ||
                   next_pos.F.S < 0 || w <= next_pos.F.S ||
                   next_pos.S.F < 0 || h <= next_pos.S.F ||
                   next_pos.S.S < 0 || w <= next_pos.S.S)
                    continue;

                if(min_dist.find(mp(next_foot, next_pos)) != min_dist.end()) continue;

                int next_cost = cur_cost;
                char c = cur_foot == kLeft ? field[next_pos.F.F][next_pos.F.S]:field[next_pos.S.F][next_pos.S.S];
                if(c == 'X') continue;
                if(c != 'T') next_cost += c - '0';

                q.push(mp(mp(next_cost, next_foot), next_pos));
            }
        }

        cout << res << endl;
    }

	return 0;
}

Measured memory_bytes: 2928