#include <cstdio>
#include <queue>
#include <vector>

using namespace std;

const int INF = 1<<28;
int w, h;
int bd[32][32];
int cost[4];
int dist[32][32][4];

int dy[] = {0, 1, 0, -1};
int dx[] = {1, 0, -1, 0};

struct node {
  int y, x, dir, d;
  node(int y, int x, int dir, int d) : y(y), x(x), dir(dir), d(d) {}
  bool operator>(const node &n) const { return this->d > n.d; }
};

int solve() {
  for (int i = 0; i < 32; i++)
    for (int j = 0; j < 32; j++)
      for (int k = 0; k < 4; k++)
        dist[i][j][k] = INF;

  priority_queue<node, vector<node>, greater<node> > Q;
  Q.push(node(0, 0, 0, 0));
  dist[0][0][0] = 0;

  while (!Q.empty()) {
    int y = Q.top().y;
    int x = Q.top().x;
    int dir = Q.top().dir;
    int d = Q.top().d;
    Q.pop();

    if (d > dist[y][x][dir])
      continue;

    for (int i = 0; i < 4; i++) {
      int c = bd[y][x] == i ? 0 : cost[i];
      int k = (dir + i) % 4;
      int xt = x + dx[k];
      int yt = y + dy[k];
      int dt = d + c;

      if (yt < 0 || yt >= h || xt < 0 || xt >= w)
        continue;
      if (dist[yt][xt][k] > dt) {
        dist[yt][xt][k] = dt;
        Q.push(node(yt, xt, k, dt));
      }
    }
  }

  int ret = INF;
  for (int i = 0; i < 4; i++)
    ret = min(ret, dist[h-1][w-1][i]);
  return ret;
}

int main(int argc, char *argv[])
{
  while (~scanf(" %d %d", &w, &h)) {
    if (!w && !h)
      break;
    for (int i = 0; i < h; i++) {
      for (int j = 0; j < w; j++) {
        scanf(" %d", bd[i] + j);
      }
    }
    for (int i = 0; i < 4; i++)
      scanf(" %d", cost + i);
    int ret = solve();
    printf("%d\n", ret);
  }
  
  return 0;
}