#include<bits/stdc++.h>
using namespace std;
#define INF 1e9

//お手上げ
//ループがあったらダメとかかな？

//           →  ↓  ←   ↑
int di[4] = {0, 1, 0, -1};
int dj[4] = {1, 0, -1, 0};

vector<int> dijk(int s, int v, vector<vector<pair<int, int> > > adjlist){
    
    priority_queue <pair<int, int> > wait;
    vector<int> result(v, INF);

    //スタート地点を追加
    result[s] = 0;
    wait.push(make_pair(0, s));

    //ダイクストラ本体
    while(!wait.empty()){    //waitが空になるまで

        int nowpoint = wait.top().second;
        int nowcost = -wait.top().first;
        wait.pop();

        if(result[nowpoint] < nowcost) continue;


        //今いる頂点と隣接しているすべての頂点をなめる
        for(int i = 0; i < adjlist[nowpoint].size(); i++){

            int nextpoint = adjlist[nowpoint][i].second;
            int nextcost = nowcost + adjlist[nowpoint][i].first;
            //現時点より安く到達できそうであれば、結果を更新して優先度付きキューに格納
            if(result[nextpoint] > nextcost){
                result[nextpoint] = nextcost;
                wait.push(make_pair(-nextcost, nextpoint));
            }
        }
    }
    
    return result;         //結果列を返す
}

int main(){

    while(1){
        int w, h; cin >> w >> h;
        if(!w) break;
        vector<vector<int> > a(h, vector<int> (w));
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                cin >> a[i][j];
            }
        }

        int c[4];
        for(int i = 0; i < 4; i++) cin >> c[i];
        map<pair<pair<int, int>, int>, int > m;                   //{ , } 方向
        int n = 0;
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                for(int k = 0; k < 4; k++){
                    m[{{i, j}, k}] = n;
                    n++;
                }
            }
        }

        vector<vector<pair<int, int> > > adjlist(3610);      //first := コスト　second := 行先

        //グラフを作っていきます
        for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                //if(a[i][j] == 4) continue;
                for(int k = 0; k < 4; k++){          //今向いてる方向

                    int now = m[{{i, j}, k}];
                    if(a[i][j] == 0){                //直進
                        for(int l = 0; l < 4; l++){
                            if(0 <= i + di[l] && i + di[l] < h && 0 <= j + dj[l] && j + dj[l] < w){
                                int next = m[{{i + di[l], j + dj[l]}, l}];
                                if(k == l) adjlist[now].push_back({0, next});
                                else adjlist[now].push_back({c[(4 + l - k) % 4], next});
                            }
                        }
                    }else if(a[i][j] == 1){          //右折
                        for(int l = 0; l < 4; l++){
                            if(0 <= i + di[l] && i + di[l] < h && 0 <= j + dj[l] && j + dj[l] < w){                            
                                int next = m[{{i + di[l], j + dj[l]}, l}];
                                if((4 + l - k) % 4 == 1) adjlist[now].push_back({0, next});
                                else adjlist[now].push_back({c[(4 + l - k) % 4], next});
                            }
                        }
                    }else if(a[i][j] == 2){
                        for(int l = 0; l < 4; l++){
                            if(0 <= i + di[l] && i + di[l] < h && 0 <= j + dj[l] && j + dj[l] < w){
                                int next = m[{{i + di[l], j + dj[l]}, l}];
                                if((4 + l - k) % 4 == 2) adjlist[now].push_back({0, next});
                                else adjlist[now].push_back({c[(4 + l - k) % 4], next});
                            }
                        }
                    }else if(a[i][j] == 3){
                        for(int l = 0; l < 4; l++){
                            if(0 <= i + di[l] && i + di[l] < h && 0 <= j + dj[l] && j + dj[l] < w){                            
                                int next = m[{{i + di[l], j + dj[l]}, l}];
                                if((4 + l - k) % 4 == 3) adjlist[now].push_back({0, next});
                                else adjlist[now].push_back({c[(4 + l - k) % 4], next});
                            }
                        }
                    }else{
                         for(int l = 0; l < 4; l++){
                            if(0 <= i + di[l] && i + di[l] < h && 0 <= j + dj[l] && j + dj[l] < w){                            
                                int next = m[{{i + di[l], j + dj[l]}, l}];
                                //if((4 + l - k) % 4 == 3) adjlist[now].push_back({0, next});
                                adjlist[now].push_back({c[(4 + l - k) % 4], next});
                            }
                        }
                    }
                }
            }
        }

        vector<int> result(n);
        int s = m[{{0, 0}, 0}];
        result = dijk(s, n, adjlist);
        //cout << result[G] << endl;

        /*for(int i = 0; i < h; i++){
            for(int j = 0; j < w; j++){
                int ans = INF;
                for(int k = 0; k < 4; k++){
                    ans = min(ans, result[m[{{i, j}, k}]]);
                }
                cout << ans << " ";
            }
            cout << endl;
        }*/
        int ans = INF;
        for(int i = 0; i < 4; i++){
            int node = m[{{h - 1, w - 1}, i}];
            ans = min(ans, result[node]);
        }
        cout << ans << endl;
        
    }
    return 0;
}


Measured memory_bytes: 3680