package main

import (
	"bufio"
	"container/heap"
	"fmt"
	"os"
	"strconv"
)

var sc = bufio.NewScanner(os.Stdin)

func Scan() string {
	sc.Scan()
	return sc.Text()
}
func iScan() int {
	n, _ := strconv.Atoi(Scan())
	return n
}
func fScan() float64 {
	n, _ := strconv.ParseFloat(Scan(), 64)
	return n
}
func stringToInt(s string) int {
	n, _ := strconv.Atoi(s)
	return n
}
func SScan(n int) []string {
	a := make([]string, n)
	for i := 0; i < n; i++ {
		a[i] = Scan()
	}
	return a
}
func iSScan(n int) []int {
	a := make([]int, n)
	for i := 0; i < n; i++ {
		a[i] = iScan()
	}
	return a
}
func abs(x int) int {
	if x < 0 {
		x = -x
	}
	return x
}
func larger(a, b int) int {
	if a < b {
		return b
	} else {
		return a
	}
}
func smaller(a, b int) int {
	if a > b {
		return b
	} else {
		return a
	}
}
func max(a []int) int {
	x := a[0]
	for i := 0; i < len(a); i++ {
		if x < a[i] {
			x = a[i]
		}
	}
	return x
}
func min(a []int) int {
	x := a[0]
	for i := 0; i < len(a); i++ {
		if x > a[i] {
			x = a[i]
		}
	}
	return x
}
func sum(a []int) int {
	x := 0
	for _, v := range a {
		x += v
	}
	return x
}
func floatSum(a []float64) float64 {
	x := 0.
	for _, v := range a {
		x += v
	}
	return x
}

var mod int = 1000000007

func main() {
	buf := make([]byte, 0)
	sc.Buffer(buf, mod)
	sc.Split(bufio.ScanWords)
	h, w := iScan(), iScan()
	edges := make([][]int, 0, 9*9)
	for i := 0; i < 10; i++ {
		for j := 0; j < 10; j++ {
			edges = append(edges, []int{j, i, iScan()})
		}
	}
	nodes := nodeInitializer(10, edges)
	dijkstra(1, nodes)
	cost := make([]int, 10)
	for i := 0; i < 10; i++ {
		cost[i] = (*nodes[i]).cost
	}
	ans := 0
	for i := 0; i < h; i++ {
		for j := 0; j < w; j++ {
			a := iScan()
			if a != -1 {
				ans += cost[a]
			}
		}
	}
	fmt.Println(ans)
}

type Node struct {
	edgesTo    []int
	edgesCosts []int
	cost       int
	from       int
	name       int
	index      int
}

type PriorityQueue []*Node

func (pq PriorityQueue) Len() int { return len(pq) }
func (pq PriorityQueue) Less(i, j int) bool {
	return pq[i].cost < pq[j].cost
}
func (pq PriorityQueue) Swap(i, j int) {
	pq[i], pq[j] = pq[j], pq[i]
	pq[i].index = i
	pq[j].index = j
}
func (pq *PriorityQueue) Push(x interface{}) {
	n := len(*pq)
	item := x.(*Node)
	item.index = n
	*pq = append(*pq, item)
}
func (pq *PriorityQueue) Pop() interface{} {
	old := *pq
	n := len(old)
	item := old[n-1]
	old[n-1] = nil
	item.index = -1
	*pq = old[0 : n-1]
	return item
}
func (pq *PriorityQueue) update(item *Node, priority int) {
	item.cost = priority
	heap.Fix(pq, item.index)
}

func nodeInitializer(n int, edges [][]int) []*Node {
	nodes := make([]*Node, n)
	for i := 0; i < n; i++ {
		nodes[i] = &Node{
			edgesTo:    []int{},
			edgesCosts: []int{},
			cost:       mod * mod,
			from:       -1,
			name:       i,
			index:      i,
		}
	}
	for _, e := range edges {
		node := *nodes[e[0]]
		node.edgesTo = append(node.edgesTo, e[1])
		node.edgesCosts = append(node.edgesCosts, e[2])
		nodes[e[0]] = &node
	}
	return nodes
}

func dijkstra(s int, nodes []*Node) {
	n := len(nodes)
	pq := make(PriorityQueue, len(nodes))
	for i := 0; i < n; i++ {
		pq[i] = nodes[i]
	}
	heap.Init(&pq)
	pq.update(nodes[s], 0)
	for len(pq) != 0 {
		currentNode := heap.Pop(&pq).(*Node)
		currentCost := currentNode.cost
		for i, to := range currentNode.edgesTo {
			cost := currentCost + currentNode.edgesCosts[i]
			if cost < (*nodes[to]).cost {
				pq.update(nodes[to], cost)
				nodes[to].from = currentNode.name
			}
		}
	}
}


Measured memory_bytes: 1896