#include<iostream>
#include<algorithm>
#include<queue>
#include<vector>
#include<string>
#include<map>
#define INF 1000000000
#define all(c) c.begin(),c.end()
#define uni(c) c.erase(unique(all(c)),c.end())
#define pb push_back
using namespace std;
typedef pair<int,int> P;
typedef pair<int,P> PP;
typedef pair<int,PP> PPP;
int w,h;
int dx[]={0,1,0,-1},dy[]={-1,0,1,0};
bool inf(int y,int x){
	if(x>=0&&x<w&&y>=0&&y<h)
		return true;
	return false;
}
int dij(vector<vector<int> > f, vector<int> op){
	priority_queue<PPP,vector<PPP> , greater<PPP> > que;
	int d[40][40][5];
	for(int i=0;i<h;i++)
	for(int j=0;j<w;j++)
	for(int k=0;k<4;k++)
	d[i][j][k]=INF;
	que.push(PPP(0,PP(1,P(0,0))));
	d[0][0][1]=0;
	while(!que.empty()){
		PPP p=que.top();
		int dit=p.second.first;
		P now=p.second.second;
		int nc=p.first;
		que.pop();
		if(d[now.first][now.second][dit]<nc){
			continue;
		}
		if(now.first==h-1&&now.second==w-1){
			return nc;
		}
		d[now.first][now.second][dit]=nc;
		for(int i=0;i<4;i++){
			int nx=dx[(i+dit)%4]+now.second,ny=dy[(i+dit)%4]+now.first;
			if(!inf(ny,nx))
				continue;
			if(f[now.first][now.second]==i&&nc<d[ny][nx][(i+dit)%4]){
				que.push(PPP(nc,PP((i+dit)%4,P(ny,nx))));
				continue;
			}
			if(nc+op[i]<d[ny][nx][(i+dit)%4]){
				que.push(PPP(nc+op[i],PP((i+dit)%4,P(ny,nx))));
			}
		}
		
		
	}
	
	
	//return d[h-1][w-1][(i+dit)%4];
}
int main(){
	while(cin>>w>>h,w||h){
		vector<vector<int> > f(h,vector<int>(w));
		for(int i=0;i<h;i++){
			for(int j=0;j<w;j++){
				cin>>f[i][j];
			}
		}
		vector<int> op(4);
		for(int i=0;i<4;i++)
			cin>>op[i];
		cout<<dij(f,op)<<endl;
		
	}
	return 0;
}