/*
    はあ辛い
 */

#include <cstdio>
#include <cassert>
#include <queue>
#include <utility>
using namespace std;

#define LEFT 0
#define RIGHT 1
#define INF 0x3fffffff

typedef pair<int, int> Coor;
typedef pair<int, Coor> Data;
typedef pair<int, Data> Pair;

int w;
int h;
int ans;
bool is_goal[60][30];
int cost[60][30];
int lmin[60][30];
int rmin[60][30];

int main() {
    while (1) {
        priority_queue<Pair, vector<Pair>, greater<Pair> > q;

        scanf("%d%d", &w, &h);
        if (w == 0 && h == 0) return 0;

        ans = INF;
        for (int i=0; i<h; i++) {
            for (int j=0; j<w; j++) {
                lmin[i][j] = INF;
                rmin[i][j] = INF;
            }
        }

        for (int i=0; i<h; i++) {
            for (int j=0; j<w; j++) {
                char c;

                is_goal[i][j] = false;
                scanf(" %c", &c);
                if (c == 'X') {
                    cost[i][j] = INF;
                } else if (c == 'S') {
                    cost[i][j] = 0;
                    lmin[i][j] = 0;
                    rmin[i][j] = 0;
                    q.push(Pair(0, Data(LEFT, Coor(j, i))));
                    q.push(Pair(0, Data(RIGHT, Coor(j, i))));
                } else if (c == 'T') {
                    cost[i][j] = 0;
                    is_goal[i][j] = true;
                } else {
                    cost[i][j] = c - '0';
                    assert(1 <= cost[i][j] && cost[i][j] <= 9);
                }
            }
        }

        while (!q.empty()) {
            Pair p = q.top(); q.pop();
            int dist = p.first;
            Data d = p.second;
            int last = d.first;
            Coor c = d.second;
            int x = c.first;
            int y = c.second;

            if (last ==  LEFT && dist > lmin[y][x]) continue;
            if (last == RIGHT && dist > rmin[y][x]) continue;

            if (last == LEFT) {
                for (int i=2; i>=0; i--) {
                    for (int j=-i; j<=i; j++) {
                        int _x = x + 3-i;
                        int _y = y + j;

                        if (_x < 0 || w <= _x) continue;
                        if (_y < 0 || h <= _y) continue;
                        if (cost[_y][_x] == INF) continue;

                        if (rmin[_y][_x] > dist + cost[_y][_x]) {
                            rmin[_y][_x] = dist + cost[_y][_x];
                            if (is_goal[_y][_x]) {
                                ans = min(ans, rmin[_y][_x]);
                                continue;
                            }
                            q.push(Pair(rmin[_y][_x], Data(RIGHT, Coor(_x, _y))));
                        }
                    }
                }
            } else {
                for (int i=2; i>=0; i--) {
                    for (int j=-i; j<=i; j++) {
                        int _x = x - (3-i);
                        int _y = y + j;

                        if (_x < 0 || w <= _x) continue;
                        if (_y < 0 || h <= _y) continue;
                        if (cost[_y][_x] == INF) continue;

                        if (lmin[_y][_x] > dist + cost[_y][_x]) {
                            lmin[_y][_x] = dist + cost[_y][_x];
                            if (is_goal[_y][_x]) {
                                ans = min(ans, lmin[_y][_x]);
                                continue;
                            }
                            q.push(Pair(lmin[_y][_x], Data(LEFT, Coor(_x, _y))));
                        }
                    }
                }
            }
        }

        if (ans < INF) {
            printf("%d\n", ans);
        } else {
            puts("-1");
        }
    }
}

Measured memory_bytes: 1084