#include <bits/stdc++.h>

#define TYPE(c)   remove_reference_t<decltype(c)>
#define REP(i, n) for(TYPE(n) i = 0; i < n; i++)
#define FOR(v, c) for(TYPE(c.begin()) v = c.begin(); v != c.end(); v++)
#define ALL(c)    c.begin(), c.end()
#define SORT(c)   sort(ALL(c))
#define RSORT(c)  sort(ALL(c), greater<TYPE(c)::value_type>())
#define UNIQUE(c) c.erase(unique(ALL(c)), c.end())

using namespace std;
using ll = long long;

constexpr int MOD  = (int)1e9 + 7;
constexpr int INF  = (int)1e9 + 1;
constexpr ll  LINF = (ll)1e18 + 1;
template<typename T> constexpr bool chmax(T& a, const T& b)
{ if(a < b) { a = b; return true; } else { return false; } }
template<typename T> constexpr bool chmin(T& a, const T& b)
{ if(b < a) { a = b; return true; } else { return false; } }
template<typename S, typename T> ostream& operator<<(ostream &os, const pair<S, T>& p)
{ return os << "(" << p.first << "," << p.second << ")"; }
template<typename T> auto operator<<(ostream& os, const T& t)
    -> typename conditional<true, ostream&, decltype(*t.begin())>::type
{ os << "["; FOR(v, t) { if(v != t.begin()) os << ","; os << *v; } os << "]"; return os; }

class Graph {
    using ll = long long;
public:
    struct Edge {
        enum class Type { Directed, Undirected };
        int  src, dst;
        ll   cost;
        bool validity;
        Edge(const int& _src, const int& _dst, const ll& _cost = 0) :
            src(_src), dst(_dst), cost(_cost), validity(true) { }
        friend std::ostream& operator <<(std::ostream& os, const Edge& e) {
            os << "src : " << e.src << ", " << "dst : " << e.dst << ", " << "cost : " << e.cost;
            return os;
        }
    };

    struct Vertex {
        ll cost;
        explicit Vertex(const ll& _cost) : cost(_cost) { }
    };

    Graph(const int&        num_vertex,
          const Edge::Type& edge_type,
          const ll&         vertex_init_cost = (ll)1e9 + 1) :
        vertices_(num_vertex, Vertex(vertex_init_cost)),
        edges_(num_vertex),
        num_vertex_(num_vertex),
        num_edge_(0),
        total_edge_cost_(0),
        total_vertex_cost_(num_vertex * vertex_init_cost),
        edge_type_(edge_type) { }

    const std::vector<Vertex>& getVertices() const { return vertices_; }
    const std::vector<std::vector<Edge>>& getEdges() const { return edges_; }
    const ll& getTotalEdgeCost() const { return total_edge_cost_; }
    const ll& getTotalVertexCost() const { return total_vertex_cost_; }
    const int& getNumVertex() const { return num_vertex_; }
    const int& getNumEdge() const { return num_edge_; }
    const Edge::Type& getEdgeType() const { return edge_type_; }

    void setCostToAllVertex(const ll& val) {
        total_vertex_cost_ = vertices_.size() * val;
        std::fill(vertices_.begin(), vertices_.end(), Vertex(val));
    };

    void setCostToSpecificVertex(const int& index, const ll& val) {
        total_vertex_cost_ += val - vertices_[index].cost;
        vertices_[index].cost = val;
    };

    int addVertex(const ll& cost = (ll)1e9 + 1) {
        vertices_.emplace_back(cost); edges_.emplace_back();
        num_vertex_++;
        total_vertex_cost_ += cost;
        return num_vertex_ - 1;
    }

    void addEdge(const int& src, const int& dst, const ll& cost = 1) {
        edges_[src].emplace_back(src, dst, cost);
        if(edge_type_ == Edge::Type::Undirected) edges_[dst].emplace_back(dst, src, cost);
        num_edge_++;
        total_edge_cost_ += cost;
    }

    void invalidateEdge(const int& src, const int& dst) {
        auto invalidate = [&](const int& src, const int& dst) -> ll {
                              for(auto& edge : edges_[src])
                                  if(edge.dst == dst) { edge.validity = false; return edge.cost; }
                              return 0LL;
                          };
        total_edge_cost_ -= invalidate(src, dst);
        if(edge_type_ == Edge::Type::Undirected) invalidate(dst, src);
        num_edge_--;
    }

    friend std::ostream& operator <<(std::ostream& os, const Graph& g) {
        for(const auto& v : g.edges_) { for(const auto& e : v) { os << "[" << e << "]" << std::endl; } }
        return os;
    }
private:
    std::vector<Vertex>            vertices_;
    std::vector<std::vector<Edge>> edges_;
    int                            num_vertex_;
    int                            num_edge_;
    ll                             total_edge_cost_;
    ll                             total_vertex_cost_;
    const Edge::Type               edge_type_;
};

class Pt {
public:
    int x;
    int y;

    constexpr Pt() : x(0), y(0) { }
    constexpr Pt(const int& _x, const int& _y) : x(_x), y(_y) { }

    constexpr Pt(const Pt &obj) : x(obj.x), y(obj.y) { }
    Pt &operator=(const Pt &obj) { x = obj.x; y = obj.y; return *this; }

    std::vector<Pt> getAroundFourPts() const {
        std::vector<Pt> result;
        for(int hwi = -1; hwi <= 1; hwi++) {
            for(int wwi = -1; wwi <= 1; wwi++) {
                if((hwi == 0) ^ (wwi == 0)) {
                    result.emplace_back(x + wwi, y + hwi);
                }
            }
        }
        return result;
    }

    std::vector<Pt> getAroundPts() const {
        std::vector<Pt> result;
        for(int hwi = -1; hwi <= 1; hwi++) {
            for(int wwi = -1; wwi <= 1; wwi++) {
                if(hwi != 0 || wwi != 0) {
                    result.emplace_back(x + wwi, y + hwi);
                }
            }
        }
        return result;
    }

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

    constexpr Pt operator +() const {
        return *this;
    }

    constexpr Pt operator -() const {
        return{ -x, -y };
    }

    constexpr Pt operator +(const Pt& other) const {
        return{ x + other.x, y + other.y };
    }

    constexpr Pt operator +=(const Pt& other) {
        x += other.x;  y += other.y;  return *this;
    }

    constexpr Pt operator -(const Pt& other) const {
        return{ x - other.x, y - other.y };
    }

    constexpr Pt operator -=(const Pt& other) {
        x -= other.x;  y -= other.y;  return *this;
    }

    constexpr Pt operator *(int s) const {
        return{ x * s, y * s };
    }

    constexpr Pt operator *=(const Pt& other) {
        x *= other.x;  y *= other.y;  return *this;
    }

    constexpr Pt operator /(int s) const {
        return{ x / s, y / s };
    }

    constexpr Pt operator /=(const Pt& other) {
        x /= other.x;  y /= other.y;  return *this;
    }

    constexpr bool operator ==(const Pt& other) {
        return x == other.x && y == other.y;
    }

    constexpr bool operator !=(const Pt& other) {
        return !(x == other.x && y == other.y);
    }

    friend std::ostream& operator <<(std::ostream& os, const Pt& obj) {
        os << "x : " << obj.x << ", "
           << "y : " << obj.y << std::endl;
        return os;
    }
};

template <typename T>
class MyMat {
public:
    using EleMap = std::map<T, std::vector<Pt>>;

    T* data;
    uint32_t w, h;

    MyMat(const uint& _w, const uint& _h, const T& def_val = 0) :
        w(_w), h(_h) {
        data = new T[h * w]();
        if(def_val != 0) {
            for(uint i = 0; i < w * h; i++) {
                data[i] = def_val;
            }
        }
    }

    MyMat(const uint &_w, const uint &_h, const T*& _data) :
        w(_w), h(_h), data(_data) {}

    ~MyMat() { delete[] data; }

    MyMat(const MyMat &obj) : data(obj.data), w(obj.w), h(obj,h) {}
    MyMat &operator=(const MyMat &obj) { data = obj.data; w = obj.w; h = obj,h; return *this; }

    MyMat clone() {
        T* new_data = new T[h * w];
        for(int i = 0; i < h * w; i++) {
            new_data[i] = data[i];
        }
        return MyMat<T>(w, h, new_data);
    }

    void stdRead() {
        for(uint hi = 0; hi < h; hi++) {
            for(uint wi = 0; wi < w; wi++) {
                std::cin >> data[wi + hi * w];
            }
        }
    }

    template<class... A>
    EleMap searchElements(const A&... keys) const {
        auto key_list = std::initializer_list<T>{keys...};
        EleMap result;
        for(const auto& key : key_list) {
            result.insert(std::make_pair(key, std::vector<Pt>()));
        }
        for(uint hi = 0; hi < h; hi++) {
            for(uint wi = 0; wi < w; wi++) {
                for(const auto& key : key_list) {
                    if(data[wi + hi * w] == key) {
                        result[key].push_back(Pt(wi, hi));
                    }
                }
            }
        }
    }

    T& at(const uint& wi, const uint& hi) const {
        return data[wi + hi * w];
    }

    T& at(const Pt& pt) const {
        return data[pt.x + pt.y * w];
    }

    friend std::ostream& operator <<(std::ostream& os, const MyMat<T>& obj) {
        for(uint hi = 0; hi < obj.h; hi++) {
            for (uint wi = 0; wi < obj.w; wi++) {
                os << obj.data[wi + hi * obj.w] << " ";
            }
            if(hi != obj.h - 1) os << std::endl;
        }
        return os;
    }
};

/**
 *  全頂点間の最短距離を求める(Warshall-Floyd法)
 *  NOTE: 計算量O(|V|^3)
 *  @Return: array[i][j] :: 頂点iから頂点jまでの最短距離
 */
std::vector<std::vector<ll>> warshall_floyd(const Graph& g,
                                            const ll& inf_val = (ll)1e18 + 1) {
    auto& vs = g.getVertices();
    auto& es = g.getEdges();
    std::vector<std::vector<ll>> dp(vs.size(), std::vector<ll>(vs.size(), inf_val));
    for(const auto& ee : es) for(const auto& e : ee) dp[e.src][e.dst] = e.cost;
    for(size_t i = 0; i < vs.size(); i++)
        for(size_t j = 0; j < vs.size(); j++)
            for(size_t k = 0; k < vs.size(); k++)
                dp[j][k] = std::min(dp[j][k], dp[j][i] + dp[i][k]);
    return dp;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    int H, W;
    std::cin >> H >> W;

    Graph g(10, Graph::Edge::Type::Directed);

    REP(i, 10) {
        REP(j, 10) {
            int c;
            std::cin >> c;
            g.addEdge(i, j, c);
        }
    }

    MyMat<int> mat(W, H);
    mat.stdRead();

    auto dp  = warshall_floyd(g);
    auto ans = 0;
    REP(y, H) {
        REP(x, W) {
            if(mat.at(x, y) == -1 || mat.at(x, y) == 1) {
                continue;
            }
            else {
                ans += dp[mat.at(x, y)][1];
            }
        }
    }

    std::cout << ans << std::endl;

    return 0;
}


Measured memory_bytes: 384