from heapq import nsmallest

from itertools import product





def calc(start, color):

    _n, _tbl, _grids = n, tbl[color], grids

    ret = 0

    for i in range(start, _n - 1, 3):

        j = 0

        while i >= 0:

            # print('calc', start, c, i, j, ret)

            ret += _tbl[_grids[i][j]]

            i -= 1

            j += 1

    for j in range((start + 1 - _n % 3) % 3, _n, 3):

        i = _n - 1

        while j < _n:

            # print('calc', start, c, i, j, ret)

            ret += _tbl[_grids[i][j]]

            i -= 1

            j += 1

    return ret





n, c = list(map(int, input().split()))

tbl = [list(map(int, input().split())) for _ in range(c)]

grids = [list(map(int, input().split())) for _ in range(n)]



tbl = list(zip(*tbl))

for row in grids:

    for i, k in enumerate(row):

        row[i] = k - 1



preliminary = []

for s in range(3):

    preliminary.append(nsmallest(3, ((calc(s, color), color) for color in range(c))))



ans = float('inf')

for (v0, c0), (v1, c1), (v2, c2) in product(*preliminary):

    if c0 == c1 or c1 == c2 or c2 == c0:

        continue

    ans = min(ans, v0 + v1 + v2)

print(ans)

from collections import defaultdict

from heapq import nsmallest

from itertools import product



n, c = list(map(int, input().split()))

tbl = [list(map(int, input().split())) for _ in range(c)]



grid_count = [defaultdict(int) for _ in range(3)]

for i in range(n):

    for j, k in enumerate(map(int, input().split())):

        grid_count[(i + j) % 3][k - 1] += 1



preliminary = [nsmallest(3, ((sum(tbl[pc][color] * cnt for pc, cnt in list(grid_count[s].items())), color)

                             for color in range(c))) for s in range(3)]



ans = float('inf')

for (v0, c0), (v1, c1), (v2, c2) in product(*preliminary):

    if c0 == c1 or c1 == c2 or c2 == c0:

        continue

    ans = min(ans, v0 + v1 + v2)

print(ans)

from heapq import nsmallest
from itertools import product


def calc(start, color):
    _n, _tbl, _grids = n, tbl[color], grids
    ret = 0
    for i in range(start, _n - 1, 3):
        j = 0
        while i >= 0:
            # print('calc', start, c, i, j, ret)
            ret += _tbl[_grids[i][j]]
            i -= 1
            j += 1
    for j in range((start + 1 - _n % 3) % 3, _n, 3):
        i = _n - 1
        while j < _n:
            # print('calc', start, c, i, j, ret)
            ret += _tbl[_grids[i][j]]
            i -= 1
            j += 1
    return ret


n, c = list(map(int, input().split()))
tbl = [list(map(int, input().split())) for _ in range(c)]
grids = [list(map(int, input().split())) for _ in range(n)]
tbl = list(zip(*tbl))
for row in grids:
    for i, k in enumerate(row):
        row[i] = k - 1
preliminary = []
for s in range(3):
    preliminary.append(nsmallest(3, ((calc(s, color), color) for color in range(c))))
ans = float("inf")
for (v0, c0), (v1, c1), (v2, c2) in product(*preliminary):
    if c0 == c1 or c1 == c2 or c2 == c0:
        continue
    ans = min(ans, v0 + v1 + v2)
print(ans)

from collections import defaultdict
from heapq import nsmallest
from itertools import product

n, c = list(map(int, input().split()))
tbl = [list(map(int, input().split())) for _ in range(c)]
grid_count = [defaultdict(int) for _ in range(3)]
for i in range(n):
    for j, k in enumerate(map(int, input().split())):
        grid_count[(i + j) % 3][k - 1] += 1
preliminary = [
    nsmallest(
        3,
        (
            (
                sum(tbl[pc][color] * cnt for pc, cnt in list(grid_count[s].items())),
                color,
            )
            for color in range(c)
        ),
    )
    for s in range(3)
]
ans = float("inf")
for (v0, c0), (v1, c1), (v2, c2) in product(*preliminary):
    if c0 == c1 or c1 == c2 or c2 == c0:
        continue
    ans = min(ans, v0 + v1 + v2)
print(ans)

+from collections import defaultdict - -def calc(start, color): -    _n, _tbl, _grids = n, tbl[color], grids -    ret = 0 -    for i in range(start, _n - 1, 3): -        j = 0 -        while i >= 0: -            # print('calc', start, c, i, j, ret) -            ret += _tbl[_grids[i][j]] -            i -= 1 -            j += 1 -    for j in range((start + 1 - _n % 3) % 3, _n, 3): -        i = _n - 1 -        while j < _n: -            # print('calc', start, c, i, j, ret) -            ret += _tbl[_grids[i][j]] -            i -= 1 -            j += 1 -    return ret - - -grids = [list(map(int, input().split())) for _ in range(n)] -tbl = list(zip(*tbl)) -for row in grids: -    for i, k in enumerate(row): -        row[i] = k - 1 -preliminary = [] -for s in range(3): -    preliminary.append(nsmallest(3, ((calc(s, color), color) for color in range(c)))) +grid_count = [defaultdict(int) for _ in range(3)] +for i in range(n): +    for j, k in enumerate(map(int, input().split())): +        grid_count[(i + j) % 3][k - 1] += 1 +preliminary = [ +    nsmallest( +        3, +        ( +            ( +                sum(tbl[pc][color] * cnt for pc, cnt in list(grid_count[s].items())), +                color, +            ) +            for color in range(c) +        ), +    ) +    for s in range(3) +]