#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <functional>
#include <string>
#include <list>
#include <queue>

using namespace std;

struct edge {int to, dist;
	edge(const int t, const int c): to(t), dist(c){}
};

int x[9] = {1, 1, 1, 1, 1, 2, 2, 2, 3};
int y[9] = {-2, -1, 0, 1, 2, -1, 0, 1, 0};
const int INF = 99999;

typedef pair<int, int> P;

void set_edge(vector<edge> G[], int s, int t, int w)
{
	G[s].push_back(edge(t,w));
}

int Dijkstra(const vector<edge> G[], int n, int s, int t)
{
	int* d = new int[n];
	priority_queue<P, vector<P>, greater<P> > que;
	fill(d, d+n, INF);
	d[s] = 0;
	que.push(P(0,s));

	while(!que.empty()){
		P p = que.top(); que.pop();
		int v = p.second;
		if(d[v] < p.first) continue;
		for (int i=0; i< G[v].size(); i++){
			edge e = G[v][i];
			if(d[e.to] > d[v]+e.dist){
				d[e.to] = d[v]+e.dist;
				que.push(P(d[e.to], e.to));
			}
		}
	}
	int dist = d[t];

	delete[] d;

	return dist;
}

int main()
{
	int w, h, ans;
	string str;

	while(true){
		cin >> w >> h;
		if(w==0 && h==0){return 0;}
		int* graph = new int[w*2*h];
		vector<edge> Graph[w*2*h];
		vector<int> s;
		vector<int> t;

		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				cin >> str;
				if(str == "X"){graph[i*w+j] = INF; graph[(i*w+j)+(h*w)] = INF;}
				else if(str == "S"){graph[i*w+j]=0; graph[(i*w+j)+(h*w)]=0; s.push_back(i*w+j); s.push_back((i*w+j)+(h*w));}
				else if(str == "T"){graph[i*w+j]=0; graph[(i*w+j)+(h*w)]=0; t.push_back(i*w+j); t.push_back((i*w+j)+(h*w));}
				else{ graph[i*w+j] = atoi(str.c_str()); graph[(i*w+j)+(h*w)] = graph[i*w+j];}
			}
		}
		/* 	二部グラフの作成 */
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				if(graph[i*w+j]!=INF){
					for(int k=0; k<9; k++){
						if((j+x[k]<w)&&(i-y[k]>=0)&&(i-y[k]<h)){
							if(graph[(i-y[k])*w+(j+x[k])]!=INF){ 
								set_edge(Graph, i*w+j, (i-y[k])*w+(j+x[k])+h*w, graph[(i-y[k])*w+(j+x[k])+h*w]);
							}
						}
						if((j-x[k]>=0)&&(i-y[k]>=0)&&(i-y[k]<h)){
							if(graph[(i-y[k])*w+(j-x[k])]!=INF){ 
								set_edge(Graph, i*w+j+h*w, (i-y[k])*w+(j-x[k]), graph[(i-y[k])*w+(j-x[k])+h*w]);
							}
						}

					}
				}
			}
		}

		delete[] graph;

		/* SどうしとTどうしを接続 */
		for(int i=0; i< s.size(); i++){
			for(int j=0; j< s.size(); j++){
				set_edge(Graph, s[i], s[j], 0);
			}
		}
		for(int i=0; i< t.size(); i++){
			for(int j=0; j< t.size(); j++){
				set_edge(Graph, t[i], t[j], 0);
			}
		}

		ans = INF; ans = min(ans,Dijkstra( Graph, w*h*2, s[0], t[0]));
		if(ans!=INF){cout << ans << endl;}
		else{cout << -1 << endl;}

	}
}