#include <iostream>
#include <queue>
#include <unordered_set>

struct Action {
	size_t x;
	size_t y;
	size_t cost;
	bool left_foot_on;
};

bool operator>(Action lhs, Action rhs) {
	return lhs.cost > rhs.cost;
}

bool operator==(Action lhs, Action rhs) {
	return lhs.x == rhs.x && lhs.y == rhs.y && lhs.left_foot_on == rhs.left_foot_on;
}

namespace std {
	template <>
	struct hash<Action> {
		using result_type = size_t;

		result_type operator()(const Action& act) const {
			return act.x * 31 + act.y * 12 + act.left_foot_on * 7;
		}
	};
}

class Climber {
private:
	using candidates_t = std::priority_queue<Action, std::vector<Action>, std::greater<Action>>;

	size_t _width;
	size_t _height;
	std::string* _cliff;
	candidates_t _candidates;
	std::unordered_set<Action> _traversed;

	char get(size_t x, size_t y);
	void try_put_candidate(const Action& now, size_t x, size_t y);
	void put_candidate(size_t x, size_t y, size_t cost, bool left_foot_on);
public:
	Climber(size_t width, size_t height);
	void load();
	int climb();
};

Climber::Climber(size_t width, size_t height) : _width(width), _height(height) { }

void Climber::load() {
	_cliff = new std::string[_height];
	for (size_t y = 0; y < _height; ++y) {
		std::string line;
		for (size_t x = 0; x < _width; ++x) {
			char a;
			std::cin >> a;
			line += a;
		}
		_cliff[y] = line;
	}
}

int Climber::climb() {
	// ??????????????????S????????????????¶????????¶???????????????????????????????
	for (size_t y = 0; y < _height; ++y) {
		for (size_t x = 0; x < _width; ++x) {
			if (get(x, y) == 'S') {
				put_candidate(x, y, 0, false);
				put_candidate(x, y, 0, true);
			}
		}
	}
	// ???????°???????????????????????????????????????????????????????????????????
	while (!_candidates.empty()) {
		const Action now = _candidates.top();
		if (get(now.x, now.y) == 'T') {
			return now.cost;
		}
		_candidates.pop();
#ifdef _DEBUG
		//std::cerr << "(" << now.x << "," << now.y << ")->" << now.cost << " [" << now.left_foot_on << "]\n";
#endif
		if (now.left_foot_on) {
			try_put_candidate(now, now.x + 1, now.y - 2);
			try_put_candidate(now, now.x + 1, now.y - 1);
			try_put_candidate(now, now.x + 1, now.y);
			try_put_candidate(now, now.x + 1, now.y + 1);
			try_put_candidate(now, now.x + 1, now.y + 2);
			try_put_candidate(now, now.x + 2, now.y - 1);
			try_put_candidate(now, now.x + 2, now.y);
			try_put_candidate(now, now.x + 2, now.y + 1);
			try_put_candidate(now, now.x + 3, now.y);
		} else {
			try_put_candidate(now, now.x - 1, now.y - 2);
			try_put_candidate(now, now.x - 1, now.y - 1);
			try_put_candidate(now, now.x - 1, now.y);
			try_put_candidate(now, now.x - 1, now.y + 1);
			try_put_candidate(now, now.x - 1, now.y + 2);
			try_put_candidate(now, now.x - 2, now.y - 1);
			try_put_candidate(now, now.x - 2, now.y);
			try_put_candidate(now, now.x - 2, now.y + 1);
			try_put_candidate(now, now.x - 3, now.y);
		}
	}
	// ????????????????????£???
	return -1;
}

void Climber::try_put_candidate(const Action& now, size_t x, size_t y) {
	char type = get(x, y);
	if (type == 'S' || type == 'X' || type == '\0') {
		return; // type==S??????????????????????????????????????????????§????????????????????????????????????????????????????
	}
	int additionalCost;
	if (type == 'T') {
		additionalCost = 0; // ????????§??????????????????
	} else {
		additionalCost = type - '0';
	}
	put_candidate(x, y, now.cost + additionalCost, !now.left_foot_on);
}

char Climber::get(size_t x, size_t y) {
	if (x >= _width || y >= _height) {
		return '\0'; // invalid range
	}
	return _cliff[y][x];
}

void Climber::put_candidate(size_t x, size_t y, size_t cost, bool left_foot_on) {
	Action a{x, y, cost, left_foot_on};
	auto alreadyTraversed = _traversed.find(a);
	if (alreadyTraversed == _traversed.end() || alreadyTraversed->cost > cost) {
		_traversed.emplace(a);
		_candidates.emplace(std::move(a));
	}
}

int main() {
	size_t width, height;
	while (true) {
		std::cin >> width >> height;
		if (width == 0 || height == 0) {
			break;
		}
		Climber climber(width, height);
		climber.load();
		std::cout << climber.climb() << std::endl;
	}
}

Measured memory_bytes: 3600