unittest
{

assert( q"INPUT
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
INPUT".split( '\n' ).parse.expand.solve == 12 );

assert( q"INPUT
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
INPUT".split( '\n' ).parse.expand.solve == 0 );

assert( q"INPUT
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
INPUT".split( '\n' ).parse.expand.solve == 47 );

}



import std.conv;
import std.range;
import std.stdio;
import std.typecons;

void main()
{
	stdin.byLineCopy.parse.expand.solve.writeln;
}

auto parse( Range )( Range input )
if( isInputRange!Range && is( ElementType!Range == string ) )
{
	auto hw = input.front.split.to!( long[] );
	auto css = new long[][]( 10, 10 );
	foreach( ref cs; css )
	{
		input.popFront;
		cs = input.front.split.to!( long[] );
	}
	auto ass = new long[][]( hw[ 0 ], hw[ 1 ] );
	foreach( ref as; ass )
	{
		input.popFront;
		as = input.front.split.to!( long[] );
	}
	return tuple( css, ass );
}

auto solve( long[][] css, long[][] ass )
{
	auto ds = dijkstraEx( css, 1 );
	auto ans = 0L;
	foreach( as; ass )
	{
		foreach( a; as )
		{
			if( 0 <= a ) ans += ds[ a ];
		}
	}
	return ans;
}

// 正の重み付きグラフの始点指定最短経路探索（ダイクストラ法）
auto dijkstraEx( bool undirected = false )( long[][] css, long s )
{
	import std.container.binaryheap;
	
	auto ds = new long[ 10 ];
	ds[] = long.max;
	ds[ s ] = 0;
	
	auto queue = heapify!( ( a, b ) => b[ 1 ] < a[ 1 ] )( new Tuple!( long, long )[ 100 ], 0 );
	queue.insert( tuple( s, 0L ) );
	while( !queue.empty )
	{
		auto fi = queue.front[ 0 ];
		auto fd = queue.front[ 1 ];
		queue.popFront();
		if( ds[ fi ] < fd ) continue;
		
		for( auto ti = 0L; ti < css.length; ti++ )
		{
			if( ti == fi ) continue;
			
			auto td = fd + css[ ti ][ fi ];
			if( ds[ ti ] < td ) continue;
			
			ds[ ti ] = td;
			queue.insert( tuple( ti, td ) );
		}
	}
	return ds;
}
