#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:200000000")
using namespace std;
template <typename T>
inline T Abs(T x) {
  return (x >= 0) ? x : -x;
}
template <typename T>
inline T sqr(T x) {
  return x * x;
}
template <typename T>
inline string toStr(T x) {
  stringstream st;
  st << x;
  string s;
  st >> s;
  return s;
}
template <typename T>
inline int bit(T mask, int b) {
  return (b >= 0 && (mask & (T(1) << b)) != 0) ? 1 : 0;
}
inline int nextInt() {
  int x;
  if (scanf("%d", &x) != 1) throw;
  return x;
}
inline long long nextInt64() {
  long long x;
  if (scanf("%lld", &x) != 1) throw;
  return x;
}
inline double nextDouble() {
  double x;
  if (scanf("%lf", &x) != 1) throw;
  return x;
}
const int INF = (int)1E9;
const long long INF64 = (long long)1E18;
const long double EPS = 1E-9;
const long double PI = 3.1415926535897932384626433832795;
const int dx[] = {-1, +1, 0, 0};
const int dy[] = {0, 0, -1, +1};
const int BOMB = -100000;
const int MAXM = 300;
const int MAXN = 30;
struct item {
  int x, y, cost;
  explicit item(int x, int y, int cost) : x(x), y(y), cost(cost) {}
  bool intersect(int x1, int YYY1, int x2, int y2) const {
    if (YYY1 != y2) return false;
    if (YYY1 >= y) return false;
    return min(x1, x2) < x && max(x1, x2) == x;
  }
};
int n, m, k, d[MAXN][MAXN][MAXM];
bool used[MAXN][MAXN][MAXM];
queue<int> qx, qy, qm;
vector<item> a;
string f[MAXN];
bool valid(int x, int y) {
  return (0 <= x && x < n) && (0 <= y && y < m) && f[x][y] == '.';
}
void update(int x, int y, int mask, int value) {
  if (d[x][y][mask] < value) {
    if (!used[x][y][mask]) {
      qm.push(mask);
      qx.push(x);
      qy.push(y);
    }
    used[x][y][mask] = true;
    d[x][y][mask] = value;
  }
}
int solve(int X, int Y) {
  memset(d, 225, sizeof d);
  update(X, Y, 0, 0);
  while (!qx.empty()) {
    int x = qx.front();
    qx.pop();
    int y = qy.front();
    qy.pop();
    int mask = qm.front();
    qm.pop();
    int value = d[x][y][mask];
    used[x][y][mask] = false;
    for (int dir = 0; dir < (int)(4); dir++) {
      int nx = x + dx[dir], ny = y + dy[dir], nmask = mask, nvalue = value - 1;
      if (valid(nx, ny)) {
        for (int i = 0; i < (int)(k); i++)
          if (a[i].intersect(x, y, nx, ny)) {
            nmask ^= 1 << i;
            if (bit(mask, i) == 1)
              nvalue -= a[i].cost;
            else
              nvalue += a[i].cost;
          }
        update(nx, ny, nmask, nvalue);
      }
    }
  }
  int ans = 0;
  for (int mask = 0; mask < (int)(1 << k); mask++) {
    int cur = d[X][Y][mask];
    for (int i = 0; i < (int)(k); i++)
      if (bit(mask, i) == 1 && a[i].cost == BOMB) cur = -INF;
    ans = max(ans, cur);
  }
  return ans;
}
int main() {
  n = nextInt();
  m = nextInt();
  int poss = 0;
  vector<int> pos(20);
  for (int i = 0; i < (int)(n); i++) {
    cin >> f[i];
    for (int j = 0; j < (int)(m); j++) {
      if (f[i][j] == 'B') {
        a.push_back(item(i, j, BOMB));
      }
      if (isdigit(f[i][j])) {
        pos[f[i][j] - '1'] = int(a.size());
        a.push_back(item(i, j, 0));
        poss++;
      }
    }
  }
  for (int i = 0; i < (int)(poss); i++) a[pos[i]].cost = nextInt();
  int ans = 0;
  k = int(a.size());
  for (int x = 0; x < (int)(n); x++)
    for (int y = 0; y < (int)(m); y++)
      if (f[x][y] == 'S') {
        f[x][y] = '.';
        ans = solve(x, y);
      }
  cout << ans << endl;
  return 0;
}
