#include <algorithm>
#include <iostream>
#include <queue>
#define N_MAX 30
#define INF (1e9)
using namespace std;
void dijkstra();
int w,h,data[N_MAX][N_MAX],d[N_MAX][N_MAX][4],c[4];
int dy[4]={-1,0,1,0};
int dx[4]={0,1,0,-1};
typedef struct stu{
  int mincost,y,x,dir;
  bool operator<(const stu & right)const{
    return mincost>right.mincost;
  }
} dat;

int main(){
  while(1){
    cin>>w>>h;
    if(!w&&!h) break;
    for(int i=0;i<h;i++)
      for(int j=0;j<w;j++) cin>>data[i][j];
    for(int i=0;i<4;i++) cin>>c[i];
    dijkstra();
  }
  return 0;
}

void dijkstra(){
  priority_queue<dat > Q;
  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;
  d[0][0][1]=0;
  Q.push((dat){0,0,0,1});
  while(!Q.empty()){
    dat t=Q.top(); Q.pop();
    int cost=t.mincost,y=t.y,x=t.x,dir=t.dir;
    if(cost>d[y][x][dir]) continue;
    for(int i=0;i<4;i++){
      int ny=y+dy[(dir+i)%4],nx=x+dx[(dir+i)%4];
      int ndir=(dir+i)%4;
      if(ny<0||nx<0||h<=ny||w<=nx) continue;
      if(d[ny][nx][ndir]>cost+c[i]){
	d[ny][nx][ndir]=cost+c[i];
	Q.push((dat){d[ny][nx][ndir],ny,nx,ndir});
      }
      if(data[y][x]!=i) continue;
      if(d[ny][nx][ndir]>cost){
	d[ny][nx][ndir]=cost;
	Q.push((dat){d[ny][nx][ndir],ny,nx,ndir});
      }
    }
  }
  int mincost=INF;
  for(int i=0;i<4;i++)
    mincost=min(mincost,d[h-1][w-1][i]);
  cout<<mincost<<endl;
}