#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i=0; i<(n); ++i)
#define RREP(i, n) for (int i=(int)(n)-1; i>=0; --i)
#define FOR(i, a, n) for (int i=(a); i<(n); ++i)
#define RFOR(i, a, n) for (int i=(int)(n)-1; i>=(a); --i)

#define SZ(x) ((int)(x).size())
#define all(x) begin(x),end(x)

#define dump(x) cerr<<#x<<" = "<<(x)<<endl
#define debug(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<< endl;

template<class T>
ostream &operator<<(ostream &os, const vector <T> &v) {
    os << "[";
    REP (i, SZ(v)) {
        if (i) os << ", ";
        os << v[i];
    }
    return os << "]";
}

template<class T, class U>
ostream &operator<<(ostream &os, const pair <T, U> &p) {
    return os << "(" << p.first << " " << p.second << ")";
}

template<class T>
bool chmax(T &a, const T &b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

template<class T>
bool chmin(T &a, const T &b) {
    if (b < a) {
        a = b;
        return true;
    }
    return false;
}

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector <vector<int>>;
using vvll = vector <vector<ll>>;

#define inf(T) (numeric_limits<T>::max() / 2)
const ll MOD = 1e9 + 7;
const ld EPS = 1e-9;

template<class T>
struct edge {
    int src, to;
    T cost;

    edge() {}
    edge(int to, T cost) : src(-1), to(to), cost(cost) {}
    edge(int src, int to, T cost) : src(src), to(to), cost(cost) {}

    friend ostream& operator<<(ostream& os, const edge& e) {
        return os << "(" << e.src << "->" << e.to << ":" << e.cost << ")";
    }
};

template<class T>
vector<T> dijkstra(const vector<vector<edge<T>>>& g, int s) {
    const T INF = inf(T);
    vector<T> d(g.size(), INF);

    using Pi = pair<T, int>;
    priority_queue<Pi, vector<Pi>, greater<Pi>> que;
    d[s] = 0;
    que.emplace(d[s], s);
    while (!que.empty()) {
        T cost; int v;
        tie(cost, v) = que.top();
        que.pop();
        if (d[v] < cost) continue;
        for (const auto &e : g[v]) {
            T nxt = cost + e.cost;
            if (d[e.to] > nxt) {
                d[e.to] = nxt;
                que.emplace(nxt, e.to);
            }
        }
    }
    return d;
}


int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);
    cout << fixed << setprecision(10);

    for (;;) {
        int w, h; cin >> w >> h;
        if (w == 0) break;

        vector<vector<char>> s(h, vector<char>(w));
        REP(i, h) REP(j, w) {
            cin >> s[i][j];
        }

        vector<vector<edge<int>>> G(h*w*2 + 1);
        REP(i, h) REP(j, w) {
            for (int di = -3; di <= 3; ++di) {
                for (int dj = -3; dj < 0; ++dj) {
                    if (abs(di) + abs(dj) > 3) continue;
                    int y = i + di, x = j + dj;
                    if (y < 0 or x < 0 or h <= y or w <= x) continue;
                    if (s[y][x] == 'X' or s[y][x] == 'S') continue;
                    int cost = s[y][x] == 'T' ? 0 : s[y][x] - '0';
                    G[i*w + j].emplace_back(h*w + y*w + x, cost);
                }
            }
            for (int di = -3; di <= 3; ++di) {
                for (int dj = 1; dj <= 3; ++dj) {
                    if (abs(di) + abs(dj) > 3) continue;
                    int y = i + di, x = j + dj;
                    if (y < 0 or x < 0 or h <= y or w <= x) continue;
                    if (s[y][x] == 'X' or s[y][x] == 'S') continue;
                    int cost = s[y][x] == 'T' ? 0 : s[y][x] - '0';
                    G[h*w + i*w + j].emplace_back(y*w + x, cost);
                }
            }
        }

        REP(i, h) REP(j, w) {
            if (s[i][j] == 'S') {
                G[2*h*w].emplace_back(i*w + j, 0);
                G[2*h*w].emplace_back(h*w + i*w + j, 0);
            }
        }

        auto dist = dijkstra(G, 2*h*w);

        int ans = inf(int);
        REP(i, h) REP(j, w) {
            if (s[i][j] != 'T') continue;
            chmin(ans, dist[i*w + j]);
            chmin(ans, dist[h*w + i*w + j]);
        }

        if (ans == inf(int)) ans = -1;
        cout << ans << endl;
    }

    return 0;
}



Measured memory_bytes: 3660