#include<bits/stdc++.h>
using namespace std;
#define INF 1e9
#include<bits/stdc++.h>
using namespace std;


//経路もわかるダイクストラ法

//pq<pair> はfirstが大きい順に出てくるのですか？
// s:= 開始ノード  v:= 頂点数  adjlist:= 隣接リスト (first:= コスト   second:= 行先)
vector<pair<int, int> > dijk(int s, int v, vector<vector<pair<int, int> > > adjlist){
    
    priority_queue <pair<int, int> > wait;
    vector<pair<int, int > > result(v);          //first  コスト　　second　どこから来たか
    for(int i = 0; i < v; i++){
        result[i].first = INF;
    }

    //スタート地点を追加
    result[s].first = 0;
    //result[s].second.push_back(s);
    wait.push(make_pair(0, s));

    //ダイクストラ本体
    while(!wait.empty()){    //waitが空になるまで

        int nowpoint = wait.top().second;
        int nowcost = -wait.top().first;
        wait.pop();

        if(result[nowpoint].first < nowcost) continue;


        //今いる頂点と隣接しているすべての頂点をなめる
        for(int i = 0; i < adjlist[nowpoint].size(); i++){

            int nextpoint = adjlist[nowpoint][i].second;
            int nextcost = nowcost + adjlist[nowpoint][i].first;

            //現時点より安く到達できそうであれば、結果を更新して優先度付きキューに格納
            if(result[nextpoint].first > nextcost){
                
                result[nextpoint].first = nextcost;
                result[nextpoint].second = nowpoint;
                wait.push(make_pair(-nextcost, nextpoint));
            }
        }
    }
    
    return result;         //結果列を返す
}

int main(){

    while(1){
        int h, w; cin >> w >> h;
        if(!h) break;
        
        map<pair<int, pair<int, int> >, int>  m;
        vector<vector<char> > a(h, vector<char> (w));
        int node = 1;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                cin >> a[i][j];
                if(a[i][j] != 'S' && a[i][j] != 'T' && a[i][j] != 'X'){
                    m[{0, {i, j}}] = node;
                    m[{1, {i, j}}] = node + 1;                    
                    node += 2;
                } 
            }
        }

        /*for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                if(m.find({0, {i, j}}) != m.end()){
                    cout << i << " " << j << " " << m[{0, {i, j}}] << " " << m[{1, {i, j}}] << " " << endl;
                }
            }
        }*/

        /*for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                cout << a[i][j] << " ";
            }
            cout << endl;
        }*/

        //cout << node << endl;
        
        vector<vector<pair<int, int> > > adjlist(node + 1);      //first := コスト　second := 行先
        //cout << h << " " << w << endl;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                //int n;
                //cout << i << " " << j << " " << a[i][j] << endl;
                if(a[i][j] == 'S'){

                    //cout << i << " " << j << endl;
                    //右に行こう
                    for(int k = 1; k <= 3; k++){
                        for(int l = -(3 - k); l <= 3 - k; l++){
                            int nj = j + k;
                            int ni = i + l;
                            if(0 <= ni && ni < h && 0 <= nj && nj < w){
                                int cost;
                                if(a[ni][nj] == 'S' || a[ni][nj] == 'X') continue;
                                else if(a[ni][nj] == 'T'){
                                    //cout << "ok" << endl;
                                    adjlist[0].push_back({0, node});
                                    continue;
                                }else cost = (int)(a[ni][nj] - '0');

                                int n1 = m[{0, {ni, nj}}];
                                

                                adjlist[0].push_back({cost, n1});
                                //adjlist[0].push_back({cost, n2});                                
                            }
                        }
                    }   

                    //左に行こう
                    for(int k = 1; k <= 3; k++){
                        for(int l = -(3 - k); l <= 3 - k; l++){
                            int nj = j - k;
                            int ni = i + l;
                            if(0 <= ni && ni < h && 0 <= nj && nj < w){
                                int cost;
                                if(a[ni][nj] == 'S' || a[ni][nj] == 'X') continue;
                                else if(a[ni][nj] == 'T'){
                                    adjlist[0].push_back({0, node});
                                    continue;                                       
                                }else cost = (int)(a[ni][nj] - '0');

                                //int n1 = m[{0, {ni, nj}}];
                                int n2 = m[{1, {ni, nj}}];

                                //adjlist[0].push_back({cost, n1});
                                adjlist[0].push_back({cost, n2});                                
                            }
                        }
                    }   

                }else if(a[i][j] != 'T' && a[i][j] != 'X'){
                    
                    int n = m[{1, {i, j}}];
                    //右に行く
                    for(int k = 1; k <= 3; k++){
                        for(int l = -(3 - k); l <= 3 - k; l++){
                            int nj = j + k;
                            int ni = i + l;
                            if(0 <= ni && ni < h && 0 <= nj && nj < w){
                                int cost;
                                if(a[ni][nj] == 'S' || a[ni][nj] == 'X') continue;
                                else if(a[ni][nj] == 'T'){
                                    adjlist[n].push_back({0, node});
                                    continue;
                                }else cost = (int)(a[ni][nj] - '0');

                                int nn = m[{0, {ni, nj}}];

                                adjlist[n].push_back({cost, nn});
                                                                
                            }
                        }
                    }

                    n = m[{0, {i, j}}];

                    //左に行こう
                    for(int k = 1; k <= 3; k++){
                        for(int l = -(3 - k); l <= 3 - k; l++){
                            int nj = j - k;
                            int ni = i + l;
                            if(0 <= ni && ni < h && 0 <= nj && nj < w){
                                int cost;
                                if(a[ni][nj] == 'S' || a[ni][nj] == 'X') continue;
                                else if(a[ni][nj] == 'T'){
                                    adjlist[n].push_back({0, node});
                                    continue;                                    
                                }else cost = (int)(a[ni][nj] - '0');

                                int nn = m[{1, {ni, nj}}];
                                adjlist[n].push_back({cost, nn});                                
                            }
                        }
                    }   
                }

                //cout << "ok" << " " << i << " " << j << " " << h << " " << w << endl;
            }
        }

        /*for(int i = 0; i < adjlist.size(); i++){
            cout << i << ": ";
            for(int j = 0; j < adjlist[i].size(); j++){
                cout << adjlist[i][j].second << " ";
            }
            cout << endl;
        }*/
        //cout << node << endl;
        vector<pair<int, int> > result(node + 1);
        result = dijk(0, node + 1, adjlist);
        /*for(int i = 0; i < node + 1; i++){
            cout << i << ": " << result[i].first << "  " << result[i].second << endl;
        }*/

        if(result[node].first == INF) cout << -1 << endl;
        else cout << result[node].first << endl;


    }

    return 0;
}



Measured memory_bytes: 4080