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

int sdx[4] = {0, 1, 0, -1};
int sdy[4] = {-1, 0, 1, 0};

struct Edge{
  int src,dst,weight;
  Edge(int src,int dst,int weight) :
    src(src), dst(dst), weight(weight) { }
};
bool operator<(const Edge &e, const Edge &f) {
  return (e.weight != f.weight) ? e.weight>f.weight :
    (e.src != f.src) ? e.src<f.src : e.dst<f.src;
}

typedef vector<Edge> Edges;
typedef vector<Edges> Graph;
const int INF = 0x7fffffff;
int w,h;
void dijkstra(const Graph &g, int s, vector<int> &dist, vector<int> &prev) {
  int n = g.size();
  dist.assign(n, INF);
  dist[s] = 0;
  prev.assign(n, -1);
  priority_queue<Edge> Q;

  for(Q.push(Edge(-2, s, 0)); !Q.empty(); ) {
    Edge e = Q.top();
    Q.pop();
    if(prev[e.dst] != -1) continue;
    prev[e.dst] = e.src;
    for(Edges::const_iterator it = g[e.dst].begin(); it != g[e.dst].end(); ++it) {
      if(dist[it->dst] > e.weight + it->weight) {
	dist[it->dst] = e.weight + it->weight;
	Q.push(Edge(it->src, it->dst, e.weight + it->weight));
      }
    }
  }
}

int main() {
  while(cin>>w>>h, w||h) {
    Graph g(w*h*4);
    int t,tk,nx,ny,inp;

    for(int i=0; i<h; ++i) {
      for(int j=0; j<w; ++j) {
	cin>>t;
	if(t==4) continue;
	for(int k=0; k<4; ++k) {
	  tk = (k+t)%4;
	  nx = j+sdx[tk], ny = i+sdy[tk];
	  if(nx >= 0 && (nx<w) && ny >= 0 && ny < h )
	    g[(i*w+j)*4+k].push_back( Edge((i*w+j)*4+k, (ny*w+nx)*4+tk, 0) );
	}
      }
    }

    int c[4];
    cin>>c[0]>>c[1]>>c[2]>>c[3];

    for(int i=0; i<h; ++i) {
      for(int j=0; j<w; ++j) {
	for(int t=0; t<4; ++t) {
	  for(int k=0; k<4; ++k) {
	    tk = (k+t)%4;
	    nx = j+sdx[tk],ny = i+sdy[tk];
	    if(nx >= 0 && nx < w && ny >= 0 && ny < h)
	       g[(i*w+j)*4+k].push_back( Edge((i*w+j)*4+k, (ny*w+nx)*4+tk, c[t]) );
	  }
	}
      }
    }

    vector<int> dist;
    vector<int> prev;
    dijkstra(g, 1, dist, prev);

    cout<<min( dist[dist.size()-2], dist[dist.size()-3] )<<endl;
  }
}