#ifndef _GLIBCXX_NO_ASSERT
#include <cassert>
#endif
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>

#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#endif

#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <istream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>

#ifdef __GXX_EXPERIMENTAL_CXX0X__
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#endif

using namespace std;
typedef pair < int , pair<pair<int , int> , int> > P;

//0 ??????1?????????2?????????3??????

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

int main ()
{
	int W , H;
	while( cin >> W >> H , W || H )
	{
		vector<vector<int>>data;
		vector<vector<vector<int>>>M;
		data.resize ( H );
		M.resize ( H );
		for( size_t i = 0; i < H; i++ )
		{
			M[i].resize ( W );
			data[i].resize ( W );
			for( size_t j = 0; j < W; j++ )
			{
				cin >> data[i][j];
				M[i][j].resize ( 4 );
				for( size_t k = 0; k < 4; k++ )
				{

				M[i][j][k] = INT_MAX;
				}
			}
		}
		int C[4] = {};
		for( size_t i = 0; i < 4; i++ )
		{
			cin >> C[i];
		}
		priority_queue<P , vector<P> , greater<P>>que;
		long long int ans = -1;
		que.push ( P{ 0 , pair < pair<int , int> , int > {pair < int , int > {0 , 0} , 0} } );
		M[0][0][0] = 0;
		while( !que.empty () )
		{
			P now = que.top (); que.pop ();
			int nowcost = now.first;
			int nowx = now.second.first.second;
			int nowy = now.second.first.first;
			int nowd = now.second.second;

			//cout << nowx << " " << nowy << " " << nowcost << endl;

			/*if( nowy == H - 1 && nowx == W - 1 )
			{
				ans = nowcost;
				break;
			}*/
			//if( data[nowy][nowx] == 4 )continue;
			for( size_t i = 0; i < 4; i++ )
			{
				int nextd = ( i + nowd ) % 4;
				int nextx = nowx + dx[nextd];
				int nexty = nowy + dy[nextd];
				if( nextx < 0 || nextx >= W || nexty < 0 || nexty >= H )continue;
				if( i == data[nowy][nowx] )
				{
					if( M[nexty][nextx][nextd]>nowcost )
					{
						M[nexty][nextx][nextd] = nowcost;
						que.push ( P{ nowcost , pair < pair<int , int> , int > {pair < int , int > {nexty , nextx} , nextd} } );
					}
				} else
				{
					if( M[nexty][nextx][nextd] > nowcost + C[i] )
					{
						M[nexty][nextx][nextd] = nowcost + C[i];
						que.push ( P{ nowcost + C[i] , pair < pair<int , int> , int > {pair < int , int > {nexty , nextx} , nextd} } );
					}
				}
			}
		}
		//cout << ans << endl;
		int ans2 = INT_MAX;
		for( size_t i = 0; i < 4; i++ )
		{
			ans2 = min ( ans2 , M[H - 1][W - 1][i] );
		}
		cout << ans2 << endl;
	}
}

Measured memory_bytes: 1364