#include <bits/stdc++.h>
#define _overload3(_1, _2, _3, name, ...) name
#define _rep(i, n) repi(i, 0, n)
#define repi(i, a, b) for (int i = (int)(a); i < (ll)(b); ++i)
#define rep(...) _overload3(__VA_ARGS__, repi, _rep, )(__VA_ARGS__)
#define ll long long
#define lld long double
#define ALL(x) x.begin(), x.end()
#ifdef DEBUG
#define line() cerr << "[" << __LINE__ << "] ";
#define dump(i) cerr << #i ": " << i << " ";
#define dumpl(i) cerr << #i ": " << i << endl;
#else
#define line(i)
#define dump(i)
#define dumpl(i)
#endif
using namespace std;

int w, h;

bool validpos(int y, int x)
{
    return (0 <= x && x < w && 0 <= y && y < h);
}

void show(map<vector<int>, int> &mincost)
{
    rep(i, h)
    {

        rep(j, w)
        {
            int best = -1; // (1 << 30);
            rep(k, 4)
            {
                best = max(best, mincost[{i, j, k}]);
            }
            cerr << best << " ";
        }
        cerr << endl;
    }
}

int main()
{
    while (true)
    {
        int dx[4] = {0, 1, 0, -1};
        int dy[4] = {-1, 0, 1, 0};

        cin >> w >> h;
        if (w == 0 && h == 0)
            break;
        vector<vector<int>> g(h, vector<int>(w, 0));
        rep(i, h) rep(j, w) cin >> g[i][j];
        int c[4];
        rep(i, 4) cin >> c[i];
        map<vector<int>, int> mincost;
        map<vector<int>, bool> visited;

        auto compare = [](vector<int> &a, vector<int> &b) {
            return ((h - 1) - a[0] + (w - 1) - a[1]) > ((h - 1) - b[0] + (w - 1) - b[1]);
        };

        priority_queue<vector<int>, vector<vector<int>>> que;
        que.push({0,
                  0,
                  1, 0}); // y,x,dir,cost
        mincost[{0, 0, 1}] = 0;
        visited[{0, 0, 1}] = true;
        while (!que.empty())
        {
            auto nowstate = que.top();
            que.pop();
            int y = nowstate[0];
            int x = nowstate[1];
            int dir = nowstate[2];
            int cost = nowstate[3];
            if (cost > mincost[{y, x, dir}])
            {
                continue;
            }
            rep(i, 4)
            {
                int ndir = (dir + i) % 4;
                int nx = x + dx[ndir];

                // cerr << "y = " << y << ",dy[ndir]=" << dy[ndir] << endl;
                int ny = y + dy[ndir];
                //cerr << "so ny = " << ny << endl;

                int ncost = cost + (g[y][x] == i ? 0 : c[i]);
                //cerr << "eval " << ny << "," << nx << "," << ndir << "," << ncost << "," << y << endl;

                if (validpos(ny, nx))
                {

                    if (visited[{ny, nx, ndir}] == false || mincost[{ny, nx, ndir}] > ncost)
                    {
                        // cerr << "push " << ny << "," << nx << "," << ndir << endl;
                        que.push({ny, nx, ndir, ncost});
                        visited[{ny, nx, ndir}] = true;
                        mincost[{ny, nx, ndir}] = ncost;
                    }
                }
                //cerr << "for : " << i << endl;
            }
            //  show(mincost);

            //  rep(i, 4)
            //        cerr
            //   << mincost[{h - 1, w - 1, i}] << " ";
            //cerr << endl;
        }
        int ans = (1 << 30);
        rep(i, 4)
        {
            if (visited[{h - 1, w - 1, i}] == true)
            {
                ans = min(ans, mincost[{h - 1, w - 1, i}]);
            }
        }
        cout << ans << endl;
    }

    return 0;
}


Measured memory_bytes: 3928