// tsukasa_diary's programing contest code template
#include <bits/stdc++.h>
using namespace std;
// define
#define for_(i,a,b) for(int i=a;i<b;++i)
#define for_rev(i,a,b) for(int i=a;i>=b;--i)
#define allof(a) a.begin(),a.end()
#define minit(a,b) memset(a,b,sizeof(a))
#define size_of(a) (int)a.size()
// typedef
typedef long long lint;
typedef double Double;
typedef pair<int, int> pii;
//
typedef vector< int > Array;
typedef vector< Array > Matrix;
typedef vector< Double > DArray;
typedef vector< DArray > DMatrix;
typedef vector< string > SArray;
typedef vector< pii > PArray;
// popcount
inline int POPCNT(int _x) { return __builtin_popcount(_x); }
inline int POPCNT(lint _x) { return __builtin_popcountll(_x); }
// inf
const int iINF = 1L << 30;
const lint lINF = 1LL << 60;
// eps
Double EPS = 1e-9;
// in range
inline bool in_range(int _v, int _mx, int _mi) { return _mi <= _v && _v < _mx; }
inline bool in_range(Double _v, Double _mi, Double _mx) { return -EPS < _v - _mi && _v - _mx < EPS; }
inline bool in_range(int _x, int _y, int _W, int _H) { return 0 <= _x && _x < _W && 0 <= _y && _y < _H; }
// neighbor clockwise
const int DX[4] = {0,1,0,-1}, DY[4] = {-1,0,1,0};
const int DX_[8] = {0,1,1,1,0,-1,-1,-1}, DY_[8] = {-1,-1,0,1,1,1,0,-1};
// variable update
inline void modAdd(int& _a, int& _b, int &_m) { _a = (_a + _b) % _m; }
inline void modAdd(lint& _a, lint& _b, lint &_m) { _a = (_a + _b) % _m; }
inline void minUpdate(int& _a, int& _b) { _a = min(_a, _b); }
inline void minUpdate(lint& _a, lint& _b) { _a = min(_a, _b); }
inline void maxUpdate(int& _a, int& _b) { _a = max(_a, _b); }
inline void maxUpdate(lint& _a, lint& _b) { _a = max(_a, _b); }

// 0 : right foot 1 : left foot
int dx[2][9] = {
	{ 1, 1, 1, 1, 1, 2, 2, 2, 3 },
	{ -1, -1, -1, -1, -1, -2, -2, -2, -3 }
};
int dy[2][9] = {
	{ 2, 1, 0, -1, -2, 1, 0, -1, 0 },
	{ 2, 1, 0, -1, -2, 1, 0, -1, 0 }
};

struct State {
	int x, y, c, f;
	State(int _x, int _y, int _c, int _f) : x(_x), y(_y), c(_c), f(_f) {}
};
bool operator > (const State& a, const State& b) { return a.c > b.c; }

int W, H;
char grid[66][33];

int cost[66][33][2];

void solve() {
	for_(y,0,H) for_(x,0,W) fill(cost[y][x], cost[y][x] + 2, iINF);
	
	priority_queue< State, vector< State >, greater< State > > q;
	
	for_(x,0,W) {
		if (grid[H - 1][x] == 'S') {
			q.push(State(x, H - 1, 0, 0));
			cost[H - 1][x][0] = 0;
			q.push(State(x, H - 1, 0, 1));
			cost[H - 1][x][1] = 0;			
		}
	}
	
	while (!q.empty()) {
		State s = q.top(); q.pop();
		
		if (cost[s.y][s.x][s.f] < s.c) continue;
		
		for_(d,0,9) {
			int nx = s.x + dx[s.f][d], ny = s.y + dy[s.f][d];
			if (!in_range(nx, ny, W, H)) continue;
			
			char tmp = grid[ny][nx];
			if (tmp == 'X') continue;
			
			int nc = 0;
			if (tmp != 'S' && tmp != 'T') nc = tmp - '0';
			
			if (cost[ny][nx][1 - s.f] > s.c + nc) {
				cost[ny][nx][1 - s.f] = s.c + nc;
				q.push(State(nx, ny, s.c + nc, 1 - s.f));
			}
		}
	}
	
	int ans = iINF;
	for_(x,0,W) if (grid[0][x] == 'T') {
		minUpdate(ans, cost[0][x][0]);
		minUpdate(ans, cost[0][x][1]);
	}
	
	if (ans == iINF) ans = -1;
	cout << ans << endl;
}

int main() {
	while (cin >> W >> H, W) {
		for_(y,0,H) for_(x,0,W) {
			cin >> grid[y][x];
		}
		solve();
	}
	return 0;
}

Measured memory_bytes: 1236