// Arup Guha
// Started 2/16/2019 finished 3/5/2019
// Solution to 2019 Mercer Contest Problem 1: Board Room

import java.util.*;

public class boardroom {
	
	final public static int NOSOL = 2000000000;
	
	final public static int[] DX = {-1,0,0,1};
	final public static int[] DY = {0,-1,1,0};
	
	public static int r;
	public static int c;
	public static int[][] grid;
	public static int k;
	public static int[] len;
	
	public static ArrayList[] boardDX;
	public static ArrayList[] boardDY;
	
	public static void main(String[] args) {
		
		// Get basic input.
		Scanner stdin = new Scanner(System.in);
		c = stdin.nextInt();
		r = stdin.nextInt();
		k = stdin.nextInt();
	
		// Process all cases.
		while (c != -1) {
			
			// Get the board lengths.
			len = new int[k];
			for (int i=0; i<k; i++)
				len[i] = stdin.nextInt();
			
			// Read in the grid.
			grid = new int[r+1][c+1];
			for (int i=r; i>=0; i--)
				for (int j=0; j<=c; j++)
					grid[i][j] = stdin.nextInt();
			
			boardDX = new ArrayList[k];
			boardDY = new ArrayList[k];
			for (int i=0; i<k; i++) {
				boardDX[i] = new ArrayList<Integer>();
				boardDY[i] = new ArrayList<Integer>();
				fillDXDY(len[i], (ArrayList<Integer>)boardDX[i], (ArrayList<Integer>)boardDY[i]);
			}
			
			// Ta da!
			System.out.println(solve());
			
			// Get next case.
			c = stdin.nextInt();
			r = stdin.nextInt();
			k = stdin.nextInt();			
		}
	}
	
	public static void fillDXDY(int hyp, ArrayList<Integer> xList, ArrayList<Integer> yList) {
		
		// try x=i for each x.
		for (int i=0; i<=hyp; i++) {
			
			int y = (int)(Math.sqrt(hyp*hyp - i*i)+1e-9);
			if (y*y+i*i != hyp*hyp) continue;
			
			// First two.
			xList.add(i);
			yList.add(y);
			xList.add(i);
			yList.add(-y);
			
			// Need these only for real Pythagorean triple.
			if (i > 0 && y > 0) {
				xList.add(-i);
				yList.add(y);
				xList.add(-i);
				yList.add(-y);		
			}
		}
	}
	
	public static int solve() {
		
		int[] dist = new int[1<<17];
		Arrays.fill(dist,  NOSOL);
		PriorityQueue<dist> pq = new PriorityQueue<dist>();
		pq.offer(new dist(grid[0][0], 0));
		
		// Starting state is (0, 0) with mask 0 (nothing used). Cost is first square.
		dist[0] = grid[0][0];
		
		// Run Dijkstra's
		while (pq.size() > 0) {
			
			// Get this item.
			dist curD = pq.poll();
			int cur = curD.d;
			int curMask = curD.mask & 31;
			int curY = (curD.mask >> 5) & 63;
			int curX = (curD.mask >> 11) & 63;
			
			// We got there!
			if (curX == r && curY == c) 
				return dist[curD.mask];
			
			// Just use the regular movement without a board.
			for (int i=0; i<DX.length; i++) {
				
				// Where I go.
				int nextX = curX + DX[i];
				int nextY = curY + DY[i];
				if (!inbounds(nextX, nextY)) continue;
				int nextMask = (nextX<<11)+(nextY<<5)+curMask;
				
				// This doesn't help.
				if (dist[nextMask] <= dist[curD.mask] + grid[nextX][nextY]) continue;
				
				// Update and put back in queue.
				dist[nextMask] = dist[curD.mask] + grid[nextX][nextY];
				pq.offer(new dist(dist[nextMask], nextMask));
			}
			
			// Now, time to try using boards.
			for (int i=0; i<k; i++) {
				
				// Used this board already.
				if ((curMask & (1<<i)) != 0) continue;
				
				// All the directions we could go.
				for (int j=0; j<boardDX[i].size(); j++) {
					
					// Where we would go.
					int nextX = curX + ((ArrayList<Integer>)boardDX[i]).get(j);
					int nextY = curY + ((ArrayList<Integer>)boardDY[i]).get(j);
					if (!inbounds(nextX, nextY)) continue;
					int nextMask = (nextX<<11)+(nextY<<5)+curMask+(1<<i);
					
					// Not helpful.
					if (dist[nextMask] <= dist[curD.mask] + grid[nextX][nextY]) continue;
					
					// Update and add to queue.
					dist[nextMask] = dist[curD.mask] + grid[nextX][nextY];
					pq.offer(new dist(dist[nextMask], nextMask));				
				}
			}
		}
		
		// Never made it.
		return -1;
	}
	
	public static boolean inbounds(int myx, int myy) {
		return myx >= 0 && myx <= r && myy >= 0 && myy <= c;
	}

}

class dist implements Comparable<dist> {
	
	public int d;
	public int mask;
	
	public dist(int myd, int mymask) {
		d = myd;
		mask = mymask;
	}
	
	public int compareTo(dist other) {
		return this.d - other.d;
	}
}