#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <string>
#include <functional>
#include <algorithm>
#include <cctype>
using namespace std;

typedef long long ll;
struct State {
    int x, y, foot, cost;
    State(int x, int y, int foot, int cost) : x(x), y(y), foot(foot), cost(cost){}
};

bool operator<(const State &lhs, const State &rhs) {
    return lhs.cost > rhs.cost;
}

const int MAX = (1 << 21);
const int dx[2][9] = {
    {-3, -2, -2, -2, -1, -1, -1, -1, -1},
    {3, 2, 2, 2, 1, 1, 1, 1, 1}
};
const int dy[2][9] = {
    {0, -1, 0, 1, -2, -1, 0, 1, 2},
    {0, -1, 0, 1, -2, -1, 0, 1, 2}
};

char field[80][80];
bool visited[80][80][2];

int main()
{
    int w, h;
    while(cin >> w >> h && w && h) {
        
        priority_queue<State, vector<State>, less<State> > que;
        for(int i = 0; i < 80; i++) {
            for(int j = 0; j < 80; j++) {
                field[i][j] = 'X';
                visited[i][j][0] = visited[i][j][1] = false;
            }
        }
        
        for(int i = 0; i < h; i++) {
            for(int j = 0; j < w; j++) {
                cin >> field[i + 5][j + 5];
                if(field[i + 5][j + 5] == 'S') {
                    que.push(State(j + 5, i + 5, 0, 0));
                    que.push(State(j + 5, i + 5, 1, 0));
                    field[i + 5][j + 5] = '0';
                }
            }
        }

        int ret = MAX;
        while(!que.empty()) {
            State cur = que.top(); que.pop();
            if(field[cur.y][cur.x] == 'T') {
                ret =  cur.cost;
                break;
            }
            visited[cur.y][cur.x][cur.foot] = true;

            //cout << cur.x << " " << cur.y << " " << cur.foot << " " << cur.cost << endl;
            for(int i = 0; i < 9; i++) {
                int nx, ny, nfoot, ncost;
                nfoot = (cur.foot + 1) %2;
                nx = cur.x + dx[nfoot][i]; ny = cur.y + dy[nfoot][i];
                if(field[ny][nx] == 'X' || visited[ny][nx][nfoot]) {
                    continue;
                }
                ncost = cur.cost + ((field[ny][nx] == 'T') ? 0 : (field[ny][nx] - '0'));
                que.push(State(nx, ny, nfoot, ncost));
            }
        }
        cout << ((ret == MAX) ? -1 : ret) << endl;
    }
}