#include <bits/stdc++.h>
using namespace std;
const int MAXN = 20;
const int INF = 0x3f3f3f3f;
const int MAXBIT = 10;
struct Node {
  int x, y, status;
};
int n, m, sx, sy;
bool wall[MAXN + 10][MAXN + 10], obj[MAXN + 10][MAXN + 10];
int val[MAXN + 10][MAXN + 10], id[MAXN + 10][MAXN + 10], cnt;
char s[MAXN + 10];
int dp[MAXN + 10][MAXN + 10][1 << MAXBIT];
int w[MAXN + 10];
queue<Node> Q;
void change(int& status, int x, int y) {
  for (int i = x; i >= 1; --i)
    if (obj[i][y]) status ^= 1 << id[i][y];
}
Node get(Node& a, int ax, int ay) {
  Node b = a;
  b.x += ax;
  b.y += ay;
  if (ay) change(b.status, b.x, min(b.y, b.y - ay));
  return b;
}
void update(const Node& a, const Node& b) {
  if (dp[a.x][a.y][a.status] + 1 < dp[b.x][b.y][b.status]) {
    dp[b.x][b.y][b.status] = dp[a.x][a.y][a.status] + 1;
    Q.push(b);
  }
}
int main() {
  scanf("%d%d", &n, &m);
  int tot = 0, x[MAXN + 10] = {0}, y[MAXN + 10] = {0};
  for (int i = 1; i <= n; ++i) {
    scanf("%s", s + 1);
    for (int j = 1; j <= m; ++j) {
      switch (s[j]) {
        case 'S':
          sx = i;
          sy = j;
          break;
        case '#':
          wall[i][j] = true;
          break;
        case 'B':
          wall[i][j] = true;
          obj[i][j] = true;
          val[i][j] = -INF;
          break;
        case '.':
          break;
        default:
          wall[i][j] = true;
          obj[i][j] = true;
          ++tot;
          x[s[j] - '0'] = i;
          y[s[j] - '0'] = j;
          break;
      }
    }
  }
  for (int i = 1; i <= tot; ++i) scanf("%d", &val[x[i]][y[i]]);
  for (int i = 1; i <= n; ++i)
    for (int j = 1; j <= m; ++j)
      if (val[i][j]) {
        id[i][j] = ++cnt;
        w[cnt] = val[i][j];
      }
  Q.push((Node){sx, sy, 0});
  memset(dp, 0x3f, sizeof dp);
  dp[sx][sy][0] = 0;
  while (!Q.empty()) {
    Node x = Q.front();
    Q.pop();
    if (x.x < n && !wall[x.x + 1][x.y]) {
      Node y = get(x, 1, 0);
      update(x, y);
    }
    if (x.x > 1 && !wall[x.x - 1][x.y]) {
      Node y = get(x, -1, 0);
      update(x, y);
    }
    if (x.y < m && !wall[x.x][x.y + 1]) {
      Node y = get(x, 0, 1);
      update(x, y);
    }
    if (x.y > 1 && !wall[x.x][x.y - 1]) {
      Node y = get(x, 0, -1);
      update(x, y);
    }
  }
  int ans = 0;
  for (int i = (1 << (cnt + 1)) - 1; i >= 0; --i) {
    if (dp[sx][sy][i] >= INF) continue;
    int res = 0;
    bool flag = true;
    for (int j = 1; j <= cnt; ++j) {
      if (i & (1 << j)) {
        if (w[j] <= -INF) {
          flag = false;
          break;
        }
        res += w[j];
      }
    }
    if (!flag) continue;
    res -= dp[sx][sy][i];
    ans = max(ans, res);
  }
  printf("%d", ans);
  return 0;
}
