#include <bits/stdc++.h>
static constexpr int MAXN = 1010;
int main(int argc, const char** argv) {
  int rows, cols;
  std::scanf("%d %d\n", &rows, &cols);
  static char grid[MAXN][MAXN];
  std::pair<int, int> start, end;
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      grid[i][j] = std::getchar();
      if (grid[i][j] == 'S') start = std::pair<int, int>(i, j);
      if (grid[i][j] == 'E') end = std::pair<int, int>(i, j);
    }
    std::getchar();
  }
  std::queue<std::pair<int, int> > nodes;
  static bool vis[MAXN][MAXN];
  static int dists[MAXN][MAXN];
  std::memset(dists, -1, MAXN * MAXN * sizeof(int));
  nodes.push(end);
  vis[end.first][end.second] = true;
  dists[end.first][end.second] = 0;
  while (!nodes.empty()) {
    const std::pair<int, int> last = nodes.front();
    nodes.pop();
    const int dx[4] = {1, -1, 0, 0};
    const int dy[4] = {0, 0, 1, -1};
    for (int i = 0; i < 4; i++) {
      const std::pair<int, int> next =
          std::pair<int, int>(last.first + dx[i], last.second + dy[i]);
      if (next.first < 0 || next.first >= rows || next.second < 0 ||
          next.second >= cols)
        continue;
      if (vis[next.first][next.second]) continue;
      if (grid[next.first][next.second] == 'T') continue;
      vis[next.first][next.second] = true;
      dists[next.first][next.second] = 1 + dists[last.first][last.second];
      nodes.push(next);
    }
  }
  const int shortest = dists[start.first][start.second];
  assert(shortest != -1 && "Guaranteed to be able to reach exit.");
  int battles = 0;
  for (int i = 0; i < rows; i++) {
    for (int j = 0; j < cols; j++) {
      if (grid[i][j] < '0' || grid[i][j] > '9') continue;
      const int dist = dists[i][j];
      if (dist != -1 && dist <= shortest) {
        battles += grid[i][j] - '0';
      }
    }
  }
  std::printf("%d\n", battles);
  return EXIT_SUCCESS;
}
