#include <iostream>
#include <algorithm>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <climits>
#include <cstdlib>
#include <cstring>

#define INF INT_MAX>>1 //要climits#includ

using namespace std;

typedef long long ll;

int dx[] ={0, 1, 0, -1};
int dy[] ={-1, 0, 1, 0};

typedef struct robot{
	int x;
	int y;
	int dir;
	int cost;
}robot;

int main() {
	while(1) {
		int w, h; cin >> w >> h;
		if(!w && !h) break;

		int s[30][30];
		for(int i=0; i<h; i++){
			for(int j=0; j<w; j++){
				cin >> s[i][j];
			}
		}
		int c[4];
		for(int i=0; i<4; i++){
			cin >> c[i];
		}

		int dp[30][30][4];
		fill(dp[0][0], dp[30][0], INF);
		dp[0][0][1] = 0;
		robot initial ={0, 0, 1, 0};
		queue<robot> q;
		q.push(initial);

		while(!q.empty()) {
			robot prev = q.front(); 
			q.pop();

			if(prev.cost > dp[prev.y][prev.x][prev.dir]) continue;

			//回転方向
			for(int i = 0; i < 4; i++) {
				robot next;
				next.dir = (prev.dir + i) % 4;
				next.cost = prev.cost;
				if(s[prev.y][prev.x] != i) next.cost += c[i];
				next.y = prev.y + dy[next.dir];
				next.x = prev.x + dx[next.dir];
				if(next.y < 0 || next.y >= h || next.x < 0 || next.x >= w) continue;
				if(dp[next.y][next.x][next.dir] > next.cost) {
					dp[next.y][next.x][next.dir] = next.cost;
					q.push(next);
				}
				
			}
		}

		int ans = INT_MAX;
		for(int i = 0; i < 4; i++){
			ans = min(ans, dp[h - 1][w - 1][i]);
		}
		cout << ans << endl;
	}

	return 0;
}
