#include <bits/stdc++.h>
using namespace std;
typedef pair<int, int> P;
int INF = 1 << 10;

vector<P> start;
vector<int> d;
P dxy[] = {P(1, 2), P(1, 1), P(1, 0), P(1, -1), P(1, -2),
		   P(2, 1), P(2, 0), P(2, -1),
		   P(3, 0)};
vector<vector<int> > weights;


struct node{
  int cost;
  P pos;
  int left;
  bool operator>(const node& a) const{
	return this->cost > a.cost;
  }
  node(int c, P p, int l){
	cost = c;
	pos = p;
	left = l;
  }
  
};

void test(){
  cout << "=====test=====" << endl;
  node a(10, P(0, 0), 1), b(11, P(10, 2), 0);
  a.cost = 10; a.pos = P(0, 0); a.left = 1;
  b.cost = 11; b.pos = P(10, 2); b.left = 0;
  if(a > b) cout << "a > b" << endl;
  else cout << "a < b" << endl;
}


void displayStage(vector<vector<char> > stage, int w, int h){
  for(int i = 0; i < h; i ++){
	for(int j = 0; j < w; j++){
	  cout << stage[i][j] << " ";
	}
	cout << endl;
  }
  cout << endl;
}

void getStart(vector<vector<char> > stage, int w, int h){
  start.clear();
  for(int i = 0; i < h; i++){
	for(int j = 0; j < w; j++){
	  if(stage[i][j] == 'S'){
		start.push_back(P(i, j));
	  }
	}
  }
}

void displayStart(){
  for(int i = 0; i < start.size(); i++){
	cout << "( " << start[i].first << ", " << start[i].second << " )" << endl;
  }
  cout << endl;
}

void init(int w, int h){
  d.clear();
  for(int i = 0; i < w * h * 2; i++){
	d.push_back(INF);
  }
}

void displayD(int w, int h, int left){
  if(left == 0){
	cout << "right" << endl;
	for(int i = 0; i < h; i++){
	  for(int j = 0; j < w; j++){
		if(d[i*w + j] == INF) cout << "INF ";
		else cout << d[i*w + j] << " ";
	  }
	  cout << endl;
	}
	cout << endl;
  }
  else{
	cout << "left" << endl;
	for(int i = 0; i < h; i++){
	  for(int j = 0; j < w; j++){
		if(d[(h*w) + i*w + j] == INF) cout << "INF ";
		else cout << d[(h*w) + i*w + j] << " ";
	  }
	  cout << endl;
	}
	cout << endl;
  }
}

void makeWeights(vector<vector<char> > stage, int w, int h){
  weights.clear();
  weights.resize(h);
  for(int i = 0; i < h; i++){
	weights[i].resize(w);
	for(int j = 0; j < w; j++){
	  if(stage[i][j] == 'T' || stage[i][j] == 'S') weights[i][j] = 0;
	  else weights[i][j] = (int)(stage[i][j] - '0');
	}
  }
}

int solve(vector<vector<char> > stage, int w, int h){
  init(w, h);
  getStart(stage, w, h);
  makeWeights(stage, w, h);
  priority_queue<node, vector<node>, greater<node> > pq;
  for(int i = 0; i < start.size(); i++){
	d[0 * (h*w) + start[i].first*w + start[i].second] = 0;
	d[1 * (h*w) + start[i].first*w + start[i].second] = 0;
	pq.push(node(0, start[i], 1));
	pq.push(node(0, start[i], 0));
  }

  while(!pq.empty()){
	node n = pq.top(); pq.pop();
	if(stage[n.pos.first][n.pos.second] == 'T'){
	  return d[n.left * (h*w) + n.pos.first*w + n.pos.second];
	}
	for(int i = 0; i < 9; i++){
	  int nx = n.pos.second + (n.left ? dxy[i].first : -dxy[i].first);
	  int ny = n.pos.first + (n.left ? dxy[i].second : -dxy[i].second);
	  if(0 <= nx && nx < w && 0 <= ny && ny < h && stage[ny][nx] != 'X'){
		int t = n.left ^ 1;
		if(d[t * (h*w) + ny*w + nx] > d[n.left * (h*w) + n.pos.first*w + n.pos.second] + weights[ny][nx]){
		  d[t * (h*w) + ny*w + nx] = d[n.left * (h*w) + n.pos.first*w + n.pos.second] + weights[ny][nx];
		  pq.push(node(d[t * (h*w) + ny*w + nx], P(ny, nx), t));
		}
	  }
	}
  }
  return -1;
  
}


int main(){
  int w, h;
  while(1){
	cin >> w >> h;
	if(w == 0 && h == 0) break;
	vector<vector<char> > stage(h);
	for(int i = 0; i < h; i++){
	  stage[i].resize(w);
	  for(int j = 0; j < w; j++){
		cin >> stage[i][j];
	  }
	}

	cout << solve(stage, w, h) << endl;
  }
  
  return 0;
}

Measured memory_bytes: 3072