#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <utility>
#include <queue>
using namespace std;

#define rep(i,n) for(int i=0; i<n; i++)
#define fi first
#define se second
typedef pair<int,int> pii;
typedef pair<int, pair<pii, int> > pnode;

struct node {
	pnode p;
	node( pnode pn ) {
		p = pn;
	}
};
bool operator<( const node& l, const node &r ) {
	return l.p.fi > r.p.fi;
}

int main() {
	int w, h;
	while(cin >> w >> h, w||h) {
		bool visit[31][31][4] = {};
		int field[31][31];
		int cost[4];
		rep(y, h) {
			rep(x, w) {
				cin >> field[x][y];
			}
		}
		rep(i,4) {
			cin >> cost[i];
		}
		priority_queue<node> que;
		que.push( node( pnode(0, pair<pii,int>(pii(0,0),0)) ) );
		while( !que.empty() ) {
			node nd = que.top();
			que.pop();
			if( visit[nd.p.se.fi.fi][nd.p.se.fi.se][nd.p.se.se] ) continue;
			visit[nd.p.se.fi.fi][nd.p.se.fi.se][nd.p.se.se] = true;
			if( nd.p.se.fi.fi == w-1 && nd.p.se.fi.se == h-1 ) {
				cout << nd.p.fi << endl;
				break;
			}
//			cout << "visit " << nd.p.se.fi.fi << ", " << nd.p.se.fi.se << ", " << nd.p.se.se << " c:" << nd.p.fi << endl;
			int dx[4] = {1, 0, -1, 0};
			int dy[4] = {0, 1, 0, -1};
			rep(i, 4) {
				int dir = (i+nd.p.se.se)%4;
				int nx = nd.p.se.fi.fi+dx[dir];
				int ny = nd.p.se.fi.se+dy[dir];
				if( 0<=nx && nx<w && 0<=ny && ny<h && !visit[nx][ny][dir] ) {
					int c = (field[nd.p.se.fi.fi][nd.p.se.fi.se] == i) ? 0 : cost[i];
					que.push( node( pnode(nd.p.fi+c, pair<pii,int>(pii(nx, ny), dir)) ) );
//					cout << "reg " << nx << ", " << ny << ", " << dir << " c:" << nd.p.fi+c << endl;
				}
			}
		}
	}
	return 0;
}