Problem:
Score : 400 points

Problem Statement

Joisino the magical girl has decided to turn every single digit that exists on this world into 1.

Rewriting a digit i with j (0≤i,j≤9) costs c_{i,j} MP (Magic Points).

She is now standing before a wall. The wall is divided into HW squares in H rows and W columns, and at least one square contains a digit between 0 and 9 (inclusive).

You are given A_{i,j} that describes the square at the i-th row from the top and j-th column from the left, as follows:

If A_{i,j}≠-1, the square contains a digit A_{i,j}.

If A_{i,j}=-1, the square does not contain a digit.

Find the minimum total amount of MP required to turn every digit on this wall into 1 in the end.

Constraints

1≤H,W≤200

1≤c_{i,j}≤10^3 (i≠j)

c_{i,j}=0 (i=j)

-1≤A_{i,j}≤9

All input values are integers.

There is at least one digit on the wall.

Input

Input is given from Standard Input in the following format:

H W
c_{0,0} ... c_{0,9}
:
c_{9,0} ... c_{9,9}
A_{1,1} ... A_{1,W}
:
A_{H,1} ... A_{H,W}

Output

Print the minimum total amount of MP required to turn every digit on the wall into 1 in the end.

Sample Input 1

2 4
0 9 9 9 9 9 9 9 9 9
9 0 9 9 9 9 9 9 9 9
9 9 0 9 9 9 9 9 9 9
9 9 9 0 9 9 9 9 9 9
9 9 9 9 0 9 9 9 9 2
9 9 9 9 9 0 9 9 9 9
9 9 9 9 9 9 0 9 9 9
9 9 9 9 9 9 9 0 9 9
9 9 9 9 2 9 9 9 0 9
9 2 9 9 9 9 9 9 9 0
-1 -1 -1 -1
8 1 1 8

Sample Output 1

12

To turn a single 8 into 1, it is optimal to first turn 8 into 4, then turn 4 into 9, and finally turn 9 into 1, costing 6 MP.

The wall contains two 8s, so the minimum total MP required is 6×2=12.

Sample Input 2

5 5
0 999 999 999 999 999 999 999 999 999
999 0 999 999 999 999 999 999 999 999
999 999 0 999 999 999 999 999 999 999
999 999 999 0 999 999 999 999 999 999
999 999 999 999 0 999 999 999 999 999
999 999 999 999 999 0 999 999 999 999
999 999 999 999 999 999 0 999 999 999
999 999 999 999 999 999 999 0 999 999
999 999 999 999 999 999 999 999 0 999
999 999 999 999 999 999 999 999 999 0
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1
1 1 1 1 1

Sample Output 2

0

Note that she may not need to change any digit.

Sample Input 3

3 5
0 4 3 6 2 7 2 5 3 3
4 0 5 3 7 5 3 7 2 7
5 7 0 7 2 9 3 2 9 1
3 6 2 0 2 4 6 4 2 3
3 5 7 4 0 6 9 7 6 7
9 8 5 2 2 0 4 7 6 5
5 4 6 3 2 3 0 5 4 3
3 6 2 3 4 2 4 0 8 9
4 6 5 4 3 5 3 2 0 8
2 1 3 4 5 7 8 6 4 0
3 5 2 6 1
2 5 3 2 1
6 9 2 5 6

Sample Output 3

47

Solution in Java8 (OpenJDK 1.8.0) (judge verdict: Wrong Answer)

import java.util.*;
import java.io.*;


public class Main {

    public static void main(String args[]){
         FastScanner sc = new FastScanner();
         PrintWriter out = new PrintWriter(System.out);
         int H = sc.nextInt();
         int W = sc.nextInt();
         long[][] G = new long[10][10];
         for(int i=0;i<10;i++){
             for(int j=0;j<10;j++){
                 G[i][j] = sc.nextInt();
             }
         }
         long[][] table = graph.wf(G);

         int res = 0;
         for(int i=0;i<H;i++){
             for(int j=0;j<W;j++){
                 int a = sc.nextInt();
                 if(a==-1) continue;
                 else{
                    res += table[a][1];
                    out.print(table[a][1]+" ");
                 }
             }
             out.println();
         }


         out.println(res);
         out.flush();
        //  System.out.println(sum);
    }
}

class MyMath{
    public static long gcm(long a, long b){
        if(a<b) return gcm(b, a);

        if(a%b==0 || b==0) return b;

        long remainder = a%b;
        return gcm(b, remainder);
    }

    public static long summation(long a, long b){
        return b*(b+1)/2-a*(a-1)/2;
    }

    public static long factorial(long n){

        if(n<=1) return 1;
        else return factorial(n-1)*n;
    }

    public static long binomial(int a, int b){
        if(a<b) return 0;
        long[][] table = new long[a+1][a+1];
        for(int i=0;i<a+1;i++){
            table[0][a] =  0;
            table[i][0] = 1;
            table[i][i] = 1;
        }
        for(int i=1;i<a+1;i++){
            for(int j=1;j<a+1;j++){
                if(i<j) table[i][j] = 0;
                else{
                    table[i][j] = table[i-1][j-1] + table[i-1][j];
                }
            }
        }
        return table[a][b];

    }
}

class graph{
    public static long dijkstra(int[][] G, int s, int t){
        Integer[] dist = new Integer[G.length];
        PriorityQueue<Integer> manage = new PriorityQueue<>((x,y) -> dist[x]-dist[y]);
        HashSet<Integer> searched = new HashSet<>();
        Arrays.fill(dist,Integer.MAX_VALUE);
        dist[s] = 0;
        searched.add(s);
        for(int i=0;i<G.length;i++){
            if(G[s][i]!=-1){
                dist[i] = G[s][i];
                manage.add(i);
            }
        }
        while(manage.size()>0){
            int now = manage.poll();
            searched.add(now);
            for(int i=0;i<G.length;i++){
                if(G[now][i]!=-1){
                    if(!searched.contains(i)){
                        if(dist[i]==Integer.MAX_VALUE){
                            dist[i] = dist[now] + G[now][i];
                            manage.add(i);
                        }
                        else{
                            dist[i] = Math.min(dist[i],dist[now]+G[now][i]);
                            manage.remove(i);
                            manage.add(i);
                        }
                    }
                }
            }
            if(searched.contains(t)) break;
        }

        return dist[t];
    }

    public static long[][] wf(long[][] G){
        long[][] dist = G;
        for(int i=0;i<G.length;i++){
            dist[i][i] = 0;
        }
        for(int i=0;i<G.length;i++){
            for(int j=0;j<G.length;j++){
                if(dist[i][j]==-1) dist[i][j] = 1_000_000_000;
            }
        }
        for(int i=0;i<G.length;i++){
            for(int j=0;j<G.length;j++){
                for(int k=0;k<G.length;k++){
                    dist[i][j] = Math.min(dist[i][j],dist[i][k]+dist[k][j]);
                }
            }
        }
        return dist;
    }
}


class FastScanner {
    private final InputStream in = System.in;
    private final byte[] buffer = new byte[1024];
    private int ptr = 0;
    private int buflen = 0;
    private boolean hasNextByte() {
        if (ptr < buflen) {
            return true;
        }else{
            ptr = 0;
            try {
                buflen = in.read(buffer);
            } catch (IOException e) {
                e.printStackTrace();
            }
            if (buflen <= 0) {
                return false;
            }
        }
        return true;
    }
    private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1;}
    private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126;}
    public boolean hasNext() { while(hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte();}
    public String next() {
        if (!hasNext()) throw new NoSuchElementException();
        StringBuilder sb = new StringBuilder();
        int b = readByte();
        while(isPrintableChar(b)) {
            sb.appendCodePoint(b);
            b = readByte();
        }
        return sb.toString();
    }
    public long nextLong() {
        if (!hasNext()) throw new NoSuchElementException();
        long n = 0;
        boolean minus = false;
        int b = readByte();
        if (b == '-') {
            minus = true;
            b = readByte();
        }
        if (b < '0' || '9' < b) {
            throw new NumberFormatException();
        }
        while(true){
            if ('0' <= b && b <= '9') {
                n *= 10;
                n += b - '0';
            }else if(b == -1 || !isPrintableChar(b)){
                return minus ? -n : n;
            }else{
                throw new NumberFormatException();
            }
            b = readByte();
        }
    }
    public int nextInt() {
        long nl = nextLong();
        if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException();
        return (int) nl;
    }
    public double nextDouble() { return Double.parseDouble(next());}
}