#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iostream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <ctime>
#include <fstream>
#include <queue>
#include <complex>
 
#define INF 100000000
#define EPS 1e-9
 
using namespace std;
 
typedef long long ll;
typedef pair<int, int> P;

#define MAX_W 30
#define MAX_H 60
int W, H;
char maze[MAX_H][MAX_W];

vector<int> ans_list;

int d[2][MAX_H][MAX_W];
bool used[2][MAX_H][MAX_W];

//右足を動かすとき
int rdx[] = {1,1,2,1,2,3,1,2,1};
int rdy[] = {-2,-1,-1,0,0,0,1,1,2};
//左足を動かすとき
int ldx[] = {-1,-1,-2,-1,-2,-3,-1,-2,-1};
int ldy[] = {-2,-1,-1,0,0,0,1,1,2};

vector<P> start_pos;
vector<P> goal_pos;

void solve(vector<P> dir[2][MAX_H][MAX_W]){
  
  /*
  cout << endl << "山の確認" << endl;
  for(int i = 0; i < H; i++){
    for(int j = 0; j < W; j++){
      if(maze[i][j] != 'X')
	cout << maze[i][j] - '0' << " ";
      else
	cout << maze[i][j] << " ";
    }
    cout << endl;
  }
  */  

  for(int i = 0; i < 2; i++){
    for(int j = 0; j < H; j++){
      for(int k = 0; k < W; k++){
	d[i][j][k] = INF;
	used[i][j][k] = false;
      }
    }
  }

  for(int i = 0; i < start_pos.size(); i++){
    for(int k = 0; k < 2; k++){
      d[k][start_pos[i].second][start_pos[i].first] = 0;
    }
  }

  while(true){

    P kk;// k.first = x :: k.second = y
    int mode = -1;// 左足か、右足どちらを動かすのか

    for(int i = 0; i < 2; i++){
      for(int j = 0; j < H; j++){
	for(int k = 0; k < W; k++){
	  if(!used[i][j][k] && (mode == -1 || d[i][j][k] < d[mode][kk.second][kk.first])){
	    mode = i;
	    kk.first = k;
	    kk.second = j;
	  }
	}
      }
    }

    if(mode == -1)
      break;

    //cout << mode << " " << kk.first << " " << kk.second << endl;

    used[mode][kk.second][kk.first] = true;

    mode = (mode + 1)%2;

    for(int i = 0; i < dir[mode][kk.second][kk.first].size(); i++){
      int x = dir[mode][kk.second][kk.first][i].first;
      int y = dir[mode][kk.second][kk.first][i].second;
      /*
      if(d[mode][y][x] > d[(mode+1)%2][kk.second][kk.first]
	 + maze[y][x] - '0'){
	printf("ok  %d %d -> %d %d\n", kk.first, kk.second, x, y);
	cout << maze[y][x] << endl;
      }
      */
      d[mode][y][x] = min(d[mode][y][x], 
			  d[(mode+1)%2][kk.second][kk.first]
			  + maze[y][x] - '0');
    }

  }

}

int main(){

  while(true){
    cin >> W >> H;
    if(W == 0)
      break;

    start_pos.clear();
    goal_pos.clear();

    for(int i = 0; i < H; i++){
      for(int j = 0; j < W; j++){
	cin >> maze[i][j];
	if(maze[i][j] == 'S'){
	  start_pos.push_back(P(j,i));
	  maze[i][j] = '0';
	}
	else if(maze[i][j] == 'T'){
	  goal_pos.push_back(P(j,i));
	  maze[i][j] = '0';
	}
      }
    }

    vector<P> dir[2][MAX_H][MAX_W]; //dir[0] : 右足を動かすとき dir[1] : 左足

    //cout << "道の生成開始" << endl;
    for(int i = 0; i < H; i++){
      for(int j = 0; j < W; j++){
	if(maze[i][j] == 'X')
	  continue;
	for(int k = 0; k < 9; k++){
	  int x = j + rdx[k];
	  int y = i + rdy[k];
	  if(x >= 0 && x < W && y >= 0 && y < H && maze[y][x] != 'X'){
	    dir[0][i][j].push_back(P(x,y));
	  }
	  x = j + ldx[k];
	  y = i + ldy[k];
	  if(x >= 0 && x < W && y >= 0 && y < H && maze[y][x] != 'X'){
	    dir[1][i][j].push_back(P(x,y));
	  }
	}
      }
    }

    //cout << "道の生成終了" << endl;
    //cout << "探索開始" << endl;

    solve(dir);

    //cout << "探索終了" << endl;

    int ans = INF;

    /*
    for(int i = 0; i < H; i++){
      for(int j = 0; j < W; j++){
	printf("%2d ", d[0][i][j]);
      }
      cout << endl;
    }
    */

    for(int i = 0; i < goal_pos.size(); i++){
      for(int k = 0; k < 2; k++){
	ans = min(ans, d[k][goal_pos[i].second][goal_pos[i].first]);
      }
    }

    ans_list.push_back(ans);

  }

  for(int i = 0; i < ans_list.size(); i++){
    if(ans_list[i] == INF)
      cout << -1 << endl;
    else
      cout << ans_list[i] << endl;
  }

  return 0;

}

Measured memory_bytes: 1796