#include <iostream>
#include <string>
#include <utility>
#include <stack>
#include <vector>
#include <queue>
#include <algorithm>
#include <map>
#include <climits>
#include <set>
#include <numeric>
#include <iomanip>
#include <cmath>
#include <cstring>
using namespace std;
int d[30][30][4];
int ops[30][30];
int c[4];
int move_h[4] = {-1, 0, 1, 0};
int move_w[4] = {0, 1, 0, -1};

pair <pair <int, int>, int> get_next(int cur_h, int cur_w, int cur_dir, int op){
  if(op == 0){
    int next_h = cur_h + move_h[cur_dir];
    int next_w = cur_w + move_w[cur_dir];
    return make_pair(make_pair(next_h, next_w), cur_dir);
  }

  int next_dir;
  if(op == 1){
    next_dir = (cur_dir + 1) % 4;
  } else if(op == 2){
    next_dir = (cur_dir + 2) % 4;
  } else if(op == 3) {
    next_dir = (cur_dir + 3) % 4;
  } else {
    next_dir = cur_dir;
  }
  int next_h = cur_h;
  int next_w = cur_w;
  if(op < 4){
    next_h += move_h[next_dir];
    next_w += move_w[next_dir];
  }
  return make_pair(make_pair(next_h, next_w), next_dir);
}

void dijikstra(int s_h, int s_w, int s_dir, int h, int w){
    for(int i = 0; i < h; i++){
      for(int j = 0; j < w; j++){
        for(int k = 0; k < 4; k++){
          d[i][j][k] = INT_MAX;
        }
      }
    }

    priority_queue < pair <int, pair<pair<int, int> , int> > , vector <pair <int, pair<pair<int, int> , int> > >, greater<pair <int, pair< pair<int, int> , int> > > > pq;
    d[s_h][s_w][s_dir] = 0;
    pq.push(make_pair(0, make_pair(make_pair(s_h, s_w), s_dir)));
    while(!pq.empty()){
        auto cur = pq.top();
        auto cur_cost = cur.first;
        auto cur_h = cur.second.first.first;
        auto cur_w = cur.second.first.second;
        auto cur_dir = cur.second.second;
        pq.pop();
        if(d[cur_h][cur_w][cur_dir] < cur_cost){
            continue;
        }

        auto tmp = get_next(cur_h, cur_w, cur_dir, ops[cur_h][cur_w]);
        int next_h = tmp.first.first;
        int next_w = tmp.first.second;
        int next_dir = tmp.second;
        int next_d = d[cur_h][cur_w][cur_dir];
        if(0 <= next_h && next_h < h && 0 <= next_w && next_w < w && d[next_h][next_w][next_dir] > next_d){
          d[next_h][next_w][next_dir] = next_d;
          pq.push(make_pair(next_d, make_pair(make_pair(next_h, next_w), next_dir)));
        }
        for(int i = 0; i < 4; i++){
            auto tmp = get_next(cur_h, cur_w, cur_dir, i);
            int next_h = tmp.first.first;
            int next_w = tmp.first.second;
            int next_dir = tmp.second;
            int next_d = d[cur_h][cur_w][cur_dir] + c[i];
            if(0 <= next_h && next_h < h && 0 <= next_w && next_w < w && d[next_h][next_w][next_dir] > next_d){
              d[next_h][next_w][next_dir] = next_d;
              pq.push(make_pair(next_d, make_pair(make_pair(next_h, next_w), next_dir)));
            }
        }
    }
}


int main(){
  while(true){
    int w;
    int h;
    cin >> w >> h;
    if(w == 0 && h == 0){
      break;
    }

    for(int i = 0; i < h; i++){
      for(int j = 0; j < w; j++){
        cin >> ops[i][j];
      }
    }

    for(int i = 0; i < 4; i++){
      cin >> c[i];
    }

    dijikstra(0, 0, 1, h, w);
    cout << min(d[h - 1][w - 1][0], min(d[h - 1][w - 1][1], min(d[h - 1][w - 1][2], d[h - 1][w - 1][3]))) << endl;
  }
  return 0;
}



Measured memory_bytes: 3248