#include <iostream>
#include <vector>
#include <string>
#include <algorithm>
#include <queue>

using namespace std;

void c()
{
    string abcd;
    cin >> abcd;
    int a = abcd[0] - '0';
    int b = abcd[1] - '0';
    int c = abcd[2] - '0';
    int d = abcd[3] - '0';
    vector<int> target = {a, b, c, d};
    vector<int> operations = {0,0,0,1,1,1};
    do{
        int total = target[0];
        for(int i = 0; i < 3; i++)
        {
            if(operations[i] == 0)
            {
                total += target[i + 1];
            }else{
                total -= target[i + 1];
            }
        }
        if(total == 7)
        {
            string result;
            char op1 = operations[0] == 0 ? '+' : '-';
            char op2 = operations[1] == 0 ? '+' : '-';
            char op3 = operations[2] == 0 ? '+' : '-';
            cout << target[0] << op1 << target[1]<< op2 << target[2] << op3 << target[3] << "=7" << endl;
            return;
        }
    }while (next_permutation(operations.begin(), operations.end()));
    return;
}
//頂点構造体
struct vertex{
    vector<int> edges_to; //各エッジの接続先のノード番号
    vector<int> edges_cost;   //各エッジのコスト

    //ダイクストラ用
    bool isDone;    //確定フラグ
    int current_cost;   //現在までのこのノードへの最小コスト
    //比較関数のオーバーロード
    bool operator<(const vertex& vertex1) const {
        return  current_cost < vertex1.current_cost;
    }
    bool operator>(const vertex& vertex1) const {
        return  current_cost > vertex1.current_cost;
    }

};

//ダイクストラ法
int dijkstra_algorithm(vector<vertex> vertexes, int start, int end)
{
    for(auto &e : vertexes)
    {
        e.isDone = false;
        e.current_cost = -1;
    }
    vertexes[start].current_cost = 0;
    priority_queue<vertex, vector<vertex>, greater<vertex>> q;
    q.push(vertexes[start]);
    while(!q.empty())
    {
        vertex doneNode = q.top();
        q.pop();
        if(doneNode.isDone) continue;
        doneNode.isDone = true;
        for(int i = 0; i < doneNode.edges_to.size(); i++)
        {
            int cost = doneNode.current_cost + doneNode.edges_cost[i];
            int to = doneNode.edges_to[i];
            if(vertexes[to].current_cost < 0 || cost < vertexes[to].current_cost)
            {
                vertexes[to].current_cost = cost;
                q.push(vertexes[to]);
            }
        }
    }
    return vertexes[end].current_cost;
}

void d()
{
    int h, w;
    cin >> h >> w;
    int c[10][10];
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
            cin >> c[i][j];
        }
    }
    vector<vector<int>> a(h);
    for(int i = 0; i < h; i++)
    {
        for(int j = 0; j < w; j++)
        {
            int temp;
            cin >> temp;
            a[i].push_back(temp);
        }
    }

    //変換グラフの生成
    vector<vertex> vertexes(10);
    for(int i = 0; i < 10; i++)
    {
        for(int j = 0; j < 10; j++)
        {
            vertexes[i].edges_to.push_back(j);
            vertexes[i].edges_cost.push_back(c[i][j]);
        }
    }

    int total = 0;
    for(int i = 0; i < h; i++)
    {
        for(int j = 0; j < w; j++)
        {
            if(a[i][j] == -1) continue;
            total += dijkstra_algorithm(vertexes, a[i][j], 1);
        }
    }
    cout << total << endl;
    //int temp = dijkstra_algorithm(vertexes, 8, 1);
    //cout << temp << endl;
}

int main() {
    d();
    return 0;
}


Measured memory_bytes: 512