#include <bits/stdc++.h>
using namespace std;
char a[1001][1001];
bool visit[1001][1001] = {false};
pair<int, int> b[4] = {{0, 1}, {1, 0}, {-1, 0}, {0, -1}};
int minimum = 0;
int r, c;
struct place {
  int r;
  int c;
};
struct path {
  pair<int, int> place;
  int pathlen;
};
bool check(int row, int column) {
  return row >= 0 && row < r && column >= 0 && column < c;
}
int transform(char a) {
  if (a == '0') return 0;
  if (a == '1') return 1;
  if (a == '2') return 2;
  if (a == '3') return 3;
  if (a == '4') return 4;
  if (a == '5') return 5;
  if (a == '6') return 6;
  if (a == '7') return 7;
  if (a == '8') return 8;
  if (a == '9') return 9;
}
void seach(int row, int column) {
  int maxPathLenght = 1001 * 1001;
  queue<path> queue;
  queue.push({{row, column}, 0});
  visit[row][column] = true;
  while (!queue.empty()) {
    path current = queue.front();
    queue.pop();
    if (current.pathlen > maxPathLenght) {
      return;
    }
    if (a[current.place.first][current.place.second] == 'S') {
      maxPathLenght = current.pathlen;
    } else {
      if (a[current.place.first][current.place.second] != 'E') {
        minimum += transform(a[current.place.first][current.place.second]);
      }
    }
    for (int i = 0; i < 4; ++i) {
      int copyrow = current.place.first + b[i].first;
      int copycolumn = current.place.second + b[i].second;
      if (check(copyrow, copycolumn) && (!visit[copyrow][copycolumn]) &&
          (a[copyrow][copycolumn] != 'T')) {
        int newlen = current.pathlen + 1;
        visit[copyrow][copycolumn] = true;
        queue.push({{copyrow, copycolumn}, newlen});
      }
    }
  }
  return;
}
int main() {
  place start;
  cin >> r >> c;
  for (int i = 0; i < r; ++i)
    for (int j = 0; j < c; ++j) {
      cin >> a[i][j];
      if (a[i][j] == 'E') {
        start.c = j;
        start.r = i;
      }
    }
  seach(start.r, start.c);
  cout << minimum << endl;
  return 0;
}
