#include <vector>
#include <map>
#include <set>
#include <stack>
#include <queue>
#include <algorithm>
#include <utility>
#include <functional>
#include <sstream>
#include <iostream>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <climits>
using namespace std;
inline int toInt(string s) { int v; istringstream sin(s); sin >> v; return v;}
template<class T> inline string toString(T x) { ostringstream sout; sout << x; return sout.str();}
typedef vector<int> vi;
typedef vector<vi>  vvi;
typedef vector<string> vs;
typedef pair<int, int> pii;
typedef long long ll;
#define ALL(a) (a).begin(),(a).end()
#define RALL(a) (a).rbegin(),(a).rend()
#define EACH(t,i,c) for(t::iretator i=(c).begin(); i!=(c).end(); ++i)
#define EXIST(s,e) ((s).find(e)!=(s).end())
#define FOR(i,a,b) for(int i=(a);i<=(b);++i)
#define REP(i,n) FOR(i,0,(n)-1)
const double EPS = 1e-12;
const double PI = acos(-1.0);

const int INF = INT_MAX/2-1;

int dx[] = {1, 1, 2, 1, 2, 3, 1, 2, 1};
int dy[] = {-2, -1, -1, 0, 0, 0, 1, 1, 2};

typedef vector<char> vc;

struct state {
	int x, y, c;
	bool l;
	state(int x, int y, int c, bool l) : x(x), y(y), c(c), l(l) {};
	bool operator<(const state &o)const {
		return c>o.c;
	}
};

int get(char c) {
	switch(c) {
	case 'S':
	case 'T':
		return 0;
	default:
		return c - '0';
	}
}

int main() {
	int w, h;
	while(cin >> w >> h, w) {
		vector<vc> field(h, vc(w));
		REP(i, h) {
			REP(j, w) {
				cin >> field[i][j];
			}
		}

		priority_queue<state> Q;
		vector<vvi> cost(2, vvi(h, vi(w, INF)));		
		REP(i, h) {
			REP(j, w) {
				if(field[i][j] == 'S') {
					Q.push(state(j, i, 0, true));
					Q.push(state(j, i, 0, false));
					cost[0][i][j] = 0;
					cost[1][i][j] = 0;
				}
			}
		}

		while(!Q.empty()) {
			state st = Q.top();
			Q.pop();
			int k = (st.l ? 1 : -1);
			int l = (st.l ? 1 : 0);

			if(field[st.y][st.x] == 'T') {
				continue;
			}

			REP(i, 9) {
				int nx = st.x + dx[i]*k;
				int ny = st.y + dy[i];

				if(0 <= nx && nx < w && 0 <= ny && ny < h && field[ny][nx] != 'X') {
					int nc = st.c + get(field[ny][nx]);
					if(nc < cost[l][ny][nx]) {
						cost[l][ny][nx] = nc;
						Q.push(state(nx, ny, nc, !st.l));
					}
				}
			}
		}

		int ans = INF;
		REP(i, h) {
			REP(j, w) {
				if(field[i][j] == 'T') {
					ans = min(ans, cost[0][i][j]);
					ans = min(ans, cost[1][i][j]);
				}
			}
		}

		if(ans == INF) {
			cout << -1 << endl;
		} else {
			cout << ans << endl;
		}
	}

	return 0;
}