// Original C++ solution (slower):
#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <climits>

#include <iostream>

#include <vector>

#include <string>

#include <sstream>

#include <algorithm>

#include <utility>

#include <set>

#include <map>

#include <stack>

#include <queue>

#include <deque>

#include <functional>



using namespace std;



#define fst first

#define scd second

#define PB push_back

#define MP make_pair

#define int long long

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

#define rall(a) a.rbegin(),a.rend()

#define omajinai ios::sync_with_stdio(false);cin.tie(0)



typedef long long ll;

typedef long double ld;

typedef vector<int> vi;

typedef vector<vi> vvi;

typedef pair<int, int> pii;

typedef vector<pii> vpii;



template<typename T>T& max(T&a,T&b){if(a>=b)return a;return b;}

template<typename T>T& min(T&a,T&b){if(a<b)return a;return b;}

template<typename T>bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}

template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}

template<typename T>T get(){T a;cin>>a;return a;}

template<typename T>T rev(T a){reverse(all(a));return a;}

template<typename T>vector<T>&sort(vector<T>&a){sort(all(a));return a;}



const int inf = 1e9;

const ll linf = 3e18;

const double eps = 1e-9;



struct to {

    int type, x, y;

    to(int type, int y, int x):type(type),y(y),x(x){}

    bool operator<(const to& t) const {

        return type < t.type;

    }

};

struct edge {

    to t; int cost;

    edge(to t, int cost):t(t),cost(cost){}

};



vector<edge> G[2][61][31];

int d[2][61][31];



char fld[62][32];



int dx[9] = {1, 1, 1, 1, 1, 2, 2, 2, 3};

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



int W, H;



bool inside(int h, int w)

{

    return (0 <= h && h < H && 0 <= w && w < W);

}



void build_graph()

{

    for (int i = 0; i < H; ++i) {

        for (int j = 0; j < W; ++j) {

            if (fld[i][j] == 'T' || fld[i][j] == 'X') continue;



            for (int k = 0; k < 9; ++k) {

                int y = i + dy[k], ax = j + dx[k], bx = j + dx[k] * -1;



                if (inside(y, ax) && fld[y][ax] != 'X') {

                    int cost = (isdigit(fld[y][ax]) ? fld[y][ax] - '0' : 0);

                    G[0][i][j].push_back(edge(to(1, y, ax), cost));

                }

                

                if (inside(y, bx) && fld[y][bx] != 'X') {

                    int cost = (isdigit(fld[y][bx]) ? fld[y][bx] - '0' : 0);

                    G[1][i][j].push_back(edge(to(0, y, bx), cost));

                }

            }

        }

    }

}



void dijkstra(to s)

{

    typedef pair<int, to> P;



    for (int i = 0; i < 2; ++i) for (int j = 0; j < H; ++j) for (int k = 0; k < W; ++k) {

        d[i][j][k] = inf;

    }



    priority_queue<P, vector<P>, greater<P> > q;

    q.push(P(0, to(s.type, s.y, s.x)));



    d[s.type][s.y][s.x] = 0;



    while (q.size()) {

        P p = q.top();

        q.pop();



        to t = p.scd;

        

        if (p.fst > d[t.type][t.y][t.x]) continue;



        for (int i = 0; i < G[t.type][t.y][t.x].size(); ++i) {

            edge e = G[t.type][t.y][t.x][i];



            if (d[e.t.type][e.t.y][e.t.x] > d[t.type][t.y][t.x] + e.cost) {

                d[e.t.type][e.t.y][e.t.x] = d[t.type][t.y][t.x] + e.cost;

                q.push(P(d[e.t.type][e.t.y][e.t.x], e.t));

            }

        }

    }

}

signed main()

{

    while (scanf("%d%d", &W, &H), W) {

        for (int i = 0; i < 2; ++i) for (int j = 0; j < H; ++j) for (int k = 0; k < W; ++k) {

            G[i][j][k].clear();

        }



        for (int i = 0; i < H; ++i) {

            for (int j = 0; j < W; ++j) {

                scanf("\n%c", &fld[i][j]);

            }

        }



        build_graph();



        int mi = inf;



        for (int i = 0; i < W; ++i) {

            if (fld[H - 1][i] == 'S') {

                for (int j = 0; j < 2; ++j) {

                    dijkstra(to(j, H - 1, i));

                    for (int k = 0; k < W; ++k) {

                        if (fld[0][k] == 'T') {

                            chmin(mi, min(d[j][0][k], d[j^1][0][k]));

                        }

                    }

                }

            }

        }



        printf("%d\n", mi == inf ? -1 : mi);

    }

}

// Optimized solution to the same problem (faster):
#include <cstdio>

#include <cstdlib>

#include <cstring>

#include <cmath>

#include <climits>

#include <iostream>

#include <vector>

#include <string>

#include <sstream>

#include <algorithm>

#include <utility>

#include <set>

#include <map>

#include <stack>

#include <queue>

#include <deque>

#include <functional>



using namespace std;



#define fst first

#define scd second

#define PB push_back

#define MP make_pair

#define int long long

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

#define rall(a) a.rbegin(),a.rend()

#define omajinai ios::sync_with_stdio(false);cin.tie(0)



typedef long long ll;

typedef long double ld;

typedef vector<int> vi;

typedef vector<vi> vvi;

typedef pair<int, int> pii;

typedef vector<pii> vpii;



template<typename T>T& max(T&a,T&b){if(a>=b)return a;return b;}

template<typename T>T& min(T&a,T&b){if(a<b)return a;return b;}

template<typename T>bool chmax(T&a,T b){if(a<b){a=b;return true;}return false;}

template<typename T>bool chmin(T&a,T b){if(a>b){a=b;return true;}return false;}

template<typename T>T get(){T a;cin>>a;return a;}

template<typename T>T rev(T a){reverse(all(a));return a;}

template<typename T>vector<T>&sort(vector<T>&a){sort(all(a));return a;}



const int inf = 1e9;

const ll linf = 3e18;

const double eps = 1e-9;



struct to {

    int type, x, y;

    to(int type, int y, int x):type(type),y(y),x(x){}

    bool operator<(const to& t) const {

        return type < t.type;

    }

};

struct edge {

    to t; int cost;

    edge(to t, int cost):t(t),cost(cost){}

};



vector<edge> G[2][61][31];

int d[2][61][31];



char fld[62][32];



int dx[9] = {1, 1, 1, 1, 1, 2, 2, 2, 3};

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



int W, H;



bool inside(int h, int w)

{

    return (0 <= h && h < H && 0 <= w && w < W);

}



void build_graph()

{

    for (int i = 0; i < H; ++i) {

        for (int j = 0; j < W; ++j) {

            if (fld[i][j] == 'T' || fld[i][j] == 'X') continue;



            for (int k = 0; k < 9; ++k) {

                int y = i + dy[k], ax = j + dx[k], bx = j + dx[k] * -1;



                if (inside(y, ax) && fld[y][ax] != 'X') {

                    int cost = (isdigit(fld[y][ax]) ? fld[y][ax] - '0' : 0);

                    G[0][i][j].push_back(edge(to(1, y, ax), cost));

                }

                

                if (inside(y, bx) && fld[y][bx] != 'X') {

                    int cost = (isdigit(fld[y][bx]) ? fld[y][bx] - '0' : 0);

                    G[1][i][j].push_back(edge(to(0, y, bx), cost));

                }

            }

        }

    }

}



void dijkstra(to s)

{

    typedef pair<int, to> P;



    priority_queue<P, vector<P>, greater<P> > q;



    q.push(P(0, to(s.type, s.y, s.x)));



    d[s.type][s.y][s.x] = 0;



    while (q.size()) {

        P p = q.top();

        q.pop();



        to t = p.scd;

        

        if (p.fst > d[t.type][t.y][t.x]) continue;



        for (int i = 0; i < G[t.type][t.y][t.x].size(); ++i) {

            edge e = G[t.type][t.y][t.x][i];



            if (d[e.t.type][e.t.y][e.t.x] > d[t.type][t.y][t.x] + e.cost) {

                d[e.t.type][e.t.y][e.t.x] = d[t.type][t.y][t.x] + e.cost;

                q.push(P(d[e.t.type][e.t.y][e.t.x], e.t));

            }

        }

    }

}

signed main()

{

    while (scanf("%d%d", &W, &H), W) {

        for (int i = 0; i < 2; ++i) for (int j = 0; j < H; ++j) for (int k = 0; k < W; ++k) {

            G[i][j][k].clear();

            d[i][j][k] = inf;

        }





        for (int i = 0; i < H; ++i) {

            for (int j = 0; j < W; ++j) {

                scanf("\n%c", &fld[i][j]);

            }

        }



        build_graph();



        for (int i = 0; i < W; ++i) {

            if (fld[H - 1][i] == 'S') {

                for (int j = 0; j < 2; ++j) {

                    dijkstra(to(j, H - 1, i));

                }

            }

        }



        int mi = inf;



        for (int i = 0; i < W; ++i) {

            if (fld[0][i] == 'T') {

                chmin(mi, min(d[0][0][i], d[1][0][i]));

            }

        }



        printf("%d\n", mi == inf ? -1 : mi);

    }

}

// Fastest known solution for this problem: