#include "iostream"
#include "climits"
#include "list"
#include "queue"
#include "stack"
#include "set"
#include "functional"
#include "algorithm"
#include "string"
#include "map"
#include "unordered_map"
#include "unordered_set"
#include "iomanip"
#include "cmath"
#include "random"
#include "bitset"
#include "cstdio"

using namespace std;

const long long int MOD = 1000000007;
const long double EPS = 1e-9;

long long int N, M, K, H, W, L, R;

struct node {
	int y, x, dir;
	bool operator < (const node& n)const {
		return y < n.y;
	}
};

int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);

	cin >> W >> H;
	int dir[] = { 0,1,0,-1,0 };
	vector<int>ans;
	while (H) {
		vector<vector<int>>v(H, vector<int>(W));
		for (int i = 0; i < H; i++) {
			for (int j = 0; j < W; j++) {
				cin >> v[i][j];
			}
		}
		vector<int>cost(4);
		for (int i = 0; i < 4; i++)cin >> cost[i];
		vector<vector<vector<int>>>dp(H, vector<vector<int>>(W, vector<int>(4, MOD)));
		dp[0][0][0] = 0;
		priority_queue<pair<int, node>, vector<pair<int, node>>, greater<pair<int, node>>>PQ;
		PQ.push({ 0,{0,0,0} });
		while (!PQ.empty()) {
			int c = PQ.top().first;
			node n = PQ.top().second;
			PQ.pop();
			if (dp[n.y][n.x][n.dir] < c)continue;
			for (int i = 0; i < 4; i++) {
				int ndir = (n.dir + i) % 4;
				int ny = dir[ndir] + n.y;
				int nx = dir[ndir + 1] + n.x;
				if (ny < 0 || nx < 0 || ny >= H || nx >= W)continue;
				if (dp[ny][nx][ndir] > c + cost[i]) {
					dp[ny][nx][ndir] = c + cost[i];
					PQ.push({ c + cost[i],{ny,nx,ndir} });
				}
			}
			if (v[n.y][n.x] == 4)continue;
			int ndir = (n.dir + v[n.y][n.x]) % 4;
			int ny = dir[ndir] + n.y;
			int nx = dir[ndir + 1] + n.x;
			if (ny < 0 || nx < 0 || ny >= H || nx >= W)continue;
			if (dp[ny][nx][ndir] > c) {
				dp[ny][nx][ndir] = c;
				PQ.push({ c ,{ ny,nx,ndir } });
			}
		}
		ans.push_back(min(dp[H - 1][W - 1][0], dp[H - 1][W - 1][1]));
		cin >> W >> H;
	}
	for (auto i : ans)cout << i << endl;
	return 0;
}

