#include <bits/stdc++.h>
template<typename T>
struct Edge {
    int from, to;
    T cost;
    Edge(int from, int to, T cost) {
        this->from = from;
        this->to = to;
        this->cost = cost;
    }
};
bool operator == (Edge<int> e1, Edge<int> e2) {
    return e1.from == e2.from &&
            e1.to == e2.to &&
            e1.cost == e2.cost;
}
template<typename T>
using Edges = std::vector<Edge<T>>;
template<typename T>
using Graph = std::vector<Edges<T>>;
template <typename T>
std::vector<T> dijkstra(const Graph<T> &g, int s) {
    int sz = (int)(g.size());
    std::vector<T> dist(sz, std::numeric_limits<T>::max());
    std::priority_queue<std::pair<T, int>, std::vector<std::pair<T, int>>, std::greater<std::pair<T, int>>> pq;
    dist[s] = 0;
    pq.push({0, s});
    while(!pq.empty()) {
        T d = pq.top().first;
        int now = pq.top().second;
        pq.pop();
        if(d > dist[now]) continue;
        for(int i=0;i<(int)(g[now].size());++i) {
            int next = g[now][i].to;
            T cost = g[now][i].cost;
            if(dist[next] > dist[now] + cost) {
                dist[next] = dist[now] + cost;
                pq.push({cost, next});
            }
        }
    }
    return dist;
}
using namespace std;
using ll = long long;
using P = pair<int, int>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vll = vector<ll>;
using vvll = vector<vector<ll>>;
const double eps = 1e-10;
const int MOD = 1000000007;
const int INF = 1000000000;
const ll LINF = 1ll<<50;
template<typename T>
void printv(const vector<T>& s) {
  for(int i=0;i<(int)(s.size());++i) {
    cout << s[i];
    if(i == (int)(s.size())-1) cout << endl;
    else cout << " ";
  }
}
int dr[9] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};
int dc[9] = {1, 1, 1, 1, 1, 2, 2, 2, 3};
int main() {
  cin.tie(0);
  cout << fixed << setprecision(10);
  while(1) {
    int w, h; cin >> w >> h;
    if(w == 0) break;
    vvi s(h, vi(w, 0));
    vi str, stc, edr, edc;
    for(int i=0;i<h;++i) {
      for(int j=0;j<w;++j) {
        char tmp; cin >> tmp;
        if(tmp == 'S') {
          str.push_back(i);
          stc.push_back(j);
        } else if(tmp == 'T') {
          edr.push_back(i);
          edc.push_back(j);
        } else if(tmp == 'X') {
          s[i][j] = INF;
        } else {
          s[i][j] = static_cast<int>(tmp - '0');
        }
      }
    }
    Graph<int> g(h*w*2);
    for(int i=0;i<h;++i) {
      for(int j=0;j<w;++j) {
        for(int k=0;k<2;++k) {
          for(int l=0;l<9;++l) {
            int nr = i + dr[l], nc = j + (k == 0 ? 1 : -1) * dc[l];
            if(!(0 <= nr && nr < h && 0 <= nc && nc < w) || s[nr][nc] == INF) continue;
            g[2*w*i + 2*j + k].push_back(Edge<int>(2*w*i + 2*j + k, 2*w*nr + 2*nc + 1 - k, s[nr][nc]));
          }
        }
      }
    }
    int ans = INF;
    for(int i=0;i<(int)(str.size());++i) {
      vector<int> dist1 = dijkstra(g, 2*w*str[i] + 2*stc[i]);
      vector<int> dist2 = dijkstra(g, 2*w*str[i] + 2*stc[i] + 1);
      for(int j=0;j<(int)(edr.size());++j) {
        ans = min(ans, dist1[2*w*edr[j] + 2*edc[j]]);
        ans = min(ans, dist2[2*w*edr[j] + 2*edc[j]]);
        ans = min(ans, dist1[2*w*edr[j] + 2*edc[j] + 1]);
        ans = min(ans, dist2[2*w*edr[j] + 2*edc[j] + 1]);
      }
    }
    cout << (ans == INF ? -1 : ans) << endl;
  }
}



Measured memory_bytes: 3888