CodeEff/ECCO huggingface dataset:
# Original solution
H, W = list(map(int, input().split()))

change_costs = [list(map(int, input().split())) for _ in range(10)]
# change_costsは9*9のコスト


for k in range(10):
    for i in range(10):
        for j in range(10):
            # print(k, i, j)
            change_costs[i][j] = min(change_costs[i][j], change_costs[i][k] + change_costs[k][j])
# print(change_costs)
# nums = []
cost = 0
for _ in range(H):
    nums = list(map(int, input().split()))
    for num in nums:
        if num == -1:
            cost += 0
        else:
            cost += change_costs[num][1]
    # nums.append(list(map(int, input().split())))
print(cost)


# Optimized solution
H, W = list(map(int, input().split()))
costs = [list(map(int, input().split())) for _ in range(10)]

nums = [0 for _ in range(10)]

for k in range(10):
    for i in range(10):
        for j in range(10):
            costs[i][j] = min(costs[i][j], costs[i][k] + costs[k][j])

ans = 0
for i in range(H):
    for num in list(map(int, input().split())):
        if num == -1:
            continue
        else:
            ans += costs[num][1]

print(ans)
# Original solution
import sys
from collections import Counter

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60


def main():
    H, W = list(map(int, readline().split()))
    C = [list(map(int, readline().split())) for _ in range(10)]
    A = list(map(int, read().split()))

    counter = Counter(A)

    for k in range(10):
        for i in range(10):
            for j in range(10):
                if C[i][j] > C[i][k] + C[k][j]:
                    C[i][j] = C[i][k] + C[k][j]

    ans = 0
    for n, freq in list(counter.items()):
        if n not in (-1, 1):
            ans += C[n][1] * freq

    print(ans)
    return


if __name__ == '__main__':
    main()


# Optimized solution
import sys

read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60


def main():
    H, W = list(map(int, readline().split()))
    C = [list(map(int, readline().split())) for _ in range(10)]
    A = list(map(int, read().split()))

    for k in range(10):
        for i in range(10):
            for j in range(10):
                if C[i][j] > C[i][k] + C[k][j]:
                    C[i][j] = C[i][k] + C[k][j]

    ans = 0
    for n in A:
        if n != -1:
            ans += C[n][1]

    print(ans)
    return


if __name__ == '__main__':
    main()
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        # vy += x_num
        init_adj_table[vx].append(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if adj in adj_table[current] and not visited[adj]:
            visited[adj] = True
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * v_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    v_num = x_num + y_num
    init_adj_table = [[] for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].append(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if adj in adj_table[current] and not visited[adj]:
            visited[adj] = True
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * v_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    v_num = x_num + y_num
    init_adj_table = [[] for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys
from collections import deque


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        # vy += x_num
        init_adj_table[vx].append(vy)
        # init_adj_table[vy].append(vx)

    return init_adj_table


def graph_bfs_Hungarian():
    ans = 0
    queue = list()
    prev = [-1] * y_num
    matching = [-1] * y_num

    for v in range(x_num):
        visited = [False] * y_num
        if matching[v] == -1:
            while queue:
                queue.pop()
            queue.append(v)
            prev[v] = -1
            flag = False
            while queue and not flag:
                current = queue[0]
                for adj in adj_table[current]:
                    if not flag:
                        if not visited[adj]:
                            visited[adj] = True
                            queue.append(matching[adj])
                            if matching[adj] >= 0:
                                prev[matching[adj]] = current
                            else:
                                flag = True
                                d, e = current, adj
                                while d != -1:
                                    t = matching[d]
                                    matching[d] = e
                                    # matching[e] = d
                                    d = prev[d]
                                    e = t

                queue.pop()

            if matching[v] != -1:
                ans += 1

    return ans


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    # v_num = x_num + y_num
    init_adj_table = [[] for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((graph_bfs_Hungarian()))

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].append(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if adj in adj_table[current] and not visited[adj]:
            visited[adj] = True
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * y_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    # print(matching)
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    # v_num = x_num + y_num
    init_adj_table = [[] for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].append(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if (not visited[adj]) and (adj in adj_table[current]):
            visited[adj] = True
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * y_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    # print(matching)
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    init_adj_table = [[] for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].add(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if (not visited[adj]) and (adj in adj_table[current]):
            visited[adj] = True
            # matching[adj] = -1: target in y not assigned to any of x
            # matching[adj] -> an assigned source in x
            # graph_dfs(matching[adj], matching, visited) = True indicates that source has been
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * y_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    # print(matching)
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    init_adj_table = [set() for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].add(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if (not visited[adj]) and (adj in adj_table[current]):
            visited[adj] = True
            # matching[adj] = -1: target in y not assigned to any of x
            # matching[adj] -> an assigned source in x
            # graph_dfs(matching[adj], matching, visited) = True indicates that source has been
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * y_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    # print(matching)
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    init_adj_table = [set() for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].add(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for adj in range(y_num):
        if (not visited[adj]) and (adj in adj_table[current]):
            visited[adj] = True
            # matching[adj] = -1: adj not assigned to any of x
            # graph_dfs(matching[adj], matching, visited) = True
            # indicates that source in x has been already assigned to another target in y
            if matching[adj] == -1 or graph_dfs(matching[adj], matching, visited):
                matching[adj] = current
                return True
    return False


def mbm():
    matching = [-1] * y_num
    res = 0
    for v in range(x_num):
        visited = [False] * y_num
        if graph_dfs(v, matching, visited):
            res += 1
    # print(matching)
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    init_adj_table = [set() for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-

"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def generate_adj_table(_edges):
    for edge in _edges:
        vx, vy = list(map(int, edge))
        init_adj_table[vx].add(vy)

    return init_adj_table


def graph_dfs(current, matching, visited):
    for target in range(y_num):
        if (not visited[target]) and (target in adj_table[current]):
            visited[target] = True
            # matching[target] = -1: target not assigned to any of x
            # graph_dfs(matching[target], matching, visited) = True
            # indicates that source in x has been already assigned to another target in y
            if matching[target] == -1 or graph_dfs(matching[target], matching, visited):
                matching[target] = current
                return True
    return False


def mbm():
    matching = [-1] * y_num
    res = 0
    for source in range(x_num):
        visited = [False] * y_num
        if graph_dfs(source, matching, visited):
            res += 1
    # print(matching)
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    init_adj_table = [set() for _ in range(x_num)]
    adj_table = generate_adj_table(edges)
    print((mbm()))

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def graph_dfs(current, matching, visited):
    for target in range(y_num):
        if (not visited[target]) and (target in adj_table[current]):
            visited[target] = True
            if matching[target] == -1 or graph_dfs(matching[target], matching,
                                                   visited):
                matching[target] = current
                return True
    return False


def mbm():
    res = 0
    matching = [-1] * y_num
    for source in range(x_num):
        visited = [False] * y_num
        if graph_dfs(source, matching, visited):
            res += 1
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    adj_table = [set() for _ in range(x_num)]
    for edge in edges:
        vx, vy = list(map(int, edge))
        adj_table[vx].add(vy)
    print((mbm()))
# Original solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def dfs(current, matching, visited):
    for target in range(y_num):
        if not visited[target] and target in adj_table[current]:
            visited[target] = True
            ''' Matching[target] = -1: target not assigned to any of x.
            And dfs(matching[target], matching, visited) = True
            indicates that source in x has been already assigned
            to another target in y. '''
            if matching[target] == -1 or dfs(matching[target], matching, visited):
                matching[target] = current
                return True
    return False


def mbm():
    res = 0
    matching = [-1] * y_num
    for source in range(x_num):
        visited = [False] * y_num
        if dfs(source, matching, visited):
            res += 1
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    adj_table = tuple([] for _ in range(x_num))
    for edge in edges:
        vx, vy = list(map(int, edge))
        adj_table[vx].append(vy)
    print((mbm()))

# Optimized solution
#!/usr/bin/env python
# -*- coding: utf-8 -*-
"""
input:
3 4 6
0 0
0 2
0 3
1 1
2 1
2 3

output:
3
"""

import sys


def dfs(current, matching, visited):
    for target in range(y_num):
        if not visited[target] and target in adj_table[current]:
            visited[target] = True
            ''' Matching[target] = -1: target not assigned to any of x.
            And dfs(matching[target], matching, visited) = True
            indicates that source in x has been already assigned
            to another target in y. '''
            if matching[target] == -1 or dfs(matching[target], matching, visited):
                matching[target] = current
                return True
    return False


def mbm():
    res = 0
    matching = [-1] * y_num
    for source in range(x_num):
        visited = [False] * y_num
        if dfs(source, matching, visited):
            res += 1
    return res


if __name__ == '__main__':
    _input = sys.stdin.readlines()
    x_num, y_num, e_num = list(map(int, _input[0].split()))
    edges = [x.split() for x in _input[1:]]

    adj_table = tuple(set() for _ in range(x_num))
    for edge in edges:
        vx, vy = list(map(int, edge))
        adj_table[vx].add(vy)
    print((mbm()))
# Original solution
import sys
from queue import deque

sys.setrecursionlimit(200000)


def hierarchize(source):
    global hierarchy
    hierarchy = [-1] * n
    queue = deque([(0, source)])
    while queue:
        h, v = queue.popleft()
        if hierarchy[v] != -1:
            continue
        hierarchy[v] = h
        if v == sink:
            return True
        queue.extend((h + 1, target)
                     for remain, target, _ in edges[v] if hierarchy[target] == -1 and remain)
    return False


def augment(v, limit):
    if v == sink:
        return limit
    res = 0
    for e in edges[v]:
        remain, target, idx = e
        if remain == 0 or hierarchy[v] >= hierarchy[target]:
            continue
        aug = augment(target, min(limit, remain))
        e[0] -= aug
        edges[target][idx][0] += aug
        res += aug
        limit -= aug
        if not limit:
            break
    return res


xn, yn, e = list(map(int, input().split()))
n = xn + yn + 2
sink = n - 1
edges = [[] for _ in range(n)]

hierarchy = [-1] * n

for x in range(xn):
    xi = x + 1
    edges[0].append([1, xi, 0])
    edges[xi].append([0, 0, x])
for y in range(yn):
    yi = xn + y + 1
    edges[yi].append([1, sink, y])
    edges[sink].append([0, yi, 0])

for _ in range(e):
    x, y = list(map(int, input().split()))
    xi, yi = x + 1, xn + y + 1
    ex, ey = edges[xi], edges[yi]
    lx, ly = len(ex), len(ey)
    ex.append([1, yi, ly])
    ey.append([0, xi, lx])

res = 0
while hierarchize(0):
    res += augment(0, 100)
print(res)

# Optimized solution
def dfs(s):
    return _dfs(s, set())


def _dfs(v, visited):
    for u in edges[v]:
        if u in visited:
            continue
        visited.add(u)
        if matched[u] == -1 or _dfs(matched[u], visited):
            matched[u] = v
            return True
    return False


xn, yn, e = list(map(int, input().split()))
edges = [set() for _ in range(xn)]
matched = [-1] * yn

for _ in range(e):
    x, y = list(map(int, input().split()))
    edges[x].add(y)

print((sum(map(dfs, list(range(xn))))))
# Original solution
f=0
while 1:
  n=eval(input())
  if n==0: break
  if f>0: print()
  N=[""]*n
  C=[0]*n
  for i in range(n):
    s=input()
    p=s.index(" ")
    N[i]=s[:p]
    a,b,c=list(map(int,s[p+1:].split(" ")))
    C[i]=(i,a*3+c)
  C=sorted(C,key=lambda x:(-x[1],x[0]))
  for e in C: print("".join([N[e[0]],",",str(e[1])]))
  f=1

# Optimized solution
f=0
while 1:
  n=eval(input())
  if n==0: break
  if f>0: print()
  C=[()]*n
  for i in range(n):
    s=input()
    p=s.index(" ")
    a,b,c=list(map(int,s[p+1:].split(" ")))
    C[i]=(i,a*3+c,s[:p])
  C=sorted(C,key=lambda x:(-x[1],x[0]))
  for e in C: print(e[2]+","+str(e[1]))
  f=1
# Original solution
f=0
while 1:
  n=eval(input())
  if n==0: break
  C=[()]*n
  for i in range(n):
    s=input()
    p=s.index(" ")
    a,b,c=list(map(int,s[p+1:].split(" ")))
    C[i]=(i,a*3+c,s[:p])
  C=sorted(C,key=lambda x:(-x[1]))
  if f>0: print()
  for e in C: print(e[2]+","+str(e[1]))
  f=1

# Optimized solution
f=0
while 1:
  n=eval(input())
  if n==0: break
  C=[()]*n
  for i in range(n):
    s=input().split(" ")
    C[i]=(i,int(s[1])*3+int(s[3]),s[0])
  C=sorted(C,key=lambda x:(-x[1]))
  if f>0: print()
  for e in C: print(e[2]+","+str(e[1]))
  f=1
# Original solution
c=1
while 1:
    W=int(eval(input()))
    if W==0:break
    n=int(eval(input()))
    dp=[0]*(W+1)
    for i in range(n):
        v,w = list(map(int, input().split(',')))
        for j in range(W,w-1,-1):
            dp[j]=max(dp[j-w]+v,dp[j])
    for i in range(W+1):
        if dp[W]==dp[i]:break
    print(('Case %d:\n%d\n%d'%(c,dp[W],i)))
    c+=1

# Optimized solution
c=1
while 1:
    W=int(eval(input()))
    if W==0:break
    dp=[0]*(W+1)
    for i in range(int(eval(input()))):
        v,w=list(map(int, input().split(',')))
        for j in range(W,w-1,-1):
            if dp[j]<dp[j-w]+v:dp[j]=dp[j-w]+v
    for i in range(W+1):
        if dp[W]==dp[i]:break
    print(('Case %d:\n%d\n%d'%(c,dp[W],i)))
    c+=1
# Original solution
c=0
for W in iter(input,'0'):
 c+=1
 W=int(W)
 dp=[0]*-~W
 for _ in[0]*int(eval(input())):
  v,w=list(map(int,input().split(',')))
  for i in range(W,w-1,-1):
   if dp[i]<dp[i-w]+v:dp[i]=dp[i-w]+v
 for i in range(W+1):
  if dp[W]==dp[i]:print(f'Case {c}:\n{dp[W]}\n{i}');break


# Optimized solution
c=0
for W in iter(input,'0'):
 c+=1
 W=int(W)
 dp=[0]*-~W
 for _ in[0]*int(eval(input())):
  v,w=list(map(int,input().split(',')))
  for i in range(W,w-1,-1):
   if dp[i]<dp[i-w]+v:dp[i]=dp[i-w]+v
 print(f'Case {c}:\n{dp[W]}\n{dp.index(dp[W])}')
# Original solution
c=0
for W in iter(input,'0'):
 c+=1
 W=int(W)
 d=[0]*-~W
 for _ in[0]*int(eval(input())):
  v,w=list(map(int,input().split(',')))
  for i in range(W,w-1,-1):
   if d[i]<d[i-w]+v:d[i]=d[i-w]+v
 print(f'Case {c}:\n{d[W]}\n{d.index(d[W])}')


# Optimized solution
def f():
 c=0
 for W in iter(input,'0'):
  c+=1
  W=int(W)
  d=[0]*-~W
  for _ in[0]*int(eval(input())):
   v,w=list(map(int,input().split(',')))
   for i in range(W,w-1,-1):
    if d[i]<d[i-w]+v:d[i]=d[i-w]+v
  print(f'Case {c}:\n{d[W]}\n{d.index(d[W])}')
if'__main__'==__name__:f()