import java.util.PriorityQueue; import java.util.Scanner; public class D { static int w, h; static int[][] field = new int[30][30]; static int[][][][] data = new int[30][30][4][4]; static int[] cost = new int[4]; static final int VECX[] = new int[] { 1, 0, -1, 0 }; static final int VECY[] = new int[] { 0, 1, 0, -1 }; public static void main(String[] args) { Scanner in = new Scanner(System.in); while (true) { w = in.nextInt(); h = in.nextInt(); if (w == 0 && h == 0) break; for (int y = 0; y < h; y++) for (int x = 0; x < w; x++) field[x][y] = in.nextInt(); for (int i = 0; i < 4; i++) cost[i] = in.nextInt(); for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { for (int a = 0; a < 4; a++) { for (int b = 0; b < 4; b++) { data[x][y][a][b] = cost[(b - a + 4) % 4]; } if (field[x][y] != 4) data[x][y][a][(a + field[x][y]) % 4] = 0; } } } Node[][][] node = new Node[w][h][4]; for (int x = 0; x < w; x++) { for (int y = 0; y < h; y++) { for (int d = 0; d < 4; d++) { node[x][y][d] = new Node(); node[x][y][d].x = x; node[x][y][d].y = y; node[x][y][d].dir = d; } } } PriorityQueue q = new PriorityQueue(); node[0][0][0].cost = 0; q.add(node[0][0][0]); while (q.size() != 0) { Node nd = q.poll(); if (nd.done) continue; // System.out.println(nd); nd.done = true; int x = nd.x; int y = nd.y; int dir = nd.dir; int cost = nd.cost; if (x == w - 1 && y == h - 1) break; // if (field[x][y] == 4) // continue; for (int d = 0; d < 4; d++) tryAdd(q, node, x + VECX[d], y + VECY[d], d, cost + data[x][y][dir][d]); } int ans = Integer.MAX_VALUE; ans = Math.min(node[w - 1][h - 1][0].cost, ans); ans = Math.min(node[w - 1][h - 1][1].cost, ans); ans = Math.min(node[w - 1][h - 1][2].cost, ans); ans = Math.min(node[w - 1][h - 1][3].cost, ans); System.out.println(ans); } } static void tryAdd(PriorityQueue q, Node[][][] nodes, int x, int y, int d, int cost) { if (x >= 0 && y >= 0 && x < w && y < h) { if (cost < nodes[x][y][d].cost) { nodes[x][y][d].cost = cost; q.add(nodes[x][y][d]); } } } static class Node implements Comparable { int x, y, dir; int cost = Integer.MAX_VALUE; int[] edgeCost = new int[4]; boolean done = false; @Override public int compareTo(Node o) { return this.cost - o.cost; } @Override public String toString() { return x + ", " + y + "," + dir; } } }