#include<iostream>
#include<vector>
#include<map>
#include<queue>
#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define Gr(y,x,compass) G[index(y,x,compass)]
using namespace std;

const int HMAX = 32, WMAX = 32, VMAX = 6 * HMAX * WMAX;
const int INF = 1e6;

int w, h;
int s[HMAX][WMAX];
int c[4];
vector<pair<int,int> > G[VMAX];
int node_cost[VMAX];

const int NORTH=0, EAST=1, SOURTH=2, WEST=3;

int left(int compass) { return (compass + 3) % 4; }
int back(int compass) { return (compass + 2) % 4; }
int right(int compass) { return (compass + 1) % 4; }

pair<int,int> step(int y, int x, int compass) {
  int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
  return make_pair(y + dy[compass], x + dx[compass]);
}

bool in_field(int y, int x, int dir) {
  pair<int,int> p = step(y,x,dir);
  return  (0 <= p.first and p.first < h and
           0 <= p.second and p.second < w);
}

int index(int y, int x, int compass) {
  return compass * w * h + y * w + x;
}

const int STRAIGHT=0, RIGHT=1, BACK=2, LEFT=3;
int cost(int y, int x, int command) {
  return (s[y][x] == command ? 0 : c[command]);
}

void calculate_cost() {
  int dx[4] = {0,1,0,-1}, dy[4] = {-1,0,1,0};
  REP(compass, 4) REP(y,h) REP(x,w) {
    int d = compass;
    if (in_field(y,x,d)) {
      Gr(y,x,compass).push_back(
        make_pair(cost(y,x,STRAIGHT), index(y+dy[d],x+dx[d],d)));
    }

    d = left(compass);
    if (in_field(y,x,d)) {
      Gr(y,x,compass).push_back(
        make_pair(cost(y,x,LEFT), index(y+dy[d],x+dx[d],d)));
    }

    d = back(compass);
    if (in_field(y,x,d)) {
      Gr(y,x,compass).push_back(
        make_pair(cost(y,x,BACK), index(y+dy[d],x+dx[d],d)));
    }

    d = right(compass);
    if (in_field(y,x,d)) {
      Gr(y,x,compass).push_back(
        make_pair(cost(y,x,RIGHT), index(y+dy[d],x+dx[d],d)));
    }
  }
}

int dijkstra() {
  priority_queue<pair<int,int> > q;
  q.push(make_pair(0,index(0,0,EAST)));
  while (not q.empty()) {
    pair<int,int> current = q.top(); q.pop();
    int current_cost = current.first,
        current_idx = current.second;
    for (pair<int,int> p : G[current_idx]) {
      int edge_cost = p.first, destination = p.second;
/*      cout << current_idx << "->" << destination
        << "(" << node_cost[destination] << "vs." << current_cost
        << "+" << edge_cost << ")" << endl;*/
      if (node_cost[destination] <= current_cost + edge_cost) 
        continue;

      node_cost[destination] = current_cost + edge_cost;
      q.push(make_pair(node_cost[destination], destination));
    }
  }
  
  int ans = INF;
  REP(i, 4) {
    ans = min(ans, node_cost[index(h-1,w-1,i)]);
  }
  return ans;
}

void init() {
  REP(y, h) REP(x,w) REP(compass,4) {
    node_cost[index(y,x,compass)] = INF;
  }
  REP(i, 4 * w * h) {
    G[i].clear();
  }
}

int main() {
  while (cin >> w >> h and h) {
    init();
    REP(y,h) REP(x,w) { cin >> s[y][x]; }
    REP(i,4) { cin >> c[i]; }
  
    calculate_cost();
/*    REP(i, 4 * w * h) {
      cout << "G[" << i << "]=<";
      REP(j, G[i].size()) {
          cout << "(" << G[i][j].first << "," << G[i][j].second 
            << ")";
      }
      cout << ">" << endl;
    }*/
    cout << dijkstra() << endl;
  }
}

Measured memory_bytes: 1584