#define _USE_MATH_DEFINES
#include <bits/stdc++.h>

using namespace std;

// repetition
#define FOR(i, a, b) for (int i = (a); i < (b); ++i)
#define rep(i, n) for (int i = 0; i < (int)(n); i++)

// container util
#define all(x) (x).begin(), (x).end()

// debug
#define dump(x) cerr << #x << " = " << (x) << endl;
#define debug(x)                                         \
  cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" \
       << " " << __FILE__ << endl;

// typedef
typedef long long lint;
typedef unsigned long long ull;
typedef complex<long double> Complex;
typedef pair<int, int> P;
typedef tuple<int, int, int> TP;
typedef vector<int> vec;
typedef vector<vec> mat;

// constant
const int MOD = (int)1e9 + 7;
const int INF = (int)1e18;
const int dx[] = {0, 1, 0, -1};
const int dy[] = {1, 0, -1, 0};
const int ddx[] = {0, 1, 1, 1, 0, -1, -1, -1};
const int ddy[] = {1, 1, 0, -1, -1, -1, 0, 1};

// conversion
inline int toInt(string s) {
  int v;
  istringstream sin(s);
  sin >> v;
  return v;
}
template <class T>
inline string toString(T x) {
  ostringstream sout;
  sout << x;
  return sout.str();
}

//
template <class T>
inline bool chmax(T& a, T b) {
  if (a < b) {
    a = b;
    return 1;
  }
  return 0;
}
template <class T>
inline bool chmin(T& a, T b) {
  if (a > b) {
    a = b;
    return 1;
  }
  return 0;
}
//

int w, h;
int s[33][33], c[6], dp[33][33][5];

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);

  while (cin >> w >> h && h != 0) {
    rep(y, h) rep(x, w) cin >> s[y][x];
    rep(i, 4) cin >> c[i];

    rep(y, h) rep(x, w) rep(k, 4) dp[y][x][k] = INF;
    dp[0][0][1] = 0;
    queue<TP> que;
    que.push(make_tuple(0, 0, 1));

    while (!que.empty()) {
      int x, y, dir;
      tie(x, y, dir) = que.front();
      que.pop();

      if (x == w - 1 && y == h - 1) continue;
      rep(i, 4) {
        int nx = x + dx[i];
        int ny = y + dy[i];
        if (nx < 0 || w <= nx || ny < 0 || h <= ny) continue;

        if (s[y][x] == 0) {  //もし床が直進で
          if (dir == i) {  //向いている向きと同じ方向に進みたいなら
            if (dp[ny][nx][i] <= dp[y][x][dir]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir]);
            que.push(make_tuple(nx, ny, i));
          } else {
            if (dir == (1 + i) % 4) {  //右折
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[1]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[1]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (2 + i) % 4) {  //反転
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[2]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[2]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (3 + i) % 4) {  //左折
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[3]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[3]);
              que.push(make_tuple(nx, ny, i));
            }
          }
        } else if (s[y][x] == 1) {   //もし床が右折で
          if (dir == (1 + i) % 4) {  //同じ方向に進みたいなら
            if (dp[ny][nx][i] <= dp[y][x][dir]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir]);
            que.push(make_tuple(nx, ny, i));
          } else {
            if (dir == i) {  //直進
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[0]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[0]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (2 + i) % 4) {  //反転
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[2]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[2]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (3 + i) % 4) {  //左折
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[3]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[3]);
              que.push(make_tuple(nx, ny, i));
            }
          }

        } else if (s[y][x] == 2) {   //反転
          if (dir == (2 + i) % 4) {  //同じ方向に進みたいなら
            if (dp[ny][nx][i] <= dp[y][x][dir]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir]);
            que.push(make_tuple(nx, ny, i));
          } else {
            if (dir == i) {  //直進
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[0]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[0]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (1 + i) % 4) {  //右折
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[1]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[1]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (3 + i) % 4) {  //左折
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[3]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[3]);
              que.push(make_tuple(nx, ny, i));
            }
          }

        } else if (s[y][x] == 3) {   //左折
          if (dir == (3 + i) % 4) {  //同じ方向に進みたいなら
            if (dp[ny][nx][i] <= dp[y][x][dir]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir]);
            que.push(make_tuple(nx, ny, i));
          } else {
            if (dir == i) {  //直進
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[0]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[0]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (1 + i) % 4) {  //右折
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[1]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[1]);
              que.push(make_tuple(nx, ny, i));
            } else if (dir == (2 + i) % 4) {  //反転
              if (dp[ny][nx][i] <= dp[y][x][dir] + c[2]) continue;
              chmin(dp[ny][nx][i], dp[y][x][dir] + c[2]);
              que.push(make_tuple(nx, ny, i));
            }
          }
        } else if (s[y][x] == 4) {
          if (dir == i) {  //直進
            if (dp[ny][nx][i] <= dp[y][x][dir] + c[0]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir] + c[0]);
            que.push(make_tuple(nx, ny, i));
          } else if (dir == (1 + i) % 4) {  //右折
            if (dp[ny][nx][i] <= dp[y][x][dir] + c[1]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir] + c[1]);
            que.push(make_tuple(nx, ny, i));
          } else if (dir == (2 + i) % 4) {  //反転
            if (dp[ny][nx][i] <= dp[y][x][dir] + c[2]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir] + c[2]);
            que.push(make_tuple(nx, ny, i));
          } else if (dir == (3 + i) % 4) {  //左折
            if (dp[ny][nx][i] <= dp[y][x][dir] + c[3]) continue;
            chmin(dp[ny][nx][i], dp[y][x][dir] + c[3]);
            que.push(make_tuple(nx, ny, i));
          }
        }

      }  // rep
    }

    int ans = INF;
    rep(i, 4) ans = min(ans, dp[h - 1][w - 1][i]);
    cout << ans << "\n";
  }

  return 0;
}


Measured memory_bytes: 3156