#include<cstdio>
#include<vector>
#include<algorithm>

using namespace std;

int graph[50][50][4]; // x, y, d
int map[50][50]; // x, y
int c[4];
typedef struct{int x,y;} pos;
typedef struct{pos p; int d;} vec;
typedef struct{vec vs,vd; int c;} edge;

#define _N 0
#define _E 1
#define _W 2
#define _S 3

int main(void) {
    while(true) {
        int w,h;
        scanf("%d%d",&w,&h);
        if(!w) break;

        vector<edge> edges;

        for(int i=0; i<h; i++)
            for(int j=0; j<w; j++)
                scanf("%d", &map[j][i]);
        for(int i=0; i<4; i++)
            scanf("%d", &c[i]);

        for(int i=0; i<w; i++)
            for(int j=0; j<h; j++) {
                switch(map[i][j]) { // add edges whose cost is zero
                    case 0: // straight
                        if(j-1>=0) edges.push_back({{{i,j},_N}, {{i,j-1},_N}, 0});
                        if(i+1<w)  edges.push_back({{{i,j},_E}, {{i+1,j},_E}, 0});
                        if(i-1>=0) edges.push_back({{{i,j},_W}, {{i-1,j},_W}, 0});
                        if(j+1<h)  edges.push_back({{{i,j},_S}, {{i,j+1},_S}, 0});
                        break;
                    case 1: // right
                        if(i+1<w)  edges.push_back({{{i,j},_N}, {{i+1,j},_E}, 0});
                        if(j+1<h)  edges.push_back({{{i,j},_E}, {{i,j+1},_S}, 0});
                        if(j-1>=0) edges.push_back({{{i,j},_W}, {{i,j-1},_N}, 0});
                        if(i-1>=0) edges.push_back({{{i,j},_S}, {{i-1,j},_W}, 0});
                        break;
                    case 2: // reverse
                        if(j+1<h)  edges.push_back({{{i,j},_N}, {{i,j+1},_S}, 0});
                        if(i-1>=0) edges.push_back({{{i,j},_E}, {{i-1,j},_W}, 0});
                        if(i+1<w)  edges.push_back({{{i,j},_W}, {{i+1,j},_E}, 0});
                        if(j-1>=0) edges.push_back({{{i,j},_S}, {{i,j-1},_N}, 0});
                        break;
                    case 3: // left
                        if(i-1>=0) edges.push_back({{{i,j},_N}, {{i-1,j},_W}, 0});
                        if(j-1>=0) edges.push_back({{{i,j},_E}, {{i,j-1},_N}, 0});
                        if(j+1<h)  edges.push_back({{{i,j},_W}, {{i,j+1},_S}, 0});
                        if(i+1<w)  edges.push_back({{{i,j},_S}, {{i+1,j},_E}, 0});
                        break;
                    case 4: // halt
                        break;
                }

                // add edges when player orders
                if(j-1>=0) edges.push_back({{{i,j},_N}, {{i,j-1},_N}, c[0]});
                if(i+1<w)  edges.push_back({{{i,j},_E}, {{i+1,j},_E}, c[0]});
                if(i-1>=0) edges.push_back({{{i,j},_W}, {{i-1,j},_W}, c[0]});
                if(j+1<h)  edges.push_back({{{i,j},_S}, {{i,j+1},_S}, c[0]});

                if(i+1<w)  edges.push_back({{{i,j},_N}, {{i+1,j},_E}, c[1]});
                if(j+1<h)  edges.push_back({{{i,j},_E}, {{i,j+1},_S}, c[1]});
                if(j-1>=0) edges.push_back({{{i,j},_W}, {{i,j-1},_N}, c[1]});
                if(i-1>=0) edges.push_back({{{i,j},_S}, {{i-1,j},_W}, c[1]});

                if(j+1<h)  edges.push_back({{{i,j},_N}, {{i,j+1},_S}, c[2]});
                if(i-1>=0) edges.push_back({{{i,j},_E}, {{i-1,j},_W}, c[2]});
                if(i+1<w)  edges.push_back({{{i,j},_W}, {{i+1,j},_E}, c[2]});
                if(j-1>=0) edges.push_back({{{i,j},_S}, {{i,j-1},_N}, c[2]});

                if(i-1>=0) edges.push_back({{{i,j},_N}, {{i-1,j},_W}, c[3]});
                if(j-1>=0) edges.push_back({{{i,j},_E}, {{i,j-1},_N}, c[3]});
                if(j+1<h)  edges.push_back({{{i,j},_W}, {{i,j+1},_S}, c[3]});
                if(i+1<w)  edges.push_back({{{i,j},_S}, {{i+1,j},_E}, c[3]});
            }

        for(int i=0; i<w; i++) // init graph
            for(int j=0; j<h; j++)
                for(int d=0; d<4; d++)
                    graph[i][j][d] = 0xFFFFFF;

        graph[0][0][_E] = 0; // init source

//        printf(":%d:\n", edges.size());
        bool updated=true; // bellman-ford
        for(int i=0; i<w*h*4 && updated; i++) {
            updated = false;
            for(vector<edge>::iterator it=edges.begin(); it!=edges.end(); it++) {
                if(graph[it->vs.p.x][it->vs.p.y][it->vs.d] + it->c < graph[it->vd.p.x][it->vd.p.y][it->vd.d]) {
                    graph[it->vd.p.x][it->vd.p.y][it->vd.d] = graph[it->vs.p.x][it->vs.p.y][it->vs.d] + it->c;
                    updated = true;
                }
            }
        }

/*        for(int i=0; i<w; i++) { 
            for(int j=0; j<h; j++) {
                printf("[");
                for(int d=0; d<4; d++) {
                    printf("%d:", graph[i][j][d]);
                }
                printf("] ");
            }
            printf("\n");
        }
        printf("\n");
        */


        int res=0xFFFFFF;
        for(int d=0; d<4; d++)
            res = min(graph[w-1][h-1][d], res);
        printf("%d\n",res);

    }
    return 0;
}

Measured memory_bytes: 2264