Problem:
Problem D:
Cliff Climbing
At 17:00, special agent Jack starts to escape from the enemy camp.
There is a cliff in between the camp and the nearest safety zone.
Jack has to climb the almost vertical cliff 
by stepping his feet on the blocks that cover the cliff.
The cliff has slippery blocks where Jack has to
spend time to take each step. 
He also has to bypass some blocks that are too loose to support his weight.
Your mission is to write a program that calculates the minimum time to complete climbing.
Figure D-1 shows an example of cliff data that you will
receive.
The cliff is covered with square blocks.
Jack starts cliff climbing from the ground under the cliff,
by stepping his left or right foot on one of the blocks marked with
'S' at the bottom row.
The numbers on the blocks are the "slippery levels".  It takes
t
time units for him to safely put his foot on a
block marked with
t
, where 1 ≤
t
≤ 9.
He cannot put his feet on blocks marked with 'X'.
He completes the climbing when he puts 
either of his feet on one of the blocks marked with 'T' at the top row.
Figure D-1: Example of Cliff Data
Jack's movement must meet the following constraints. 
After putting his left (or right) foot on a block, he can only move
his right (or left, respectively) foot.
His left foot position (
lx
,
ly
) and his right foot position
(
rx
,
ry
) should satisfy
lx
<
rx
and |
lx
-
rx
| + |
ly
-
ry
| ≤ 3
.
This implies that, given a position of his left foot in Figure D-2 (a), he has to
place his right foot on one of the nine blocks marked with blue color.
Similarly, given a position of his right foot in Figure D-2 (b),
he has to place his
left foot on one of the nine blocks marked with blue color.
Figure D-2: Possible Placements of Feet
Input
The input is a sequence of datasets.
The end of the input is indicated by a line containing two zeros separated by a space.
Each dataset is formatted as follows:
w h
s(1,1)
...
s(1,w)
s(2,1)
...
s(2,w)
...
s(h,1)
...
s(h,w)
The integers
w
and
h
are the width and the height of 
the matrix data of the cliff. You may assume 2 ≤
w
≤ 30 and 5 ≤
h
≤ 60.
Each of the following
h
lines consists of
w
characters
delimited by a space.
The character
s(y, x)
represents the state of the block at
position 
(
x
,
y
) as follows:
'S': Jack can start cliff climbing from this block.
'T': Jack finishes climbing when he reaches this block.
'X': Jack cannot put his feet on this block.
'1' - '9' (
= t
): Jack has to spend
t
time units
to put either of his feet on this block.
You can assume that it takes no time to put a foot on a block marked with 'S' or 'T'.
Output
For each dataset, print a line only having a decimal integer indicating 
the minimum time required for the cliff climbing,
when Jack can complete it.
Otherwise, print a line only having "-1" for the dataset.
Each line should not have any characters other than these numbers.
Sample Input
6 6
4 4 X X T T
4 7 8 2 X 7
3 X X X 1 8
1 2 X X X 6
1 1 2 4 4 7
S S 2 3 X X
2 10
T 1
1 X
1 X
1 X
1 1
1 X
1 
...(truncated)

Submitted solutions:

code_snippet: #include <iostream>
#include <algorithm>
#include <queue>
#include <cstdio>
using namespace std;
#define reps(i,j,k) for(int i = j ; i < k ; ++i)
#define rep(i,j) reps(i,0,j)


const int ldx[] = {1,1,2,1,2,3,1,2,1};
const int ldy[] = {2,1,1,0,0,0,-1,-1,-2};

const int rdx[] = {-1,-2,-1,-3,-2,-1,-2,-1,-1};
const int rdy[] = {2,1,1,0,0,0,-1,-1,-2};

class data{
public:
	int y;
	int x;
	int cost;
	bool is_r;
	data(){}
	data(int y,int x,int cost,bool is_r){
		this->y = y;
		this->x = x;
		this->cost = cost;
		this->is_r = is_r;
	}
	
	bool operator<(const data &a)const{
		return a.cost < cost;
	}

};
int memo[70][50][2];
int main(){
	int w,h;
	while(true){
		rep(i,70){
			rep(j,50){
				rep(k,2){
					memo[i][j][k] = 1e9;
				}
			}
		}
		cin >> w >> h;
		char stage[100][100];
		if( w == 0 && h == 0)break;
		rep(i,h){
			rep(j,w){
				scanf(" %c",&stage[i][j]);
			}
		}
		priority_queue < data > Q;
		rep(i,h){
			rep(j,w){
				if(stage[i][j] == 'S'){

					Q.push(data(i,j,0,true));
					Q.push(data(i,j,0,false));
				}
			}
		}
		int ans = -1;
		while(!Q.empty()){
			data d = Q.top();
			Q.pop();
			if(memo[d.y][d.x][d.is_r] != 1e9)continue;
			memo[d.y][d.x][d.is_r] = d.cost;			
			if(stage[d.y][d.x] == 'T'){
				ans = d.cost;
				break;
			}
			if(d.is_r){
				rep(idx,9){
					int ny = d.y + rdy[idx];
					int nx = d.x + rdx[idx];
					if(ny < 0 || ny > h-1 || nx < 0 || nx > w-1 || stage[ny][nx] == 'X'){
						continue;
					}
					if(stage[ny][nx] == 'S' || stage[ny][nx] == 'T'){
						Q.push(data(ny,nx,d.cost,false));
					}
					else Q.push(data(ny,nx,d.cost+stage[ny][nx]-'0',false));
				}
			}
			else{
				rep(idx,9){
					int ny = d.y + ldy[idx];
					int nx = d.x + ldx[idx];
					if(ny < 0 || ny > h-1 || nx < 0 || nx > w-1 || stage[ny][nx] == 'X'){
						continue;
					}
					if(stage[ny][nx] == 'S' || stage[ny][nx] == 'T'){
						Q.push(data(ny,nx,d.cost,true));
					}
					else Q.push(data(ny,nx,d.cost+stage[ny][nx]-'0',true));
				}

			}
		}
		cout << ans << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 30
memory_kb: 3652
final_rank: 13

code_snippet: #include <queue>
#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")

// #ifndef ONLINE_JUDGE
// #define _GLIBCXX_DEBUG // 配列外参照のエラー
// #endif

// スタンダードライブラリ
#include <bits/stdc++.h>
using namespace std;

// 型関連
using ll = long long;
using lint = long long;
using pll = pair<ll, ll>;
using plll = tuple<ll, ll, ll>;
using pii = pair<int, int>;
using piii = tuple<ll, ll, ll>;
using vi = vector<int>;
using vvi = vector<vector<int>>;
using vvvi = vector<vector<vector<int>>>;
using vvvvi = vector<vector<vector<vector<int>>>>;
using vvvvvi = vector<vector<vector<vector<vector<int>>>>>;
using vl = vector<ll>;
using vvl = vector<vector<ll>>;
using vvvl = vector<vector<vector<ll>>>;
using vvvvl = vector<vector<vector<vector<ll>>>>;

template <class T> using prique = priority_queue<T>;
template <class T> void chmin(T &a, T b) {
    if (a > b)
        a = b;
}
template <class T> void chmax(T &a, T b) {
    if (a < b)
        a = b;
}

#define all(v) v.begin(), v.end()

// 型定数
constexpr ll mod = 998244353;
constexpr ll MOD = 1000000007;
int INF32 = 2e9;
ll INF64 = 9e18;
#define endl '\n';

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

/////////////////////////// print関連
template <typename T> void print(vector<T> A);
void print();
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail);
void print(string S);
template <typename T> void print(vector<vector<T>> &F);

inline void Yes(bool f);

///////////////////ここから//////////////////////
bool solve() {
    int H, W;
    cin >> W >> H;
    if (H == 0) {
        return false;
    }

    vvi F(H, vi(W));
    set<pii> Sset, Tset, Xset;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            char c;
            cin >> c;
            if (c == 'S') {
                Sset.insert({i, j});
            } else if (c == 'T') {
                Tset.insert({i, j});
            } else if (c == 'X') {
                Xset.insert({i, j});
            } else {
                F[i][j] = c - '0';
            }
        }
    }

    int drx[2][9] = {{-2, -1, -1, 0, 0, 0, 1, 1, 2},
                     {-2, -1, -1, 0, 0, 0, 1, 1, 2}};
    int dry[2][9] = {{1, 1, 2, 1, 2, 3, 1, 2, 1},
                     {-1, -1, -2, -1, -2, -3, -1, -2, -1}};

    using state = tuple<int,int,int,int>;
    priority_queue<state, vector<state>, greater<state>> que;
    vvvi dist(H, vvi(W, vi(2, INF32)));
    vvvi f(H, vvi(W, vi(2, 0)));

    for (auto [x, y] : Sset) {
        for (int L = 0; L < 2; L++) {
            dist[x][y][L] = 0;
            que.emplace(0, x, y, L);
        }
    }
    while (!que.empty()) {
        auto [dis, x, y, L] = que.top();
        que.pop();
        if (f[x][y][L]) {
            continue;
        }
        f[x][y][L] = 1;
        for (int d = 0; d < 9; d++) {
            int nx = x + drx[L][d], ny = y + dry[L][d],nL=1-L;
            if (nx < 0 || nx >= H || ny < 0 || ny >= W) {
                continue;
            }
            if (Xset.count({nx, ny}) || dis + F[nx][ny] >= dist[nx][ny][nL]) {
                continue;
            }
            dist[nx][ny][nL] = dis + F[nx][ny];
            que.emplace(dist[nx][ny][nL],nx,ny,nL);
        }
    }
    int ans=INF32;
    for (auto [x, y] : Tset) {
        for (int L = 0; L < 2; L++) {
            chmin(ans,dist[x][y][L]);
        }
    }
    if (ans == INF32) {
        print(-1);
    } else {
        print(ans);
    }

    return true;
}

int main() {
    ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    while (solve())
        ;
}

////////////////////print/////////////////////////
// 1次元ベクトルを出力する
template <typename T> void print(vector<T> A) {
    if (A.size() == 0) {
        return;
    }
    for (size_t i = 0; i < A.size() - 1; i++) {
        cout << A[i] << ' ';
    }
    cout << A[A.size() - 1] << endl;
    return;
}

// 2次元ベクトルを出力する
template <typename T> void print(vector<vector<T>> &F) {
    for (size_t i = 0; i < F.size(); i++) {
        for (size_t j = 0; j < F[i].size(); j++) {
            cout << F[i][j];
            if (j < F[i].size() - 1) {
                cout << ' ';
            }
        }
        cout << endl;
    }
}

// 空白行を出力するprint
void print() { cout << endl; }

// 数値・文字列を空白区切りで出力する. print(a,b)など
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

void print(string S) { cout << S << endl; }

//////////////出力関連

inline void Yes(bool f) {
    if (f) {
        cout << "Yes" << endl;
    } else {
        cout << "No" << endl;
    }
}
accuracy: 1
time_ms: 50
memory_kb: 3840
final_rank: 15

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;

// 15::44 ~
const int INF = 2e8;

int main() {
    while (true) {
        int w, h;
        cin >> w >> h;
        if (w == 0 && h == 0) {
            break;
        }

        vector<vector<char>> grid(h, vector<char>(w));
        vector<pair<int, int>> start;
        vector<pair<int, int>> target;
        for (int i = 0; i < h; i++) {
            for (int j = 0; j < w; j++) {
                cin >> grid[i][j];
                if (grid[i][j] == 'S') {
                    start.emplace_back(i, j);
                    grid[i][j] = '0';
                }
                if (grid[i][j] == 'T') {
                    target.emplace_back(i, j);
                    grid[i][j] = '0';
                }
            }
        }

        vector<vector<vector<int>>> dist(h, vector<vector<int>>(w, vector<int>(2, INF)));
        priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>, greater<>> pq;
        for (auto [x, y] : start) {
            dist[x][y][0] = 0;
            dist[x][y][1] = 0;
            pq.emplace(0, x, y, 0);
            pq.emplace(0, x, y, 1);
        }

        while (!pq.empty()) {
            auto [cost, x, y, leg] = pq.top();
            pq.pop();

            if (dist[x][y][leg] < cost) {
                continue;
            }

            // 左足からの移動
            if (leg == 0) {
                for (int ay = 1; ay <= 3; ay++) {
                    for (int ax = -2; ax <= 2; ax++) {
                        int rx = x + ax;
                        int ry = y + ay;
                        if (rx < 0 || rx >= h || ry < 0 || ry >= w) {
                            continue;
                        }
                        if (grid[rx][ry] == 'X') {
                            continue;
                        }
                        if (!(abs(x - rx) + abs(y - ry) <= 3)) {
                            continue;
                        }

                        int next_cost = cost + (grid[rx][ry] - '0');
                        if (dist[rx][ry][1] > next_cost) {
                            dist[rx][ry][1] = next_cost;
                            pq.emplace(next_cost, rx, ry, 1);
                        }
                    }
                }
            }

            // 右足からの移動
            if (leg == 1) {
                for (int ay = -3; ay <= -1; ay++) {
                    for (int ax = -2; ax <= 2; ax++) {
                        int lx = x + ax;
                        int ly = y + ay;
                        if (lx < 0 || lx >= h || ly < 0 || ly >= w) {
                            continue;
                        }
                        if (grid[lx][ly] == 'X') {
                            continue;
                        }
                        if (!(abs(x - lx) + abs(y - ly) <= 3)) {
                            continue;
                        }

                        int next_cost = cost + (grid[lx][ly] - '0');
                        if (dist[lx][ly][0] > next_cost) {
                            dist[lx][ly][0] = next_cost;
                            pq.emplace(next_cost, lx, ly, 0);
                        }
                    }
                }
            }
        }

        int ans = INF;
        for (auto [x, y] : target) {
            ans = min({ans, dist[x][y][0], dist[x][y][1]});
        }
        cout << (ans == INF ? -1 : ans) << endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3840
final_rank: 12

code_snippet: #include <bits/stdc++.h>
using namespace std;

template<typename T>
using pqg = priority_queue<T, vector<T>, greater<T>>;

bool solve() {
    int H, W;
    cin >> W >> H;
    if (H == 0 && W == 0) return false;
    vector<vector<char>> C(H, vector<char>(W));
    vector D(H, vector(W, array<int, 2>{1 << 30, 1 << 30}));
    pqg<tuple<int, int, int, int>> q;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            cin >> C[i][j];
            if (C[i][j] == 'S') {
                D[i][j][0] = 0;
                D[i][j][1] = 0;
                q.emplace(0, i, j, 0);
                q.emplace(0, i, j, 1);
            }
        }
    }
    int ans = 1 << 30;
    while (q.size()) {
        auto [d, r, c, f] = q.top();
        q.pop();
        if (C[r][c] == 'T') ans = min(ans, d);
        for (int dr = -3; dr <= 3; dr++) {
            for (int dc = -3; dc <= 3; dc++) {
                if (abs(dr) + abs(dc) > 3) continue;
                if (f && dc >= 0) continue;
                if (!f && dc <= 0) continue;
                int nr = r + dr, nc = c + dc;
                if (0 <= nr && nr < H && 0 <= nc && nc < W) {
                    if (C[nr][nc] == 'X') continue;
                    int w = (isdigit(C[nr][nc]) ? C[nr][nc] - '0' : 0);
                    if (D[nr][nc][!f] > d + w) {
                        D[nr][nc][!f] = d + w;
                        q.emplace(d + w, nr, nc, !f);
                    }
                }
            }
        }
    }
    if (ans == 1 << 30) ans = -1;
    cout << ans << '\n';
    return true;
}

int main() {
    while (solve()) {}
}
accuracy: 1
time_ms: 10
memory_kb: 3584
final_rank: 1

code_snippet: #include <bits/stdc++.h>
using namespace std;
typedef int ll;
typedef unsigned long long ull;
typedef long double ld;
#define rep(i, n) for (ll i = 0; i < (ll)(n); i++)
#define rrep(i,start,end) for (ll i = start;i >= (ll)(end);i--)
#define repn(i,end) for(ll i = 0; i <= (ll)(end); i++)
#define reps(i,start,end) for(ll i = start; i < (ll)(end); i++)
#define repsn(i,start,end) for(ll i = start; i <= (ll)(end); i++)
#define each(p,a) for(auto &p:a)
typedef vector<ll> vll;
typedef vector<pair<ll ,ll>> vpll;
typedef vector<vector<ll>> vvll;
typedef set<ll> sll;
typedef map<ll , ll> mpll;
typedef pair<ll ,ll> pll;
typedef tuple<ll , ll , ll> tpl3;
#define LL(...) ll __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) ld __VA_ARGS__; input(__VA_ARGS__)
#define Str(...) string __VA_ARGS__; input(__VA_ARGS__)
#define Ch(...) char __VA_ARGS__; input(__VA_ARGS__)
#define all(a)  (a).begin(),(a).end()
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() );
#define sz(x) (ll)x.size()
// << std::fixed << std::setprecision(10)
const ll INF = 1 << 29;
const ld EPS = 1e-9;
 
ll lceil(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b)+1;}else{return -((-a)/b);}}
ll lfloor(ll a,ll b){if(a%b==0){return a/b;}if(a>=0){return (a/b);}else{return -((-a)/b)-1;}}
inline ll positive_mod(ll a,ll m){return (a % m + m)%m;}
inline ll popcnt(ull a){ return __builtin_popcountll(a);}
//0indexed
inline ll topbit(ll a){assert(a != 0);return 63 - __builtin_clzll(a);}
inline ll smlbit(ll a){assert(a != 0);return __builtin_ctzll(a);}
template<class T> bool chmin(T& a, T b){if(a > b){a = b;return true;}return false;}
template<class T> bool chmax(T& a, T b){if(a < b){a = b;return true;}return false;}
template<typename T> std::istream &operator>>(std::istream&is,std::vector<T>&v){for(T &in:v){is>>in;}return is;}
template<typename T> std::ostream &operator<<(std::ostream&os,const std::vector<T>&v){for(auto it=std::begin(v);it!=std::end(v);){os<<*it<<((++it)!=std::end(v)?" ":"");}return os;}
template<typename T1, typename T2>std::ostream &operator<< (std::ostream &os, std::pair<T1,T2> p){os << "{" << p.first << "," << p.second << "}";return os;}
template<class... T>void input(T&... a){(cin >> ... >> a);}
void print(){cout << endl;}
template<class T, class... Ts>void print(const T& a, const Ts&... b){cout << a;((cout << ' ' << b), ...);cout << endl;}
template<class T> void pspace(const T& a){ cout << a << ' ';}
void perr(){cerr << endl;}
template<class T, class... Ts>void perr(const T& a, const Ts&... b){cerr << a;((cerr << ' ' << b), ...);cerr << endl;}
void yes(bool i = true){ return print(i?"yes":"no"); }
void Yes(bool i = true){ return print(i?"Yes":"No"); }
void YES(bool i = true){ return print(i?"YES":"NO"); }
template <class T> vector<T> &operator++(vector<T> &v) {for(auto &e : v) e++;return v;}
template <class T> vector<T> operator++(vector<T> &v, signed) {auto res = v;for(auto &e : v) e++;return res;}
template <class T> vector<T> &operator--(vector<T> &v) {for(auto &e : v) e--;return v;}
template <class T> vector<T> operator--(vector<T> &v, signed) {auto res = v;for(auto &e : v) e--;return res;}
//grid探索用
vector<ll> _ta = {0,0,1,-1,1,1,-1,-1};
vector<ll> _yo = {1,-1,0,0,1,-1,1,-1};
bool isin(ll now_i,ll now_j,ll h,ll w){return (0<=now_i && now_i < h && 0 <= now_j && now_j < w);}
  
ll lpow(ll x,ll n){ll ans = 1;while(n >0){if(n & 1)ans *= x;x *= x;n >>= 1;}return ans;}
ll Modlpow(ll x,ll n,ll m){ll ans = 1;ll a = x%m;while(n >0){if(n & 1){ans *= a;ans%= m;}a *= a;a %= m;n >>= 1;}return ans;} 
const ll MOD9 = 998244353LL;
const ll MOD10 = 1000000007LL;

void solve(ll h,ll w){
  vector<vector<char>> s(h,vector<char>(w));
  rep(i,h){
    cin>> s[i];
  }
  vpll ltor,rtol;
  repsn(i,-2,2)repsn(j,1,3){
    if(abs(i)+abs(j)<= 3){
      ltor.push_back({i,j});
      rtol.push_back({i,-j});
    }
  }
  // ll siz = sz(ltor);

  auto tostate =[&](ll i,ll j,ll k,ll l,ll z){
    return z * (h*w)*(h*w) + i *(h*w)*w + j *(h*w) + k * w + l;
  };
  auto revstate = [&](ll v) -> tuple<ll,ll,ll,ll,ll> {
    ll l = v % w;
    ll k = (v%(h*w))/w;
    v /= h * w;
    ll j = v % w;
    ll i = (v%(h*w))/w;
    v /= h * w;
    ll z = v;
    return{i,j,k,l,z};
  };
  // vector<vpll> g(h * w*h*w * 2);
  // rep(i,h)rep(j,w)rep(k,h)rep(l,w){
  //   if(s[i][j] == 'X' or s[k][l] == 'X')continue;
  //   bool ok = false;
  //   each(p,ltor){
  //     auto[a,b] = p;
  //     if(i+a == k && j + b == l)ok =true;
  //   }
  //   if(!ok)continue;
  //   //hidari,migi
  //   each(p,ltor){
  //     auto [a,b] = p;
  //     if(isin(i+a,j+b,h,w) && s[i+a][j+b] != 'X'){
  //       g[tostate(i,j,k,l,0)].emplace_back(tostate(i,j,i+a,b+j,1),isdigit(s[i+a][b+j])?s[i+a][b+j]-'0':0);
  //     }
  //   }
  //   each(p,rtol){
  //     auto [a,b] = p;
  //     if(isin(k+a,l+b,h,w) && s[k+a][l+b] != 'X'){
  //       g[tostate(i,j,k,l,1)].emplace_back(tostate(k+a,l+b,k,l,0),isdigit(s[k+a][b+l])?s[k+a][l+b]-'0':0);
  //     }
  //   }
    
  // }

  using P = pair<ll,ll>;
  vll dis(h * w*h*w * 2,INF);

  // G[i]<j,d> i->j の距離(d)
  // 「仮の最短距離, 頂点」が小さい順に並ぶ
  priority_queue<P,vector<P>,greater<P>>pq;
  vll ablegoal;
  rep(i,h)rep(j,w){
    if(s[i][j] == 'S'){
      //hidari
      each(p,ltor){
        auto [a,b] = p;
        if(isin(i+a,j+b,h,w) && s[i+a][j+b] != 'X'){
          dis[tostate(i,j,i+a,b+j,1)] = isdigit(s[i+a][b+j])?s[i+a][b+j]-'0':0;
          pq.push({dis[tostate(i,j,i+a,b+j,1)],tostate(i,j,i+a,b+j,1)});
        }
      }
      each(p,rtol){
        auto [a,b] = p;
        if(isin(i+a,j+b,h,w) && s[i+a][j+b] != 'X'){
          dis[tostate(i+a,j+b,i,j,0)] = isdigit(s[i+a][b+j])?s[i+a][b+j]-'0':0;
          pq.push({dis[tostate(i+a,j+b,i,j,0)],tostate(i+a,j+b,i,j,0)});
        }
      }
    }
    if(s[i][j] == 'T'){
      each(p,ltor){
        auto [a,b] = p;
        if(isin(i+a,j+b,h,w) && s[i+a][j+b] != 'X'){
          ablegoal.push_back(tostate(i,j,i+a,j+b,0));
          ablegoal.push_back(tostate(i,j,i+a,j+b,1));
        }
      }
      each(p,rtol){
        auto [a,b] = p;
        if(isin(i+a,j+b,h,w) && s[i+a][j+b] != 'X'){
          ablegoal.push_back(tostate(i+a,j+b,i,j,0));
          ablegoal.push_back(tostate(i+a,j+b,i,j,1));
        }
      }
    }
  }
  while(!pq.empty()){
    auto [len,now] = pq.top();
    pq.pop();
    if(dis[now]< len){
      continue;
    }
    auto[i,j,k,l,z] = revstate(now);
    if(z == 0){
      each(p,ltor){
        auto [a,b] = p;
        if(isin(i+a,j+b,h,w) && s[i+a][j+b] != 'X'){
          ll next = tostate(i,j,i+a,b+j,1);
          ll cost =isdigit(s[i+a][b+j])?s[i+a][b+j]-'0':0;
          if(dis[next] > dis[now] + cost){
            dis[next] = dis[now] + cost;
            pq.push({dis[next],next});
          }
        }
      }
    }else if(z == 1){
      each(p,rtol){
        auto [a,b] = p;
        if(isin(k+a,l+b,h,w) && s[k+a][l+b] != 'X'){
          ll next = tostate(k+a,l+b,k,l,0);
          ll cost =isdigit(s[k+a][l+b])?s[k+a][l+b]-'0':0;
          if(dis[next] > dis[now] + cost){
            dis[next] = dis[now] + cost;
            pq.push({dis[next],next});
          }
        }
      }
    }


    // for(auto &p:g[now]){
    //   // 注意！
    //   auto [next,cost] = p;
    //   if(dis[next] > dis[now] + cost){
    //     dis[next] = dis[now] + cost;
    //     pq.push({dis[next],next});
    //   }
    // }
  }
  ll ans = INF;
  each(p,ablegoal){
    chmin(ans,dis[p]);
  }
  if(ans >= INF){
    cout << -1 << endl;
  }else{
    cout << ans << endl;
  }
}
 
int main(){
  ios::sync_with_stdio(false);cin.tie(nullptr);
  while(true){
    LL(w,h);
    if(w == 0 && h == 0)break;
    solve(h,w);
  }
}
accuracy: 1
time_ms: 160
memory_kb: 51684
final_rank: 19

code_snippet: #include <bits/stdc++.h>


using namespace std;
//make -f ../makefile SRC=
/*
*/


//------------------------------------------------------------------------------
bool DEBUG = false;
const int INF = 1000000000;

const int MAX_M = 60;
const int MAX_N = 30;
static int G[MAX_M*MAX_N];
const int F = 2;
static int D[MAX_M*MAX_N][F];
static bool marked[MAX_M*MAX_N];

const char SRC = 'S';
const char DEST = 'T';
const char WALL = 'X';
const char FREE = '.';

typedef pair<int,int> PA;
typedef vector<PA> PAS;
static vector<PAS> actions =
{
    {{0,-1}, {0,-2}, {0,-3}, {-1,-1}, {-1,-2}, {-2,-1}, {1,-1}, {1,-2}, {2,-1}},
    {{0, 1}, {0, 2}, {0, 3}, {-1, 1}, {-1, 2}, {-2, 1}, {1, 1}, {1, 2}, {2, 1}}
};
//------------------------------------------------------------------------------
struct State
{
    int v; // vertex
    int f; // foot // L=0, R=1
    State(): v(-1), f(1) {}
    State(int vert, int foot): v(vert), f(foot) {}
    bool operator<(const State& s1) const
    {
        if (v == s1.v) return f < s1.f;
        return v < s1.v;
    }
    void debug() const
    {
        printf("v=%d, f=%c\n", v, f);
    }
};

typedef vector<State> States;
//------------------------------------------------------------------------------
void debug_grid(int M, int N)
{
    for (int m=0; m<M; ++m) { for (int n=0; n<N; ++n) if (G[m*N+n]!=INF) printf("%d ",G[m*N+n]); else printf("X "); printf("\n"); }
}


//------------------------------------------------------------------------------
States successors(int M, int N, const State& s1)
{
    States states;
    int m1 = s1.v/N;
    int n1 = s1.v%N;

    int m2, n2, v2;
    int f2 = ( s1.f == 0 ? 1 : 0 );
    //--------------------------------------------------------------------------
    for (PA p: actions[f2])
    {
        m2 = m1 + p.first;
        n2 = n1 + p.second;

        if (m2 < 0 || m2 >= M || n2 < 0 || n2 >= N) continue;
        v2 = m2*N + n2;
        if (G[v2] == INF) continue;
        states.push_back( State(v2, f2) );
    }
    return states;
}
//------------------------------------------------------------------------------
int bfs(int M, int N, const State& s0, const set<int>& dests)
{
    queue<State> Q;
    for (int v=0; v<M*N; v++) { D[v][0] = INF;  D[v][1] = INF; }
    D[s0.v][s0.f] = 0;
    Q.push( s0 );

    int res = INF;
    while (!Q.empty())
    {
        State s1 = Q.front(); Q.pop();
        if (dests.find(s1.v) != dests.end())
        {
            res = min(res, D[s1.v][s1.f]);
            continue;
        }

        for (State s2: successors(M, N, s1))
        {
            if (D[s2.v][s2.f] == INF || D[s2.v][s2.f] > D[s1.v][s1.f] + G[s2.v])
            {
                D[s2.v][s2.f] = D[s1.v][s1.f] + G[s2.v];
                Q.push( s2 );
            }
        }
    }
    return res;
}

//------------------------------------------------------------------------------
void test()
{

}

//------------------------------------------------------------------------------
int solve(int M, int N, const vector<int>& srcs, const set<int>& dests)
{
    if (DEBUG)
    {
        debug_grid(M, N);
        printf("srcs: "); for (int v: srcs) printf("%d ",v); printf("\n");
        printf("dests: "); for (int v: dests) printf("%d ",v); printf("\n");
    }
    //--------------------------------------------------------------------------
    // base cases:
    if (dests.empty()) return INF;
    //--------------------------------------------------------------------------
    // init params:
    int res = INF;
    //--------------------------------------------------------------------------
    // compute:
    State s0;
    for (int src: srcs)
    {
        s0 = State(src, 0);
        res = min(res, bfs(M, N, s0, dests));

        s0 = State(src, 1);
        res = min(res, bfs(M, N, s0, dests));
    }
    return res;
}

//------------------------------------------------------------------------------printf("%d\n", res);
int main()
{
    //test(); return 0;
    //DEBUG = true;
    //--------------------------------------------------------------------------
    int M, N, v, src, num;
    char c;
    while (true)
    {
        num = scanf("%d %d ", &N, &M);
        if (N == 0 && M == 0) break;
        for (int v=0; v<M*N; ++v) G[v] = 0;

        vector<int> srcs;
        set<int> dests;
        for (int m=0; m<M; ++m)
            for (int n=0; n<N; ++n)
                {
                    num = scanf("%c ", &c);
                    v = m*N + n;
                    if (c == WALL) G[v] = INF;
                    else if (c == SRC) srcs.push_back( v );
                    else if (c == DEST) dests.insert( v );
                    else G[v] = c-'0';
                }

        int res = solve(M, N, srcs, dests);
        if (res == INF) printf("-1\n");
        else printf("%d\n", res);
    }
    //--------------------------------------------------------------------------
    return 0;
}
//------------------------------------------------------------------------------
accuracy: 1
time_ms: 1580
memory_kb: 3436
final_rank: 17

code_snippet: #include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> pi;
typedef vector<ll> vi;
#define FOR(i,l,r) for(ll i=l;i<r;i++)
#define REP(i,n) FOR(i,0,n)
#define ALL(A) A.begin(),A.end()
template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return 1;}return 0;}
template<typename T>using min_priority_queue=priority_queue<T,vector<T>,greater<T>>;
int main(){
    while(1){
        ll W,H;cin>>W>>H;
        if(!W)return 0;
        vector<string>S(H,string(W,'.'));
        REP(i,H)REP(j,W)cin>>S[i][j];
        vector<vector<vector<ll>>>D(2,vector<vector<ll>>(H,vector<ll>(W,1e18)));
        min_priority_queue<tuple<ll,ll,ll,ll>>Q;
        REP(i,H)REP(j,W)if(S[i][j]=='S'){
            D[0][i][j]=D[1][i][j]=0;
            Q.emplace(make_tuple(0LL,0LL,i,j));
            Q.emplace(make_tuple(0LL,1LL,i,j));
        }
        vector<vector<pi>>move={
            {pi(2,1),pi(1,1),pi(1,2),pi(0,1),pi(0,2),pi(0,3),pi(-1,1),pi(-1,2),pi(-2,1)},
            {pi(2,-1),pi(1,-1),pi(1,-2),pi(0,-1),pi(0,-2),pi(0,-3),pi(-1,-1),pi(-1,-2),pi(-2,-1)}
        };
        while(Q.size()){
            auto[d,f,x,y]=Q.top();Q.pop();
            if(d!=D[f][x][y])continue;
            for(auto[dx,dy]:move[f]){
                if(min({x+dx,y+dy,H-1-x-dx,W-1-y-dy})>=0&&S[x+dx][y+dy]!='X'){
                    ll c=S[x+dx][y+dy]-'0';
                    if(S[x+dx][y+dy]=='T'||S[x+dx][y+dy]=='S')c=0;
                    if(chmin(D[1-f][x+dx][y+dy],d+c))Q.emplace(make_tuple(d+c,1-f,x+dx,y+dy));
                }
            }
        }
        ll ans=1e18;
        REP(i,H)REP(j,W)if(S[i][j]=='T')ans=min({ans,D[0][i][j],D[1][i][j]});
        if(ans>1e17)ans=-1;
        cout<<ans<<endl;
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3412
final_rank: 4

code_snippet: #include <bits/stdc++.h>

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

#include <unistd.h>

namespace fastio {
static constexpr uint32_t SZ = 1 << 17;
char ibuf[SZ];
char obuf[SZ];
char out[100];
// pointer of ibuf, obuf


uint32_t pil = 0, pir = 0, por = 0;

struct Pre {
    char num[10000][4];
    constexpr Pre() : num() {
        for (int i = 0; i < 10000; i++) {
            int n = i;
            for (int j = 3; j >= 0; j--) {
                num[i][j] = n % 10 | '0';
                n /= 10;
            }
        }
    }
} constexpr pre;

inline void load() {
    memmove(ibuf, ibuf + pil, pir - pil);
    pir = pir - pil + fread(ibuf + pir - pil, 1, SZ - pir + pil, stdin);
    pil = 0;
    if (pir < SZ)
        ibuf[pir++] = '\n';
}

inline void flush() {
    fwrite(obuf, 1, por, stdout);
    por = 0;
}

void rd(char &c) {
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
}

void rd(string &x) {
    x.clear();
    char c;
    do {
        if (pil + 1 > pir)
            load();
        c = ibuf[pil++];
    } while (isspace(c));
    do {
        x += c;
        if (pil == pir)
            load();
        c = ibuf[pil++];
    } while (!isspace(c));
}

template <typename T> void rd_real(T &x) {
    string s;
    rd(s);
    x = stod(s);
}

template <typename T> void rd_integer(T &x) {
    if (pil + 100 > pir)
        load();
    char c;
    do
        c = ibuf[pil++];
    while (c < '-');
    bool minus = 0;
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (c == '-') {
            minus = 1, c = ibuf[pil++];
        }
    }
    x = 0;
    while ('0' <= c) {
        x = x * 10 + (c & 15), c = ibuf[pil++];
    }
    if constexpr (is_signed<T>::value || is_same_v<T, i128>) {
        if (minus)
            x = -x;
    }
}

void rd(int &x) {
    rd_integer(x);
}
void rd(ll &x) {
    rd_integer(x);
}
void rd(i128 &x) {
    rd_integer(x);
}
void rd(uint &x) {
    rd_integer(x);
}
void rd(ull &x) {
    rd_integer(x);
}
void rd(u128 &x) {
    rd_integer(x);
}
void rd(double &x) {
    rd_real(x);
}
void rd(long double &x) {
    rd_real(x);
}

template <class T, class U> void rd(pair<T, U> &p) {
    return rd(p.first), rd(p.second);
}
template <size_t N = 0, typename T> void rd_tuple(T &t) {
    if constexpr (N < std::tuple_size<T>::value) {
        auto &x = std::get<N>(t);
        rd(x);
        rd_tuple<N + 1>(t);
    }
}
template <class... T> void rd(tuple<T...> &tpl) {
    rd_tuple(tpl);
}

template <size_t N = 0, typename T> void rd(array<T, N> &x) {
    for (auto &d : x)
        rd(d);
}
template <class T> void rd(vector<T> &x) {
    for (auto &d : x)
        rd(d);
}

void read() {}
template <class H, class... T> void read(H &h, T &...t) {
    rd(h), read(t...);
}

void wt(const char c) {
    if (por == SZ)
        flush();
    obuf[por++] = c;
}
void wt(const string s) {
    for (char c : s)
        wt(c);
}
void wt(const char *s) {
    size_t len = strlen(s);
    for (size_t i = 0; i < len; i++)
        wt(s[i]);
}

template <typename T> void wt_integer(T x) {
    if (por > SZ - 100)
        flush();
    if (x < 0) {
        obuf[por++] = '-', x = -x;
    }
    int outi;
    for (outi = 96; x >= 10000; outi -= 4) {
        memcpy(out + outi, pre.num[x % 10000], 4);
        x /= 10000;
    }
    if (x >= 1000) {
        memcpy(obuf + por, pre.num[x], 4);
        por += 4;
    } else if (x >= 100) {
        memcpy(obuf + por, pre.num[x] + 1, 3);
        por += 3;
    } else if (x >= 10) {
        int q = (x * 103) >> 10;
        obuf[por] = q | '0';
        obuf[por + 1] = (x - q * 10) | '0';
        por += 2;
    } else
        obuf[por++] = x | '0';
    memcpy(obuf + por, out + outi + 4, 96 - outi);
    por += 96 - outi;
}

template <typename T> void wt_real(T x) {
    ostringstream oss;
    oss << fixed << setprecision(15) << double(x);
    string s = oss.str();
    wt(s);
}

void wt(int x) {
    wt_integer(x);
}
void wt(ll x) {
    wt_integer(x);
}
void wt(i128 x) {
    wt_integer(x);
}
void wt(uint x) {
    wt_integer(x);
}
void wt(ull x) {
    wt_integer(x);
}
void wt(u128 x) {
    wt_integer(x);
}
void wt(double x) {
    wt_real(x);
}
void wt(long double x) {
    wt_real(x);
}

template <class T, class U> void wt(const pair<T, U> val) {
    wt(val.first);
    wt(' ');
    wt(val.second);
}
template <size_t N = 0, typename T> void wt_tuple(const T t) {
    if constexpr (N < std::tuple_size<T>::value) {
        if constexpr (N > 0) {
            wt(' ');
        }
        const auto x = std::get<N>(t);
        wt(x);
        wt_tuple<N + 1>(t);
    }
}
template <class... T> void wt(tuple<T...> tpl) {
    wt_tuple(tpl);
}
template <class T, size_t S> void wt(const array<T, S> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}
template <class T> void wt(const vector<T> val) {
    auto n = val.size();
    for (size_t i = 0; i < n; i++) {
        if (i)
            wt(' ');
        wt(val[i]);
    }
}

void print() {
    wt('\n');
}
template <class Head, class... Tail> void print(Head &&head, Tail &&...tail) {
    wt(head);
    if (sizeof...(Tail))
        wt(' ');
    print(forward<Tail>(tail)...);
}
void __attribute__((destructor)) _d() {
    flush();
}
} // namespace fastio


using fastio::flush;
using fastio::print;
using fastio::read;

inline void first(bool i = true) {
    print(i ? "first" : "second");
}
inline void Alice(bool i = true) {
    print(i ? "Alice" : "Bob");
}
inline void Takahashi(bool i = true) {
    print(i ? "Takahashi" : "Aoki");
}
inline void yes(bool i = true) {
    print(i ? "yes" : "no");
}
inline void Yes(bool i = true) {
    print(i ? "Yes" : "No");
}
inline void No() {
    print("No");
}
inline void YES(bool i = true) {
    print(i ? "YES" : "NO");
}
inline void NO() {
    print("NO");
}
inline void Yay(bool i = true) {
    print(i ? "Yay!" : ":(");
}
inline void Possible(bool i = true) {
    print(i ? "Possible" : "Impossible");
}
inline void POSSIBLE(bool i = true) {
    print(i ? "POSSIBLE" : "IMPOSSIBLE");
}

/**
 * @brief Fast IO
 */

int N, M;

int encode(int i, int j, int k) {
    return i * M * 2 + j * 2 + k;
}

tuple<int,int,int> decode(int A) {
    return {A/(M*2), (A/2)%M, A%2};
}

int main() {
while(1) {
    cin >> M >> N;
    if (N == 0 && M == 0) return 0;
    vector<vector<char>> C(N,vector<char>(M));
    rep(i,0,N) rep(j,0,M) cin >> C[i][j];
    vector DP(N, vector(M, vector<int>(2, inf)));
    priority_queue<pair<int,int>, vector<pair<int,int>>, greater<pair<int,int>>> PQ;
    rep(i,0,N) {
        rep(j,0,M) {
            if (C[i][j] == 'S') {
                DP[i][j][0] = DP[i][j][1] = 0;
                PQ.push({0,encode(i,j,0)});
                PQ.push({0,encode(i,j,1)});
            }
        }
    }
    while(!PQ.empty()) {
        pair<int,int> P = PQ.top();
        PQ.pop();
        int T = P.first;
        auto [X,Y,Z] = decode(P.second);
        if (DP[X][Y][Z] < T) continue;
        if (Z == 0) {
            rep(dy,1,4) {
                rep(dx,-2,3) {
                    if (abs(dx)+abs(dy) > 3) continue;
                    int NX = X + dx, NY = Y + dy, NZ = 1-Z;
                    if (0 <= NX && NX < N && 0 <= NY && NY < M) {
                        if (C[NX][NY] == 'X') continue;
                        int NT;
                        if (isdigit(C[NX][NY])) {
                            NT = T + (C[NX][NY] - '0');
                        }
                        else {
                            NT = T;
                        }
                        if (chmin(DP[NX][NY][NZ], NT)) {
                            PQ.push({NT,encode(NX,NY,NZ)});
                        }
                    }
                }
            }
        }
        if (Z == 1) {
            rep(dy,-3,0) {
                rep(dx,-2,3) {
                    if (abs(dx)+abs(dy) > 3) continue;
                    int NX = X + dx, NY = Y + dy, NZ = 1-Z;
                    if (0 <= NX && NX < N && 0 <= NY && NY < M) {
                        if (C[NX][NY] == 'X') continue;
                        int NT;
                        if (isdigit(C[NX][NY])) {
                            NT = T + (C[NX][NY] - '0');
                        }
                        else {
                            NT = T;
                        }
                        if (chmin(DP[NX][NY][NZ], NT)) {
                            PQ.push({NT,encode(NX,NY,NZ)});
                        }
                    }
                }
            }
        }
    }
    int ANS = inf;
    rep(i,0,N) {
        rep(j,0,M) {
            if (C[i][j] == 'T') {
                rep(k,0,2) {
                    chmin(ANS, DP[i][j][k]);
                }
            }
        }
    }
    cout << (ANS == inf ? -1 : ANS) << endl;
}
}
accuracy: 1
time_ms: 20
memory_kb: 3404
final_rank: 3

code_snippet: #include <bits/stdc++.h>
using namespace std;
int INF=10000;
int h,w;
char table[61][31];
int cost[2][61][31];
priority_queue<vector<int> > q;
vector<pair<int,int> > v;
int tu(int n){
	return (n+1)/2;
}
void gen(int x,int y,int lr){
	v.clear();
	for(int i=1;i<=3;i++){
		for(int k=i-3;k<=3-i;k++){
			v.push_back(make_pair(x+lr*i,y+k));
		}
	}
	int len=v.size();
	for(int i=0;i<len;i++){
		if(v.at(i).first<0||w<=v.at(i).first||v.at(i).second<0||h<=v.at(i).second){
			v.erase(v.begin()+i);
			len--;
			i--;
		}
	}
}
int main(){
	cin>>w>>h;
	while(w+h>0){
		for(int i=0;i<h;i++){
			for(int k=0;k<w;k++){
				cost[0][i][k]=-INF;
				cost[1][i][k]=-INF;
				cin>>table[i][k];
				if(table[i][k]=='S'){
					q.push({0,i,k,1});
					q.push({0,i,k,-1});
					table[i][k]=0;
				}
			}
		}//l=1,r=-1
		bool flag=false;
		int t1,h1,w1,lr;
		int x,y,test;
		while(q.size()>0&&flag==false){
			t1=q.top().at(0);
			h1=q.top().at(1);
			w1=q.top().at(2);
			lr=q.top().at(3);
			q.pop();
			if(t1>cost[tu(lr)][h1][w1]){
				cost[tu(lr)][h1][w1]=t1;
				gen(w1,h1,lr);
				while(v.size()>0){
					x=v.at(0).first;
					y=v.at(0).second;
					v.erase(v.begin());
					if(table[y][x]=='T'){
						flag=true;
						cout<<-t1<<endl;
						break;
					}
					else if(table[y][x]=='X'||table[y][x]=='S')continue;
					else {
						test=table[y][x]-48;
						if(test<0)test=test+48;
						if(cost[tu(-lr)][y][x]<=-INF+100)q.push({t1-test,y,x,-lr});
					}
				}
			}
		}
		if(flag==false)cout<<-1<<endl;
		while(q.size()>0)q.pop();
		cin>>w>>h;
	}
}
accuracy: 1
time_ms: 50
memory_kb: 3176
final_rank: 11

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using vll = vector<ll>;
using vvll = vector<vll>;
using vvvll = vector<vvll>;
using vb = vector<bool>;
using vvb = vector<vb>;
using vvvb = vector<vvb>;
#define all(A) A.begin(),A.end()
#define rep(i, n) for (int i = 0; i < (int) (n); i++)
template<class T>
void chmax(T& p, T q) { if (p < q)p = q; };

void solve(ll H, ll W) {
    swap(H, W);
    vector<vector<char>> C(H, vector<char>(W));
    rep(h, H)rep(w, W)cin >> C[h][w];
    vvvll DP(H, vvll(W, vll(2, 1e18)));
    vvvb seen(H, vvb(W, vb(2, 0)));
    priority_queue<pair<ll, pair<pair<ll, ll>, ll>>, vector<pair<ll, pair<pair<ll, ll>, ll>>>, greater<pair<ll, pair<pair<ll, ll>, ll>>>> Q;
    rep(h, H)rep(w, W) {
        if (C[h][w] == 'S') {
            DP[h][w][0] = DP[h][w][1] = 0;
            Q.push({ 0,{{h,w},0} });
            Q.push({ 0,{{h,w},1} });
        }
    }
    ll an = 1e18;
    while (!Q.empty()) {
        ll c = Q.top().first;
        ll h = Q.top().second.first.first;
        ll w = Q.top().second.first.second;
        ll u = Q.top().second.second;
        Q.pop();
        if (seen[h][w][u])continue;
        seen[h][w][u] = 1;
        if (u == 0) {
            for (ll nw = w + 1; nw <= min(w + 3, W - 1); nw++) {
                ll dh = 3 - (nw - w);
                for (ll nh = max(0ll, h - dh); nh <= min(H - 1, h + dh); nh++) {
                    if (seen[nh][nw][1])continue;
                    if (C[nh][nw] == 'X')continue;
                    if (C[nh][nw] == 'T') {
                        an = min(an, c);
                        continue;
                    }
                    ll nc = c + C[nh][nw] - '0';
                    if (DP[nh][nw][1] > nc) {
                        DP[nh][nw][1] = nc;
                        Q.push({ nc,{{nh,nw},1} });
                    }
                }
            }
        }
        else {
            for (ll nw = w - 1; nw >= max(w - 3, 0ll); nw--) {
                ll dh = 3 - (w - nw);
                for (ll nh = max(0ll, h - dh); nh <= min(H - 1, h + dh); nh++) {
                    if (seen[nh][nw][0])continue;
                    if (C[nh][nw] == 'X')continue;
                    if (C[nh][nw] == 'T') {
                        an = min(an, c);
                        continue;
                    }
                    ll nc = c + C[nh][nw] - '0';

                    if (DP[nh][nw][0] > nc) {
                        DP[nh][nw][0] = nc;
                        Q.push({ nc,{{nh,nw},0} });
                    }
                }
            }
        }
    }
    cout << (an < 1e17 ? an : -1) << endl;

}

int main() {
    cin.tie(nullptr);
    ios::sync_with_stdio(false);

    ll H, W;
    while (cin >> H >> W) {
        if (H == 0)return 0;
        solve(H, W);
    }

}
accuracy: 1
time_ms: 20
memory_kb: 3660
final_rank: 10

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using ll = long long;

const ll INF = 1e9;
int W, H;

void solve() {
    vector<vector<char>> grid(H, vector<char>(W));
    for (int i = 0; i < H; i++)for (int j = 0; j < W; j++)cin >> grid[i][j];

    vector<pair<int, int>> start;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (grid[i][j] == 'S')start.push_back({i, j});
        }
    }

    priority_queue<tuple<ll, int, int, int>, vector<tuple<ll, int, int, int>>, greater<>> pq;
    vector<vector<vector<ll>>> dist(H, vector<vector<ll>>(W, vector<ll>(2, INF)));
    for (auto [x, y]: start) {
        pq.push({0, x, y, 0});
        dist[x][y][0] = 0;
    }

    for (auto [x, y]: start) {
        pq.push({0, x, y, 1});
        dist[x][y][1] = 0;
    }

    ll ans = INF;
    while (!pq.empty()) {
        auto [cost, x, y, leg] = pq.top();
        pq.pop();
        if (dist[x][y][leg ^ 1] < cost)continue;

        if (leg == 0) {
            for (int i = 1; i <= 3; i++) {
                for (int j = -2; j <= 2; j++) {
                    int lx = j + x, ly = i + y;
                    if (abs(lx - x) + abs(ly - y) <= 3) {
                        if (!(0 <= lx && lx < H && 0 <= ly && ly < W))continue;
                        if (grid[lx][ly] == 'X')continue;
                        if (grid[lx][ly] == 'T') {
                            ans = min(ans, cost);
                            continue;
                        }
                        if (dist[lx][ly][leg] > cost + (grid[lx][ly] - '0')) {
                            dist[lx][ly][leg] = cost + (grid[lx][ly] - '0');
                            pq.push({dist[lx][ly][leg], lx, ly, leg ^ 1});
                        }
                    }
                }
            }
        } else {
            for (int i = -3; i <= -1; i++) {
                for (int j = -2; j <= 2; j++) {
                    int lx = j + x, ly = i + y;
                    if (abs(lx - x) + abs(ly - y) <= 3) {
                        if (!(0 <= lx && lx < H && 0 <= ly && ly < W))continue;
                        if (grid[lx][ly] == 'X')continue;
                        if (grid[lx][ly] == 'T') {
                            ans = min(ans, cost);
                            continue;
                        }
                        if (dist[lx][ly][leg] > cost + (grid[lx][ly] - '0')) {
                            dist[lx][ly][leg] = cost + (grid[lx][ly] - '0');
                            pq.push({dist[lx][ly][leg], lx, ly, leg ^ 1});
                        }
                    }
                }
            }
        }
    }
    if (ans == INF)cout << -1 << endl;
    else cout << ans << endl;
}

int main() {
    while (true) {
        cin >> W >> H;
        if (W == 0 && H == 0)break;
        solve();
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3400
final_rank: 2

code_snippet: #include <iostream>
#include <vector>
#include <algorithm>
#include <utility>
#include <map>
#include <cmath>
#include <queue>
#include <string>
#include <set>
#include <stack>
#include <numeric>
#include <functional>
#include <bitset>

using namespace std;
using ll = long long;

const ll INF = 1e9;
int W, H;

void solve() {
    vector<vector<char>> grid(H, vector<char>(W));
    for (int i = 0; i < H; i++)for (int j = 0; j < W; j++)cin >> grid[i][j];

    vector<pair<int, int>> start;
    for (int i = 0; i < H; i++) {
        for (int j = 0; j < W; j++) {
            if (grid[i][j] == 'S')start.push_back({i, j});
        }
    }

    priority_queue<tuple<ll, int, int, int>, vector<tuple<ll, int, int, int>>, greater<>> pq;
    vector<vector<vector<ll>>> dist(H, vector<vector<ll>>(W, vector<ll>(2, INF)));
    for (auto [x, y]: start) {
        pq.push({0, x, y, 0});
        dist[x][y][0] = 0;
    }

    for (auto [x, y]: start) {
        pq.push({0, x, y, 1});
        dist[x][y][1] = 0;
    }

    ll ans = INF;
    while (!pq.empty()) {
        auto [cost, x, y, leg] = pq.top();
        pq.pop();
        if (dist[x][y][leg ^ 1] < cost)continue;

        if (leg == 0) {
            for (int i = 1; i <= 3; i++) {
                for (int j = -2; j <= 2; j++) {
                    int lx = j + x, ly = i + y;
                    if (abs(lx - x) + abs(ly - y) <= 3) {
                        if (!(0 <= lx && lx < H && 0 <= ly && ly < W))continue;
                        if (grid[lx][ly] == 'X')continue;
                        if (grid[lx][ly] == 'T') {
                            ans = min(ans, cost);
                            continue;
                        }
                        if (dist[lx][ly][leg] > cost + (grid[lx][ly] - '0')) {
                            dist[lx][ly][leg] = cost + (grid[lx][ly] - '0');
                            pq.push({dist[lx][ly][leg], lx, ly, leg ^ 1});
                        }
                    }
                }
            }
        } else {
            for (int i = -3; i <= -1; i++) {
                for (int j = -2; j <= 2; j++) {
                    int lx = j + x, ly = i + y;
                    if (abs(lx - x) + abs(ly - y) <= 3) {
                        if (!(0 <= lx && lx < H && 0 <= ly && ly < W))continue;
                        if (grid[lx][ly] == 'X')continue;
                        if (grid[lx][ly] == 'T') {
                            ans = min(ans, cost);
                            continue;
                        }
                        if (dist[lx][ly][leg] > cost + (grid[lx][ly] - '0')) {
                            dist[lx][ly][leg] = cost + (grid[lx][ly] - '0');
                            pq.push({dist[lx][ly][leg], lx, ly, leg ^ 1});
                        }
                    }
                }
            }
        }
    }
//    for (int op = 0; op < 2; op++) {
//        for (int i = 0; i < H; i++) {
//            for (int j = 0; j < W; j++) {
//                cout << (dist[i][j][op] == INF ? -1 : dist[i][j][op]) << " ";
//            }
//            cout << endl;
//        }
//        cout << endl;
//    }

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

int main() {
    while (true) {
        cin >> W >> H;
        if (W == 0 && H == 0)break;
        solve();
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3552
final_rank: 7

code_snippet: // (⁠◕⁠ᴗ⁠◕⁠✿⁠)

// #pragma GCC target("avx2")
// #pragma GCC optimize("O3")
// #pragma GCC optimize("unroll-loops")
#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define srep(i, s, n) for (ll i = s; i < (n); i++)
#define len(x) ((int)(x).size())
#define all(x) (x).begin(), (x).end()
using namespace std;
template<typename T> using vc = vector<T>;
template<typename T> using vv = vc<vc<T>>;
template<typename T> using vvv = vv<vc<T>>;
using vi = vc<int>;using vvi = vv<int>; using vvvi = vv<vi>;
using ll = long long;using vl = vc<ll>;using vvl = vv<ll>; using vvvl = vv<vl>;
using ld = long double; using vld = vc<ld>; using vvld = vc<vld>; using vvvld = vc<vvld>;
using uint = unsigned int;
using ull = unsigned long long;
const ld pi = 3.141592653589793;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3f;
// const ll mod = 1000000007;
const ll mod = 998244353;
inline bool inside(ll y, ll x, ll H, ll W) {return 0 <= (y) and (y) < (H) and 0 <= (x) and (x) < (W); }

#define debug(var)  do{std::cout << #var << " : \n";view(var);}while(0)
template<typename T> void view(T e){cout << e << endl;}
template<typename T> void view(const vc<T>& v){for(const auto& e : v){ cout << e << " "; } cout << endl;}

int solve(int h, int w){
    vv<char> S(h, vc<char>(w)); rep(i, h) rep(j, w) cin >> S[i][j];
    vvvi dist(h, vvi(w, vi(2, inf)));
    using P = tuple<int, int, int, int>;
    priority_queue<P, vc<P>, greater<P>> q;
    rep(i, h) rep(j, w) if (S[i][j] == 'S'){
        q.push({0, i, j, 0});
        q.push({0, i, j, 1});
        dist[i][j][0] = 0;
        dist[i][j][1] = 0;
    }
    vi dx = {-2, -1, -1, 0, 0, 0, 1, 1, 2}, dy = {1, 1, 2, 1, 2, 3, 1, 2, 1};
    while (!q.empty()){
        auto [d, x, y, f] = q.top(); q.pop();
        if (dist[x][y][f] < d) continue;
        rep(k, 9){
            int nx = x + dx[k], ny = y + (f ? dy[k] : -dy[k]);
            if (inside(nx, ny, h, w) && S[nx][ny] != 'X' && S[nx][ny] != 'S'){
                if (S[nx][ny] == 'T') return dist[x][y][f];
                else if (dist[nx][ny][f ^ 1] > dist[x][y][f] + S[nx][ny] - '0'){
                    dist[nx][ny][f ^ 1] = dist[x][y][f] + S[nx][ny] - '0';
                    q.push({dist[nx][ny][f ^ 1], nx, ny, f ^ 1});
                }
            }
        }
    }
    return -1;
}

int main(){
    vc<int> ans;
    while (true){
        int w, h; cin >> w >> h;
        if (w == 0) break;
        ans.push_back(solve(h, w));
    }
    for (auto x : ans) cout << x << endl;
}
accuracy: 1
time_ms: 20
memory_kb: 3552
final_rank: 7

code_snippet: #include <bits/stdc++.h>

bool solve() {
    int W, H;
    std::cin >> W >> H;
    if (W == 0 and H == 0) {
        return false;
    }
    std::vector S(H, std::vector<char>(W, -1));
    for (int i{} ; i < H ; i++) {
        for (int j{} ; j < W ; j++) {
            std::cin >> S[i][j];
        }
    }
    auto in{[&](int x, int y) -> bool {
        return 0 <= x and x < H and 0 <= y and y < W;
    }};
    auto pos{[&](int x, int y) -> int {
        assert(in(x, y));
        return x * W + y;
    }};
    auto f{[&](int next, int lx, int ly, int rx, int ry) -> int {
        return next * (H * W * H * W) + pos(lx, ly) * (H * W) + pos(rx, ry);
    }};
    auto valid{[&](int lx, int ly, int rx, int ry) -> bool {
        if (!in(lx, ly)) return false;
        if (!in(rx, ry)) return false;
        if (S[lx][ly] == 'X') return false;
        if (S[rx][ry] == 'X') return false;
        if (ly >= ry) return false;
        if (std::abs(lx - rx) + std::abs(ly - ry) > 3) return false;
        return true;
    }};
    auto cost{[&](int x, int y) -> short {
        // assert(S[x][y] != 'X');
        if (S[x][y] == 'X') return (short)1e4;
        if (S[x][y] == 'S' or S[x][y] == 'T') return 0;
        return S[x][y] - '0';
    }};
    std::unordered_map<int, int> map;
    int N{};
    for (int lx{} ; lx < H ; lx++) {
        for (int ly{} ; ly < W ; ly++) {
            for (int rx{} ; rx < H ; rx++) {
                for (int ry{} ; ry < W ; ry++) {
                    if (!valid(lx, ly, rx, ry)) continue;
                    map[f(0, lx, ly, rx, ry)] = N++;
                    map[f(1, lx, ly, rx, ry)] = N++;
                }
            }
        }
    }
    std::vector g(N, std::vector<std::pair<int, short>>{});
    for (int lx{} ; lx < H ; lx++) {
        for (int ly{} ; ly < W ; ly++) {
            for (int rx{} ; rx < H ; rx++) {
                for (int ry{} ; ry < W ; ry++) {
                    if (!valid(lx, ly, rx, ry)) continue;
                    for (int dx{-3} ; dx <= 3 ; dx++) {
                        for (int dy{-3} ; dy <= 3 ; dy++) {
                            if (dx == 0 and dy == 0) continue;
                            int nlx{rx + dx}, nly{ry + dy};
                            if (valid(nlx, nly, rx, ry) and std::pair(lx, ly) != std::pair(nlx, nly)) {
                                // assert(nlx != lx or nly != ly);
                                // std::cout << "((" << lx + 1 << ',' << ly + 1 << "),(" << rx + 1 << ',' << ry + 1 << "))" << 
                                //      " -> ((" << nlx + 1 << ',' << nly + 1 << "),(" << rx + 1 << ',' << ry + 1 << "))" << std::endl;
                                g[map[f(0, lx, ly, rx, ry)]].emplace_back(map[f(1, nlx, nly, rx, ry)], cost(nlx, nly));
                            }
                            int nrx{lx + dx}, nry{ly + dy};
                            if (valid(lx, ly, nrx, nry) and std::pair(rx, ry) != std::pair(nrx, nry)) {
                                // assert(nrx != rx or nry != ry);
                                g[map[f(1, lx, ly, rx, ry)]].emplace_back(map[f(0, lx, ly, nrx, nry)], cost(nrx, nry));
                            }
                        }
                    }
                }
            }
        }
    }
    const short INF{(short)1e4};
    std::vector<short> dist(N, INF);
    using qt = std::pair<short, int>;
    std::priority_queue<qt, std::vector<qt>, std::greater<qt>> que;
    for (int lx{} ; lx < H ; lx++) {
        for (int ly{} ; ly < W ; ly++) {
            for (int rx{} ; rx < H ; rx++) {
                for (int ry{} ; ry < W ; ry++) {
                    if (!valid(lx, ly, rx, ry)) continue;
                    if (S[lx][ly] == 'S') {
                        // std::cout << lx << ' ' << ly << ' ' << rx << ' ' << ry << ' ' << cost(rx, ry) << std::endl;
                        dist[map[f(0, lx, ly, rx, ry)]] = cost(rx, ry);
                        que.emplace(cost(rx, ry), map[f(0, lx, ly, rx, ry)]);
                    }
                    if (S[rx][ry] == 'S') {
                        // std::cout << lx << ' ' << ly << ' ' << rx << ' ' << ry << ' ' << cost(lx, ly) << std::endl;
                        dist[map[f(1, lx, ly, rx, ry)]] = cost(lx, ly);
                        que.emplace(cost(lx, ly), map[f(1, lx, ly, rx, ry)]);
                    }
                }
            }
        }
    }
    while (que.size()) {
        auto [d, v]{que.top()};
        que.pop();
        if (dist[v] < d) continue;
        assert(dist[v] == d);
        for (auto [x, c] : g[v]) {
            if (dist[x] > d + c) {
                dist[x] = d + c;
                que.emplace(dist[x], x);
            }
        }
    }
    short ans{INF};
    for (int lx{} ; lx < H ; lx++) {
        for (int ly{} ; ly < W ; ly++) {
            for (int rx{} ; rx < H ; rx++) {
                for (int ry{} ; ry < W ; ry++) {
                    if (!valid(lx, ly, rx, ry)) continue;
                    // std::cout << lx + 1 << ' ' << ly + 1 << ' ' << rx + 1 << ' ' << ry + 1 << ' ' << f(0, lx, ly, rx, ry) << ' ' << f(1, lx, ly, rx, ry) << " -> " 
                    //     << dist[f(0 ,lx, ly, rx, ry)] << ' ' << dist[f(1, lx, ly, rx, ry)] << std::endl;
                    if (S[lx][ly] == 'T' or S[rx][ry] == 'T') {
                        ans = std::min(ans, dist[map[f(0, lx, ly, rx, ry)]]);
                        ans = std::min(ans, dist[map[f(1, lx, ly, rx, ry)]]);
                    }
                }
            }
        }
    }
    // std::cout << f(0, 5, 0, 7, 1) << ' ' << f(1, 5, 0, 7, 1) << std::endl;
    // for (auto x : g[f(0, 9, 0, 7, 1)]) std::cout << x.first << ' ' << x.second << std::endl;;
    // std::cout << std::endl;
    std::cout << (ans == INF ? -1 : ans) << '\n';
    return true;
}

int main() {
    std::cin.tie(nullptr)->sync_with_stdio(false);
    while (solve()) ;
}
accuracy: 1
time_ms: 2410
memory_kb: 7664
final_rank: 20

code_snippet: #include <bits/stdc++.h>
using namespace std;
using ll = long long;
using P = pair<ll, ll>;
#define rep(i, a, b) for(ll i = a; i < b; ++i)
#define rrep(i, a, b) for(ll i = a; i >= b; --i)
constexpr ll inf = 4e18;
struct SetupIO {
    SetupIO() {
        ios::sync_with_stdio(0);
        cin.tie(0);
        cout << fixed << setprecision(30);
    }
} setup_io;
int main(void) {
    constexpr int dx[2][9] = {
        {1, 1, 1, 1, 1, 2, 2, 2, 3},
        {-1, -1, -1, -1, -1, -2, -2, -2, -3},
    };
    constexpr int dy[2][9] = {
        {-2, -1, 0, 1, 2, -1, 0, 1, 0},
        {-2, -1, 0, 1, 2, -1, 0, 1, 0},
    };
    while(1) {
        int w, h;
        cin >> w >> h;
        if(w == 0 and h == 0) break;
        vector<vector<char>> c(h, vector<char>(w));
        rep(i, 0, h) {
            rep(j, 0, w) {
                cin >> c[i][j];
            }
        }
        rep(i, 0, h / 2) {
            swap(c[i], c[h - 1 - i]);
        }
        vector<vector<pair<int, int>>> g(2 * h * w);
        rep(i, 0, h) {
            rep(j, 0, w) {
                if(c[i][j] == 'X') continue;
                rep(k, 0, 2) {
                    int idx = k * h * w + i * w + j;
                    rep(l, 0, 9) {
                        int ni = i + dy[k][l], nj = j + dx[k][l];
                        if(0 <= ni and ni < h and 0 <= nj and nj < w and c[ni][nj] != 'X') {
                            int nidx = (1 - k) * h * w + ni * w + nj;
                            int cost = 0;
                            if(isdigit(c[ni][nj])) {
                                cost = c[ni][nj] - '0';
                            }
                            g[idx].push_back({nidx, cost});
                        }
                    }
                }
            }
        }
        vector<int> d(2 * h * w, 1e9);
        priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> pq;
        rep(i, 0, w) {
            if(c[0][i] == 'S') {
                d[i] = 0;
                pq.push({d[i], i});
                d[h * w + i] = 0;
                pq.push({d[h * w + i], h * w + i});
            }
        }
        while(!pq.empty()) {
            auto [dist, cur] = pq.top();
            pq.pop();
            if(d[cur] < dist) continue;
            for(const auto& [to, cost] : g[cur]) {
                if(d[to] > d[cur] + cost) {
                    d[to] = d[cur] + cost;
                    pq.push({d[to], to});
                }
            }
        }
        int ans = 1e9;
        rep(i, 0, w) {
            if(c[h - 1][i] == 'T') {
                ans = min(ans, d[(h - 1) * w + i]);
                ans = min(ans, d[h * w + (h - 1) * w + i]);
            }
        }
        if(ans == 1e9) {
            ans = -1;
        }
        cout << ans << '\n';
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3908
final_rank: 14

code_snippet: #include <iostream>
#include <tuple>
#include <queue>
#include <vector>
#include <algorithm>
using namespace std;

const int dy[9] = { 1, 1, 1, 1, 1, 2, 2, 2, 3 };
const int dx[9] = { -2, -1, 0, 1, 2, -1, 0, 1, 0 };
int H, W;
int V[69][69];
bool Goal[69][69];
bool Calced[2][2009][2009];
int Dist[2][2009][2009];

void Initialize() {
	for (int i = 0; i < 69; i++) {
		for (int j = 0; j < 69; j++) {
			V[i][j] = 0; Goal[i][j] = false;
		}
	}
}

int main() {
	while (true) {
		// Step 1. Input
		Initialize();
		cin >> W >> H; if (W == 0 && H == 0) break;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				char c; cin >> c;
				if (c == 'S') { V[i][j] = 0; }
				if (c == 'T') { V[i][j] = 0; Goal[i][j] = true; }
				if (c == 'X') { V[i][j] = 1000000; }
				if (c >= '1' && c <= '9') { V[i][j] = (c - '0'); }
			}
		}

		// Step 2. Dijkstra Init
		priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>, greater<tuple<int, int, int, int>>> Q;
		for (int i = 0; i <= H * W; i++) {
			for (int j = 0; j <= H * W; j++) {
				Dist[0][i][j] = 1000000; Calced[0][i][j] = false;
				Dist[1][i][j] = 1000000; Calced[1][i][j] = false;
			}
		}
		for (int i = 0; i < H * W; i++) {
			int px = i / W, py = i % W;
			if (V[px][py] != 0 || Goal[px][py] == true) continue;
			Dist[0][i][H * W] = 0; Q.push(make_tuple(0, 0, i, H * W));
			Dist[1][H * W][i] = 0; Q.push(make_tuple(0, 1, H * W, i));
		}

		// Step 3. Dijkstra
		while (!Q.empty()) {
			int pos1 = get<1>(Q.top());
			int pos2 = get<2>(Q.top()); int px = pos2 / W, py = pos2 % W;
			int pos3 = get<3>(Q.top()); int qx = pos3 / W, qy = pos3 % W;
			Q.pop();
			if (Calced[pos1][pos2][pos3] == true) continue;
			Calced[pos1][pos2][pos3] = true;
			for (int i = 0; i < 9; i++) {
				int rx = -1, ry = -1;
				if (pos1 == 0) { rx = px + dx[i]; ry = py + dy[i]; }
				if (pos1 == 1) { rx = qx - dx[i]; ry = qy - dy[i]; }
				if (rx < 0 || ry < 0 || rx >= H || ry >= W) continue;
				int nex1 = 1 - pos1;
				int nex2 = pos2; if (pos1 == 1) { nex2 = rx * W + ry; }
				int nex3 = pos3; if (pos1 == 0) { nex3 = rx * W + ry; }
				if (Dist[nex1][nex2][nex3] > Dist[pos1][pos2][pos3] + V[rx][ry]) {
					Dist[nex1][nex2][nex3] = Dist[pos1][pos2][pos3] + V[rx][ry];
					Q.push(make_tuple(Dist[nex1][nex2][nex3], nex1, nex2, nex3));
				}
			}
		}

		// Step 4. Output
		int Answer = 1000000;
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				for (int k = 0; k < H * W; k++) {
					if (Goal[i][j] == false) continue;
					Answer = min(Answer, Dist[0][i * W + j][k]);
					Answer = min(Answer, Dist[1][i * W + j][k]);
					Answer = min(Answer, Dist[0][k][i * W + j]);
					Answer = min(Answer, Dist[1][k][i * W + j]);
					if (Answer == 5) {
						Answer += 0;
					}
				}
			}
		}
		if (Answer == 1000000) cout << "-1" << endl;
		else cout << Answer << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 350
memory_kb: 42480
final_rank: 18

code_snippet: #include<iostream>
#include<string>
#include<vector>
#include<math.h>
#include<iomanip>
#include<algorithm>
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<bitset>
// #include<atcoder/all>

using namespace std;
// using namespace atcoder;
using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

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

int main(){
	while (true)
	{
		int w, h;
		cin >> w >> h;
		if (w == 0 && h == 0) {
			break;
		}
		
		vector<vector<vector<int>>> dp(h, vector<vector<int>>(w, vector<int>(2, 1000000000)));
		priority_queue<tuple<int, int, int, int>, vector<tuple<int, int, int, int>>, greater<tuple<int, int, int, int>>> q;
		vector<vector<char>> s;
		for (int i = 0; i < h; i++)
		{
			s.push_back(vector<char>());
			for (int j = 0; j < w; j++)
			{
				char c;
				cin >> c;
				s[i].push_back(c);
				if (c == 'S') {
					dp[i][j][0] = 0;
					dp[i][j][1] = 0;
					q.push(tuple<int, int, int, int>(0, i, j, 0));
					q.push(tuple<int, int, int, int>(0, i, j, 1));
				}
			}
		}
		int ans = -1;
		while (q.size() > 0)
		{
			auto [cur_dist, cur_x, cur_y, cur_step] = q.top();
			q.pop();
			if (s[cur_x][cur_y] == 'T') {
				ans = cur_dist;
				break;
			}
			for (int i = 0; i < 9; i++)
			{
				int next_x = cur_x + dx[i];
				int next_y = cur_y + (cur_step ? dy[i] : -dy[i]);
				int next_step = 1 - cur_step;
				if (next_x < 0) continue;
				if (h <= next_x) continue;
				if (next_y < 0) continue;
				if (w <= next_y) continue;
				if (s[next_x][next_y] == 'X') continue;
				if (s[next_x][next_y] == 'S') continue;
				if (s[next_x][next_y] == 'T') {
					if (dp[next_x][next_y][next_step] > cur_dist) {
						q.push(tuple<int, int, int, int>(cur_dist, next_x, next_y, next_step));
						dp[next_x][next_y][next_step] = cur_dist;
					}
					continue;
				}
				int next_dist = cur_dist + s[next_x][next_y] - '0';
				if (dp[next_x][next_y][next_step] > next_dist) {
					q.push(tuple<int, int, int, int>(next_dist, next_x, next_y, next_step));
					dp[next_x][next_y][next_step] = next_dist;
				}
			}
			
		}
		cout << ans << endl;
	}
	
}
accuracy: 1
time_ms: 20
memory_kb: 3524
final_rank: 6

code_snippet: #include <bits/stdc++.h>
using namespace std;


//---------------------------- テンプレゾーン --------------------------------//

const long long INF = 1000000010;
const long long INFL = 1000000000000000010;
const double MYPI = 3.14159265358979;
const double epsilon = 1e-10;



typedef long long ll;
typedef __int128_t lll;
typedef unsigned int uint;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<ll, ll> pl;
typedef vector<ll> vl;
typedef vector<vl> vvl;
typedef vector<vvl> vvvl;
typedef vector<double> vd;
typedef vector<vd> vvd;
typedef vector<vvd> vvvd;
typedef vector<bool> vb;
typedef vector<vb> vvb;
typedef vector<vvb> vvvb;
typedef vector<char> vc;
typedef vector<vc> vvc;
typedef vector<vvc> vvvc;
typedef vector<pl> vp;
typedef tuple<ll, ll, ll> tt;
typedef vector<tuple<ll, ll, ll>> vt;
typedef vector<string> vs;

#define overload3(a, b, c, d, ...) d
#define overload4(a, b, c, d, e, ...) e
#define overload5(a, b, c, d, e, f, ...) f
#define overload6(a, b, c, d, e, f, g, ...) g
#define pb push_back
#define eb emplace_back
#define MP make_pair
#define REP_0(n) for(int _=0;_<(n);_++)
#define REP_1(i, n) for(int i=0;i<(n);i++)
#define REP_2(i, l, r) for(int i=(l);i<(r);i++)
#define REP_3(i, l, r, d) for(int i=(l);i<(r);i+=(d))
#define REP(...) overload4(__VA_ARGS__, REP_3, REP_2, REP_1, REP_0)(__VA_ARGS__)
#define REPP(i, n) for(int i=1;i<=(n);i++)
#define RREP_1(i, n) for(int i=(n)-1;i>=0;i--)
#define RREP_2(i, l, r) for(int i=(r)-1;i>=(l);i--)
#define RREP_3(i, l, r, d) for(int i=(r)-1;i>=(l);i-=(d))
#define RREP(...) overload4(__VA_ARGS__, RREP_3, RREP_2, RREP_1)(__VA_ARGS__)
#define RREPP(i, n) for(int i=(n);i>0;i--)
#define EACH1(e, a) for(auto &e : a)
#define EACH2(x, y, a) for(auto &[x, y] : a)
#define EACH3(x, y, z, a) for(auto &[x, y, z] : a)
#define EACH(...) overload4(__VA_ARGS__, EACH3, EACH2, EACH1)(__VA_ARGS__)
#define ALL1(x) begin(x), end(x)
#define ALL2(x, a) begin(x), begin(x) + a
#define ALL3(x, a, b) begin(x) + a, begin(x) + b
#define ALL(...) overload3(__VA_ARGS__, ALL3, ALL2, ALL1)(__VA_ARGS__)
#define RALL1(i) (i).rbegin(), (i).rend()
#define RALL2(i, a) (i).rend() - a, (i).rend()
#define RALL3(i, a, b) (i).rend() - b, (i).rend() - a
#define RALL(...) overload3(__VA_ARGS__, RALL3, RALL2, RALL1)(__VA_ARGS__)
#define sz(x) (long long)x.size()
#define LB(a, x) (lower_bound(a.begin(), a.end(), x) - a.begin())
#define UB(a, x) (upper_bound(a.begin(), a.end(), x) - a.begin())
#define FLG(x, i) (((x)>>(i)) & 1)
#define CNTBIT(x) __builtin_popcountll(x)
#define TOPBIT(t) (t == 0 ? -1 : 63 - __builtin_clzll(t))
#define BTMBIT(t) (t == 0 ? 64 : __builtin_ctzll(t))
#define IN(x, a, b) ((a) <= (x) && (x) < (b))
#define INT(...) int __VA_ARGS__; input(__VA_ARGS__)
#define STR(...) string __VA_ARGS__; input(__VA_ARGS__)
#define CHAR(...) char __VA_ARGS__; input(__VA_ARGS__)
#define DBL(...) double __VA_ARGS__; input(__VA_ARGS__)
#define LD(...) long double __VA_ARGS__; input(__VA_ARGS__)
#define VL1(a, n) vector<long long> a(n); for(int I=0;I<(n);I++)cin >> a[I]
#define VL2(a, b, n) vector<long long> a(n), b(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I]
#define VL3(a, b, c, n) vector<long long> a(n), b(n), c(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I]
#define VL4(a, b, c, d, n) vector<long long> a(n), b(n), c(n), d(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I]
#define VL5(a, b, c, d, e, n) vector<long long> a(n), b(n), c(n), d(n), e(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I] >> e[I]
#define VL(...) overload6(__VA_ARGS__, VL5, VL4, VL3, VL2, VL1)(__VA_ARGS__)
#define VD1(a, n) vector<double> a(n); for(int I=0;I<(n);I++)cin >> a[I]
#define VD2(a, b, n) vector<double> a(n), b(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I]
#define VD3(a, b, c, n) vector<double> a(n), b(n), c(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I]
#define VD4(a, b, c, d, n) vector<double> a(n), b(n), c(n), d(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I]
#define VD5(a, b, c, d, e, n) vector<double> a(n), b(n), c(n), d(n), e(n); for(int I=0;I<(n);I++)cin >> a[I] >> b[I] >> c[I] >> d[I] >> e[I]
#define VD(...) overload6(__VA_ARGS__, VD5, VD4, VD3, VD2, VD1)(__VA_ARGS__)
#define VVL(a, n, m) vector<vector<long long> > a(n, vector<long long>(m)); for(int I=0;I<(n);I++)for(int J=0;J<(m);J++)cin >> a[I][J]
#define VVC(s, n, m) vector<vector<char> > s(n, vector<char>(m)); for(int I=0;I<(n);I++)for(int J=0;J<(m);J++)cin >> s[I][J]
#define VS(s, n) vector<string> s(n); for(int I=0;I<(n);I++)cin >> s[I];

template <typename T1, typename T2>
ostream &operator<<(ostream &os, const pair<T1, T2> &a){
  return os << a.first << " " << a.second;
}
template <typename T1, typename T2, typename T3>
ostream &operator<<(ostream &os, const tuple<T1, T2, T3> &a){
  return os << get<0>(a) << " " << get<1>(a) << " " << get<2>(a);
}

struct IoSetup{
  IoSetup() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout << fixed << setprecision(15);
  }
} iosetup;

#ifdef LOCAL
#  include <debug_print.hpp>
#  define debug(...) debug_print::multi_print(#__VA_ARGS__, __VA_ARGS__)
#else
#  define debug(...) (static_cast<void>(0))
#endif

template <typename T>
using minheap = priority_queue<T, vector<T>, greater<T>>;
 
template <typename T>
using maxheap = priority_queue<T>;

template<class... T>
void input(T&... a){
  (cin >> ... >> a);
}

template <typename... T>
constexpr auto min(T... a){
  return min(initializer_list<common_type_t<T...>>{a...});
}
template <typename... T>
constexpr auto max(T... a){
  return max(initializer_list<common_type_t<T...>>{a...});
}

template <typename T1, typename T2>
bool chmax(T1 &x, const T2 &y){
  return x < y ? x = y, true : false;
}
template <typename T1, typename T2>
bool chmin(T1 &x, const T2 &y){
  return x > y ? x = y, true : false;
}

void OUT(){cout << "\n";}

template <typename T, typename... Ts>
void OUT(const T &a, const Ts&... b){
  cout << a;
  (cout << ... << (cout << " ", b));
  cout << "\n";
}

template <typename T>
void OUT(const vector<T> &res){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] << " ";
  }
  cout << "\n";
}

template <typename T>
void OUT_(const T &a){
  cout << a << " ";
}

template <typename T>
void OUTN(const vector<T> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] + (T)margin << "\n";
  }
}

template <typename T>
void OUTN_(const vector<T> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    cout << res[i] + (T)margin << " ";
  }
  cout << "\n";
}

template <typename T>
void OUTNN(const vector<vector<T>> &res, long long margin = 0){
  for(int i=0;i<(int)res.size();i++){
    for(int j=0;j<(int)res[i].size();j++){
      cout << res[i][j] + (T)margin << " ";
    }
    cout << "\n";
  }
}

void YES(const bool &res = true, bool Capital = false){
  if(Capital) cout << (res ? "YES" : "NO") << "\n";
  else cout << (res ? "Yes" : "No") << "\n";
}

void FIRST(const bool &res = true, bool Capital = false){
  if(Capital) cout << (res ? "FIRST" : "SECOND") << "\n";
  else cout << (res ? "First" : "Second") << "\n";
}

template <typename T>
void DEC(vector<T> &a, long long dif = 1){
  for(auto &x : a)x -= (T)dif;
}
template <typename T>
void DEC(vector<T> &a, vector<T> &b, long long dif = 1){
  for(auto &x : a)x -= (T)dif;
  for(auto &x : b)x -= (T)dif;
}
template <typename T>
void DEC(vector<vector<T>> &a, long long dif = 1){
  for(auto &v : a)for(auto &x : v)x -= (T)dif;
}

template <typename T>
void INC(vector<T> &a, long long dif = 1){
  for(auto &x : a)x += (T)dif;
}
template <typename T>
void INC(vector<T> &a, vector<T> &b, long long dif = 1){
  for(auto &x : a)x += (T)dif;
  for(auto &x : b)x += (T)dif;
}
template <typename T>
void INC(vector<vector<T>> &a, long long dif = 1){
  for(auto &v : a)for(auto &x : v)x += (T)dif;
}

template <typename T>
T SUM(const vector<T> &a){
  return accumulate(a.begin(), a.end(), (T)0);
}
template <typename T>
T SUM(const vector<vector<T>> &a){
  T ret = 0;
  for(int i=0;i<(int)a.size();i++)ret += accumulate(a[i].begin(), a[i].end(), (T)0);
  return ret;
}

template <typename T>
T MAX(const vector<T> &a){
  return *max_element(a.begin(), a.end());
}
template <typename T>
T MAX(const vector<vector<T>> &a){
  T ret = -INFL;
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(ret < a[i][j])ret = a[i][j];
  return ret;
}

template <typename T>
int ARGMAX(const vector<T> &a){
  int ret = 0;
  for(int i=1;i<(int)a.size();i++)if(a[ret] < a[i])ret = i;
  return ret;
}
template <typename T>
pair<int, int> ARGMAX(const vector<vector<T>> &a){
  pair<int, int> ret = {0, 0};
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(a[ret.first][ret.second] < a[i][j])ret = {i, j};
  return ret;
}

template <typename T>
T MIN(const vector<T> &a){
  return *min_element(a.begin(), a.end());
}
template <typename T>
T MIN(const vector<vector<T>> &a){
  T ret = INFL;
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(ret > a[i][j])ret = a[i][j];
  return ret;
}

template <typename T>
int ARGMIN(const vector<T> &a){
  int ret = 0;
  for(int i=1;i<(int)a.size();i++)if(a[ret] > a[i])ret = i;
  return ret;
}
template <typename T>
pair<int, int> ARGMIN(const vector<vector<T>> &a){
  pair<int, int> ret = {0, 0};
  for(int i=0;i<(int)a.size();i++)for(int j=0;j<(int)a[i].size();j++)if(a[ret.first][ret.second] > a[i][j])ret = {i, j};
  return ret;
}

template <typename T>
int SIGN(const T &a){
  if(abs(a) < epsilon)return 0;
  return a > 0 ? 1 : -1;
}

template <typename T>
vector<T> UNIQ(vector<T> a){
  sort(a.begin(), a.end());
  a.erase(unique(a.begin(), a.end()), a.end());
  return a;
}

template <typename T>
vector<T> sorted(vector<T> a, bool Descending = false){
  sort(a.begin(), a.end());
  if(Descending)reverse(a.begin(), a.end());
  return a;
}

template <typename T>
vector<T> cumsum(const vector<T> &a){
  int n = (int)a.size();
  vector<T> ret(n+1, (T)0);
  for(int i=0;i<n;i++)ret[i+1] = ret[i] + a[i];
  return ret;
}
template <typename T>
vector<vector<T>> cumsum(const vector<vector<T>> &a){
  int n = (int)a.size(), m = (int)a[0].size();
  vector<vector<T>> ret(n+1, vector<T>(m+1, (T)0));
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)ret[i+1][j+1] = ret[i+1][j] + a[i][j];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)ret[i+1][j+1] += ret[i][j+1];
  return ret;
}
template <typename T>
vector<vector<vector<T>>> cumsum(const vector<vector<vector<T>>> &a){
  int n = (int)a.size(), m = (int)a[0].size(), l = (int)a[0][0].size();
  vector<vector<vector<T>>> ret(n+1, vector<vector<T>>(m+1, vector<T>(l+1, (T)0)));
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] = ret[i+1][j+1][k] + a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] += ret[i][j+1][k+1];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)ret[i+1][j+1][k+1] += ret[i+1][j][k+1];
  return ret;
}
template <typename T>
void cumsum_inplace(vector<T> &a){
  int n = (int)a.size();
  for(int i=0;i<n-1;i++)a[i+1] += a[i];
}
template <typename T>
void cumsum_inplace(vector<vector<T>> &a){
  int n = (int)a.size(), m = (int)a[0].size();
  for(int i=0;i<n-1;i++)for(int j=0;j<m;j++)a[i+1][j] += a[i][j];
  for(int i=0;i<n;i++)for(int j=0;j<m-1;j++)a[i][j+1] += a[i][j];
}
template <typename T>
void cumsum_inplace(vector<vector<vector<T>>> &a){
  int n = (int)a.size(), m = (int)a[0].size(), l = (int)a[0][0].size();
  for(int i=0;i<n-1;i++)for(int j=0;j<m;j++)for(int k=0;k<l;k++)a[i+1][j][k] += a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m-1;j++)for(int k=0;k<l;k++)a[i][j+1][k] += a[i][j][k];
  for(int i=0;i<n;i++)for(int j=0;j<m;j++)for(int k=0;k<l-1;k++)a[i][j][k+1] += a[i][j][k];
}

template< typename T = long long >
struct Edge {
  long long from, to;
  T cost;
  long long idx;
  Edge() = default;
  Edge(long long from, long long to, T cost = 1, long long idx = -1) : from(from), to(to), cost(cost), idx(idx) {}
  operator int() const { return to; }
};

template< typename T = long long >
struct Graph {
  vector< vector< Edge< T > > > g, ginv;
  vector<int> indeg, outdeg;
  long long es;
  Graph() = default;
  explicit Graph(long long n) : g(n), ginv(n), indeg(n, 0), outdeg(n, 0), es(0) {}
  size_t size() const {
    return g.size();
  }
  void add_directed_edge(long long from, long long to, T cost = 1) {
    indeg[to]++, outdeg[from]++;
    //ginv[to].emplace_back(to, from, cost, es);
    g[from].emplace_back(from, to, cost, es++);
  }
  void add_edge(long long from, long long to, T cost = 1) {
    indeg[from]++, outdeg[from]++, indeg[to]++, outdeg[to]++;
    g[from].emplace_back(from, to, cost, es);
    g[to].emplace_back(to, from, cost, es++);
  }
  inline vector< Edge< T > > &operator[](const int &k) {
    return g[k];
  }
  inline const vector< Edge< T > > &operator[](const int &k) const {
    return g[k];
  }
};

template< typename T = long long >
using Edges = vector< Edge< T > >;

template< typename T >
struct Enumeration {
private:
  static vector< T > _fact, _finv, _inv;
  inline static void expand(size_t sz) {
    if(_fact.size() < sz + 1) {
      int pre_sz = max(1, (int) _fact.size());
      _fact.resize(sz + 1, T(1));
      _finv.resize(sz + 1, T(1));
      _inv.resize(sz + 1, T(1));
      for(int i = pre_sz; i <= (int) sz; i++) {
        _fact[i] = _fact[i - 1] * T(i);
      }
      _finv[sz] = T(1) / _fact[sz];
      for(int i = (int) sz - 1; i >= pre_sz; i--) {
        _finv[i] = _finv[i + 1] * T(i + 1);
      }
      for(int i = pre_sz; i <= (int) sz; i++) {
        _inv[i] = _finv[i] * _fact[i - 1];
      }
    }
  }
public:
  explicit Enumeration(size_t sz = 0) { expand(sz); }
  static inline T fact(int k) {
    expand(k);
    return _fact[k];
  }
  static inline T finv(int k) {
    expand(k);
    return _finv[k];
  }
  static inline T inv(int k) {
    expand(k);
    return _inv[k];
  }
  static T P(int n, int r) {
    if(r < 0 || n < r) return 0;
    return fact(n) * finv(n - r);
  }
  static T C(int p, int q) {
    if(q < 0 || p < q) return 0;
    return fact(p) * finv(q) * finv(p - q);
  }
};

template< typename T >
vector< T > Enumeration< T >::_fact = vector< T >();
template< typename T >
vector< T > Enumeration< T >::_finv = vector< T >();
template< typename T >
vector< T > Enumeration< T >::_inv = vector< T >();

template <typename T>
T norm1(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return abs(a.first - b.first) + abs(a.second - b.second);
}
template <typename T>
T norm22(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return (a.first - b.first) * (a.first - b.first) + (a.second - b.second) * (a.second - b.second);
}
template <typename T>
double norm2(const pair<T, T> &a, const pair<T, T> &b = {(T)0, (T)0}){
  return sqrt(norm22(a, b));
}

long long powll(long long a, long long n){
  assert(n >= 0);
  if(n == 0)return 1;
  long long ret = 1;
  while(n){
    if(n & 1)ret *= a;
    a *= a;
    n >>= 1;
  }
  return ret;
}

vector<long long> str_to_vl(const string &s){
  vector<long long> ret(s.size());
  if(s.size() == 0)return ret;
  if(0 <= s[0]-'A' && s[0]-'A' < 26) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - 'A';
  else if(0 <= s[0]-'a' && s[0]-'a' < 26) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - 'a';
  else if(0 <= s[0]-'0' && s[0]-'0' < 10) for(int i=0;i<(int)s.size();i++) ret[i] = s[i] - '0';
  else assert(0);
  return ret;
}

// 0-indexed
long long TOPDIGIT(long long x){
  assert(x >= 0);
  long long ret = 0;
  while(x >= 10){x /= 10; ret++;}
  return ret;
}

template <typename T>
vector<pair<T, int>> sorti(const vector<T> &a){
  vector<pair<T, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}
template <typename T1, typename T2>
vector<tuple<T1, T2, int>> sorti(const vector<T1> &a, const vector<T2> &b){
  assert(a.size() == b.size());
  vector<tuple<T1, T2, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], b[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}
template <typename T1, typename T2, typename T3>
vector<tuple<T1, T2, T3, int>> sorti(const vector<T1> &a, const vector<T2> &b, const vector<T3> &c){
  assert(a.size() == b.size() && a.size() == c.size());
  vector<tuple<T1, T2, T3, int>> ret(a.size());
  for(int i=0;i<(int)a.size();i++){
    ret[i] = {a[i], b[i], c[i], i};
  }
  sort(ret.begin(), ret.end());
  return ret;
}

// 高々小数第 k 位までの実数を 10^k 倍して整数化
ll decimal_to_ll(const string &s, int k){
  int n = s.size();
  for(int i=0;i<n;i++){
    if(s[i] == '.'){
      ll ret = stoll(s.substr(0, i) + s.substr(i + 1));
      for(int j=0;j<k-(n-1-i);j++)ret *= 10;
      return ret;
    }
  }
  ll ret = stoll(s);
  for(int i=0;i<k;i++)ret *= 10;
  return ret;
}

long long max(const int &a, const long long &b){return max((long long)a, b);}
long long min(const int &a, const long long &b){return min((long long)a, b);}

const vector<long long> dy = {1, 0, -1, 0, 1, -1, -1, 1};
const vector<long long> dx = {0, 1, 0, -1, 1, 1, -1, -1};

random_device seed_gen;
mt19937_64 rnd;

// [low, high] の範囲の値を持つ長さ len のランダムベクトルを生成
vector<long long> random_vl(int len, long long low, long long high){
  uniform_int_distribution<long long> dist(low, high);
  vector<long long> ret(len);
  for(int i=0;i<len;i++)ret[i] = dist(rnd);
  return ret;
};

vector<long long> random_permutation(int len){
  uniform_int_distribution<int> dist(1, len);
  vector<long long> ret(len);
  set<int> se;
  for(int i=0;i<len;i++){
    int tmp = dist(rnd);
    while(se.count(tmp))tmp = dist(rnd);
    ret[i] = tmp;
    se.insert(ret[i]);
  }
  return ret;
};

//--------------------------- テンプレゾーン終 -------------------------------//

//----------------------------- コピペゾーン ---------------------------------//

/*
始点s　最短距離dist ひとつ前の頂点prev
最短経路を求めるときはコメントアウトを外してprevをいれる
計算量 O(|E|log|V|)
*/

template<typename T>
vector<T> Dijkstra(const Graph<T> &g, long long s /*, vl &prev*/){
  long long n = g.size();
  vector<T> dist(n, INFL);
  dist[s] = 0;
  priority_queue<pair<T, long long>, vector<pair<T, long long>>, greater<pair<T, long long>>> pq;
  pq.emplace(0, s);
  while(!pq.empty()){
    auto [d, v] = pq.top();
    pq.pop();
    if(dist[v] >= d){
      for(auto &e : g[v]){
        if(e.cost < 0)continue;
        if(dist[e.to] > dist[v] + e.cost){
          dist[e.to] = dist[v] + e.cost;
          pq.emplace(dist[e.to], e.to);
          //prev[e.to] = v;
        }
      }
    }
  }
  return dist;
}

//---------------------------- コピペゾーン終 --------------------------------//

#define int long long

void solve(){
  vl ans;
  while(1){
    INT(w, h);
    if(w == 0)break;
    VVC(c, h, w);
    vl s, t;
    REP(i, h)REP(j, w){
      if(c[i][j] == 'S')s.pb(j);
      if(c[i][j] == 'T')t.pb(j);
    }
    Graph g(h*w*2);
    REP(i, h)REP(j, w)REP(k, h)REP(l, w){
      if(c[i][j] == 'X' || c[k][l] == 'X')continue;
      ll cost = c[k][l] - '0';
      if(j < l && abs(i - k) + abs(j - l) <= 3){
        if(!IN(cost, 1, 10))cost = 0;
        g.add_directed_edge(i*w+j, k*w+l + h*w, cost);
      }
      if(j > l && abs(i - k) + abs(j - l) <= 3){
        if(!IN(cost, 1, 10))cost = 0;
        g.add_directed_edge(i*w+j + h*w, k*w+l, cost);
      }
    }
    ll res = INFL;
    EACH(v, s){
      auto dist = Dijkstra(g, (h-1) * w + v);
      EACH(u, t){
        chmin(res, dist[u]);
        chmin(res, dist[h*w + u]);
      }
      dist = Dijkstra(g, h*w + (h-1) * w + v);
      EACH(u, t){
        chmin(res, dist[u]);
        chmin(res, dist[h*w + u]);
      }
    }
    ans.pb(res == INFL ? -1 : res);
  }
  OUTN(ans);
}

int solve_test(int n, vl a){

  return 0;
}

int solve_naive(int n, vl a){

  return 0;
}

void random_test(){
  rnd.seed(seed_gen());

  uniform_int_distribution<int> dist_n(4, 10), dist_m(4, 10), dist_a(1, 20), dist_b(1, 20);  

  for(int test = 1; test <= 100; test++){
    int n = dist_n(rnd), m = dist_m(rnd);
    vl a = random_vl(n, 3, 20);
    auto Output = solve_test(n, a), Answer = solve_naive(n, a);
    if(Output != Answer){
      cout << "Wrong Answer on Test #" << test << '\n';
      debug(n);
      debug(a);
      debug(Answer);
      debug(Output);
      break;
    }
  }
}

signed main(){
  int T = 1;
  // cin >> T;

  while(T--) solve();

  // random_test();

  return 0;
}
accuracy: 1
time_ms: 500
memory_kb: 4772
final_rank: 16

code_snippet: #include <bits/stdc++.h>
using namespace std;

const pair<int,int>V[]={{2,1},{1,1},{1,2},{0,1},{0,2},{0,3},{-1,1},{-1,2},{-2,1}};
const int inf=1<<30;

bool solve(){
    int W,H;
    cin>>W>>H;
    if(W==0)return false;
    vector S(H,vector<char>(W));
    vector D(H,vector(W,vector<int>(2,inf)));
    priority_queue<tuple<int,int,int,int>,vector<tuple<int,int,int,int>>,greater<tuple<int,int,int,int>>>pq;
    vector<pair<int,int>>goal;
    for(int i=0;i<H;i++){
        for(int j=0;j<W;j++){
            cin>>S[i][j];
            if(S[i][j]=='S'){
                D[i][j][0]=0;
                D[i][j][1]=0;
                pq.push(make_tuple(0,i,j,0));
                pq.push(make_tuple(0,i,j,1));
            }else if(S[i][j]=='T'){
                goal.push_back(make_pair(i,j));
            }
        }
    }
    while(pq.size()){
        auto[c,x,y,t]=pq.top();
        pq.pop();
        if(D[x][y][t]<c)continue;
        for(auto[dx,dy]:V){
            if(t==1)dy=-dy;
            int ex=x+dx,ey=y+dy;
            if(0<=ex&&ex<H&&0<=ey&&ey<W&&S[ex][ey]!='X'){
                if(S[ex][ey]=='T'&&D[ex][ey][1-t]>c){
                    D[ex][ey][1-t]=c;
                    pq.push(make_tuple(D[ex][ey][1-t],ex,ey,1-t));
                }
                if('0'<=S[ex][ey]&&S[ex][ey]<='9'&&D[ex][ey][1-t]>c+S[ex][ey]-'0'){
                    D[ex][ey][1-t]=c+S[ex][ey]-'0';
                    pq.push(make_tuple(D[ex][ey][1-t],ex,ey,1-t));
                }
            }
        }
    }
    int ans=inf;
    for(auto[gx,gy]:goal){
        ans=min(ans,D[gx][gy][0]);
        ans=min(ans,D[gx][gy][1]);
    }
    if(ans==inf)cout<<-1<<"\n";
    else cout<<ans<<"\n";
    return true;
}

int main(){
    while(1){
        if(!solve()){
            return 0;
        }
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3512
final_rank: 5

code_snippet: #include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>

using namespace std;
using ll = long long;
using dat = pair<ll,pair<pair<int,int>,int>>;
int w,h;
void solve(){
    vector<vector<char>> a(h,vector<char>(w));
    for(int i = 0;i<h;i++) for(int j = 0;j<w;j++) cin>>a[i][j];
    vector<vector<vector<ll>>> dp(2,vector<vector<ll>>(h,vector<ll>(w,1e9)));
    priority_queue<dat,vector<dat>,greater<dat>> que;
    for(int i = 0;i<h;i++) for(int j = 0;j<w;j++){
        if(a[i][j]=='S') {
            dp[0][i][j] = dp[1][i][j] = 0;
            que.push(make_pair(0,make_pair(make_pair(i,j),0)));
            que.push(make_pair(0,make_pair(make_pair(i,j),1)));
        }
    }
    while(que.size()){
        auto now = que.top();
        que.pop();
        int ni = now.second.first.first;
        int nj = now.second.first.second;
        int t = now.second.second;
        if(dp[t][ni][nj]<now.first) continue;
        for(int i = 1;i<=3;i++){
            for(int j = -3;j<=3;j++){
                if(abs(i)+abs(j)>3) continue;
                int nni = ni + j;
                int nnj = nj;
                if(t==0) nnj += i;
                else nnj -= i;
                if(nni<0||nni>=h||nnj<0||nnj>=w) continue;
                if(a[nni][nnj]=='X') continue;
                int nxt = now.first;
                if('0'<=a[nni][nnj]&&a[nni][nnj]<='9') nxt += a[nni][nnj] - '0';
                int nt = t ^ 1;
                if(dp[nt][nni][nnj]>nxt){
                    que.push(make_pair(nxt,make_pair(make_pair(nni,nnj),nt)));
                    dp[nt][nni][nnj] = nxt;
                }
            }
        }
    }
    ll ans = 1e9;
    for(int i = 0;i<h;i++) for(int j = 0;j<w;j++) if(a[i][j]=='T') ans = min(ans,min(dp[0][i][j],dp[1][i][j]));
    if(ans==1e9) ans = -1;
    cout<<ans<<endl;
    

    
}

int main(){
    
    while(true){
        cin>>w>>h;
        if(w==0) break;
        solve();
    }
}
accuracy: 1
time_ms: 20
memory_kb: 3564
final_rank: 9