There is a grid with N rows and N columns of squares. Let (i,j) be the square at the i-th row from the top and the j-th column from the left.
These squares have to be painted in one of the C colors from Color 1 to Color C. Initially, (i,j) is painted in Color c_{i,j}.
We say the grid is a good grid when the following condition is met for all i,j,x,y satisfying 1 \leq i,j,x,y \leq N:
 - If (i+j) \% 3=(x+y) \% 3, the color of (i,j) and the color of (x,y) are the same.
 - If (i+j) \%  3 \neq (x+y) \% 3, the color of (i,j) and the color of (x,y) are different.
Here, X \% Y represents X modulo Y.
We will repaint zero or more squares so that the grid will be a good grid.
For a square, the wrongness when the color of the square is X before repainting and Y after repainting, is D_{X,Y}.
Find the minimum possible sum of the wrongness of all the squares.

-----Constraints-----
 - 1 \leq N \leq 500
 - 3 \leq C \leq 30
 - 1 \leq D_{i,j} \leq 1000 (i \neq j),D_{i,j}=0 (i=j)
 - 1 \leq c_{i,j} \leq C
 - All values in input are integers.

-----Input-----
Input is given from Standard Input in the following format:
N C
D_{1,1} ... D_{1,C}
:
D_{C,1} ... D_{C,C}
c_{1,1} ... c_{1,N}
:
c_{N,1} ... c_{N,N}

-----Output-----
If the minimum possible sum of the wrongness of all the squares is x, print x.

-----Sample Input-----
2 3
0 1 1
1 0 1
1 4 0
1 2
3 3

-----Sample Output-----
3

 - Repaint (1,1) to Color 2. The wrongness of (1,1) becomes D_{1,2}=1.
 - Repaint (1,2) to Color 3. The wrongness of (1,2) becomes D_{2,3}=1.
 - Repaint (2,2) to Color 1. The wrongness of (2,2) becomes D_{3,1}=1.
In this case, the sum of the wrongness of all the squares is 3.
Note that D_{i,j} \neq D_{j,i} is possible.

Difficulty: interview

Starter code:

Solutions:
from collections import defaultdict
import itertools
n, c = map(int, input().split())
D = [list(map(int, input().split()))for _ in range(c)]

# 集計
diago = [defaultdict(int)for _ in range(3)]
for i in range(n):
    for j, color in enumerate(map(int, input().split())):
        color -= 1
        if (i+j) % 3 == 0:
            diago[0][color] += 1
        elif (i+j) % 3 == 1:
            diago[1][color] += 1
        else:
            diago[2][color] += 1


# 0列目をcにするときのcにするときの最小コスト
costs = [[0]*c for _ in range(3)]
for i in range(3):
    for j in range(c):
        for k, v in diago[i].items():
            costs[i][j] += D[k][j]*v

INF = 10**18
ans = INF
for trio in itertools.combinations(range(c), 3):
    for color in itertools.permutations(trio, 3):
        cost = sum(costs[i][j] for i, j in enumerate(color))
        if cost < ans:
            ans = cost
print(ans)

import sys
import math
import collections
import bisect
import copy
import itertools

# import numpy as np

sys.setrecursionlimit(10 ** 7)
INF = 10 ** 16
MOD = 10 ** 9 + 7
# MOD = 998244353

ni = lambda: int(sys.stdin.readline())
ns = lambda: list(map(int, sys.stdin.readline().split()))
na = lambda: list(map(int, sys.stdin.readline().split()))
na1 = lambda: list([int(x) - 1 for x in sys.stdin.readline().split()])


# ===CODE===


def main():
    n, c = ns()
    d = [na() for _ in range(c)]
    color = [na() for _ in range(n)]

    cnt = [[0] * c for _ in range(3)]

    for i in range(n):
        for j in range(n):
            cnt[(i + j) % 3][color[i][j] - 1] += 1

    ans = INF
    for cost in itertools.permutations(list(range(c)), 3):
        tmp_ans = 0
        for i in range(3):
            for j in range(c):
                tmp_ans += cnt[i][j] * d[j][cost[i]]
        ans = min(ans, tmp_ans)

    print(ans)


def __starting_point():
    main()

__starting_point()

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

cst = [[0,0,0] for i in range(C)]

for i in range(N):
    for j in range(N):
        cst[c[i][j]-1][(i+j)%3] += 1

ans = 10**10

for i in range(C):
    for j in range(C):
        for k in range(C):
            if i == j or i == k or j == k:
                continue
            x = [i,j,k]
            a = 0
            for l in range(3):
                for m in range(C):
                    a += D[m][x[l]]*cst[m][l]
            ans = min(ans,a)

print(ans)


N,C = list(map(int,input().split()))

discomforts = [[0]*(N+1)]
for _ in range(C):
    row = [0]
    row.extend(list(map(int,input().split())))
    discomforts.append(row)
grid = [[0]*(N+1)]
for _ in range(N):
    row = [0]
    row.extend(list(map(int,input().split())))
    grid.append(row)

color_counts = [[0]*(C+1) for i in range(3)]

for i in range(1,N+1):
    for j in range(1,N+1):
        color_counts[(i+j)%3][grid[i][j]] += 1

ans = float('inf')
for c0 in range(1,C+1):
    for c1 in range(1,C+1):
        for c2 in range(1,C+1):
            if c0 != c1 and c1 != c2 and c2 != c0:
                total = 0
                for i in range(1,C+1):
                    total += discomforts[i][c0]*color_counts[0][i]
                    total += discomforts[i][c1]*color_counts[1][i]
                    total += discomforts[i][c2]*color_counts[2][i]
                ans = min(ans,total)
print(ans)

n,c=map(int,input().split())
D=[]
for i in range(c):
    D.append(list(map(int,input().split())))
C=[]
for i in range(n):
    C.append(list(map(int,input().split())))
    
A=[[0]*c for i in range(3)]
for i in range(n):
    for j in range(n):
        a=(i+j)%3
        A[a][C[i][j]-1]+=1

ans=10**100
for a0 in range(c):
    for a1 in range(c):
        for a2 in range(c):
            if a0==a1 or a1==a2 or a2==a0:
                continue
            cnt=0
            for i in range(c):
                cnt+=D[i][a0]*A[0][i]
                cnt+=D[i][a1]*A[1][i]
                cnt+=D[i][a2]*A[2][i]
            ans=min(cnt,ans)
print(ans)

import sys
from itertools import permutations

sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7


def resolve():
    n, c = list(map(int, input().split()))
    D = [list(map(int, input().split())) for _ in range(c)]
    grid = [list(map(int, input().split())) for _ in range(n)]

    col_cnt = [[0] * c for _ in range(3)]
    for i in range(n):
        for j in range(n):
            col = grid[i][j] - 1
            col_cnt[(i + j + 2) % 3][col] += 1

    res = f_inf
    for pattern in permutations(list(range(c)), 3):
        cost = 0
        for idx, col in enumerate(pattern):
            for k in range(c):
                cnt = col_cnt[idx][k]
                cost += D[k][col] * cnt
        res = min(res, cost)
    print(res)


def __starting_point():
    resolve()

__starting_point()

import sys
def main():
  input = sys.stdin.readline
  n, c = map(int, input().split())
  d = [0 for _ in range(c)]
  for i in range(c):
    d[i] = [int(x) for x in input().split()]
  grid = [0 for _ in range(n)]
  for i in range(n):
    grid[i] = [int(x) for x in input().split()]
  
  k1, k2, k3 = [0]*c, [0]*c, [0]*c
  for i in range(n):
    for j in range(n):
      if (i+j)%3 == 1:
        k1[grid[i][j]-1] += 1
      elif (i+j)%3 == 2:
        k2[grid[i][j]-1] += 1
      else:
        k3[grid[i][j]-1] += 1
  
  key1, key2, key3 = [], [], []
  for i in range(c):
    sub1, sub2, sub3 = 0, 0, 0
    for j in range(c):
      if i == j:
        continue
      sub1 += k1[j]*d[j][i]
      sub2 += k2[j]*d[j][i]
      sub3 += k3[j]*d[j][i]
    key1.append([sub1, i])
    key2.append([sub2, i])
    key3.append([sub3, i])
  key1.sort()
  key2.sort()
  key3.sort()
  key1 = key1[:3]
  key2 = key2[:3]
  key3 = key3[:3]
  ans = pow(10, 9)
  for i in range(3):
    for j in range(3):
      for k in range(3):
        if key1[i][1] != key2[j][1] and key2[j][1] != key3[k][1] and key1[i][1] != key3[k][1]:
          if ans > key1[i][0]+key2[j][0]+key3[k][0]:
            ans = key1[i][0]+key2[j][0]+key3[k][0]
  print(ans)
  
def __starting_point():
  main()
__starting_point()

from collections import Counter
from itertools import permutations

N, C = list(map(int, input().split()))
D = [list(map(int, input().split())) for i in range(C)]
c = [list([int(s) - 1 for s in input().split()]) for i in range(N)]

d = [Counter(sum([c[j][(i - j) % 3::3] for j in range(N)], []))
     for i in range(3)]
ans = 1000000007
for t in permutations(list(range(C)), 3):
    dis = 0
    for i in range(3):
        for k, v in list(d[i].items()):
            dis += D[k][t[i]] * v
    ans = min(dis, ans)
print(ans)


from itertools import permutations

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

#グリッド座標を3種類に分ける
rem = [[] for _ in range(3)]
for i in range(N):
    for j in range(N):
        rem[(i+j+2)%3].append(c[i][j])
# print(rem)

cost = [[] for _ in range(3)]

for i in range(3):
    for s in range(C):
        tmp = 0
        for t in rem[i]:
            tmp += D[t-1][s]
        cost[i].append((tmp, s+1))

for i in cost:
    i.sort()
    i = i[:3]
 
ans = 1e10
for i in cost[0]:
    for j in cost[1]:
        for h in cost[2]:
            if i[1] != j[1] and j[1] != h[1] and h[1] != i[1]:
                ans = min(ans,i[0]+j[0]+h[0])
print(ans)

from collections import defaultdict
from itertools import permutations

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

dcnt = [defaultdict(int) for _ in range(3)]
for i, ci in enumerate(cmat, 1):
    for j, cij in enumerate(ci, 1):
        mod = (i + j) % 3
        dcnt[mod][cij - 1] += 1

ans = 10 ** 9
for color in permutations(list(range(c)), 3):
    if len(set(color)) == 3:
        tmp = 0
        for i, cnt in enumerate(dcnt):
            tmp += sum(d[k][color[i]] * cnt[k] for k in cnt)
        ans = min(ans, tmp)
print(ans)


from collections import Counter
from itertools import permutations

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

a = []
b = []

for _ in range(c):
    array = list(map(int, input().split()))
    a.append(array)

for _ in range(n):
    array = list(map(int, input().split()))
    b.append(array)


group1 = []
group2 = []
group3 = []

for i in range(n):
    for j in range(n):
        if (i + j) % 3 == 0:
            group1.append(b[i][j])
        elif (i + j) % 3 == 1:
            group2.append(b[i][j])
        else:
            group3.append(b[i][j])

g1 = Counter(group1)
g2 = Counter(group2)
g3 = Counter(group3)

sum1 = []
sum2 = []
sum3 = []


def cal(l, output):
    for i in range(c):
        s = 0
        for j in l.items():
            s += a[j[0]-1][i-1] * j[1]
        output.append(s)


li = [g1, g2, g3]
li2 = [sum1, sum2, sum3]

for i in range(3):
    cal(li[i], li2[i])

cc = list(range(c))

min_sum = 10**10
for i, j, k in permutations(cc, 3):
    sum = sum1[i] + sum2[j] + sum3[k]
    if sum < min_sum:
        min_sum = sum

print(min_sum)

n, c = list(map(int, input().split()))
D = [tuple(map(int, input().split())) for _ in range(c)]
C = [tuple([int(x)-1 for x in input().split()]) for _ in range(n)]

cols = [[0] * c for _ in range(3)]
for i in range(n):
    for j in range(n):
        c_from = C[i][j]
        cols[(i+j)%3][c_from] += 1

from itertools import permutations
d = 1000*500*500
for p0, p1, p2 in permutations(list(range(c)), 3):
    d_ = 0
    for c_from in range(c):
        d_ += cols[0][c_from]*D[c_from][p0]
        d_ += cols[1][c_from]*D[c_from][p1]
        d_ += cols[2][c_from]*D[c_from][p2]
    d = min(d, d_)
print(d)


#愚直回 ３重ループ 30x30x30x500x500=6.75*10**9 厳しいか。。。
#メモ化しとけばいける？-->python TLE, pypy3 262ms #17206796
#出現するものをカウントしておく
memo_mod = [[-1]*31 for _ in range(3)]
memo_app = [[0]*31 for _ in range(3)]

N,C = list(map(int,input().split()))
D = [list(map(int,input().split())) for _ in range(C)]
c = [list(map(int,input().split())) for _ in range(N)]
fa=float('inf')

for i in range(N):
    for j in range(N):
        memo_app[(i+j)%3][c[i][j]] +=1

for mod0 in range(1,C+1):
    for mod1 in range(1,C+1):
        for mod2 in range(1,C+1):
            if mod0 == mod1 or mod1==mod2 or mod2==mod0:
                continue
            else:
                ans = 0
                if memo_mod[0][mod0]== -1:
                    tmp = 0
                    for idx in range(1,C+1):
                        tmp += memo_app[0][idx]*D[idx-1][mod0-1]
                    ans += tmp
                else:
                    ans += memo_mod[0][mod0]

                if memo_mod[1][mod1]== -1:
                    tmp = 0
                    for idx in range(1,C+1):
                        tmp += memo_app[1][idx]*D[idx-1][mod1-1]
                    ans += tmp
                else:
                    ans += memo_mod[1][mod1]


                if memo_mod[2][mod2]== -1:
                    tmp = 0
                    for idx in range(1,C+1):
                        tmp += memo_app[2][idx]*D[idx-1][mod2-1]
                    ans += tmp
                else:
                    ans += memo_mod[2][mod2]
                fa = min(fa,ans)
print(fa)


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

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

ax = [[0 for i in range(c)] for j in range(3)]

for i in range(n):
    for j in range(n):
        x = (i+j) % 3
        ax[x][nl[i][j]-1] += 1

l = list(range(0,c))
import itertools
ll = list(itertools.permutations(l, 3))
res = float('inf')

#axを変換していくコストを全列挙
for i in ll:
    temp= 0
    for j in range(c):
        temp += ax[0][j]*dl[j][i[0]]
        temp += ax[1][j]*dl[j][i[1]]
        temp += ax[2][j]*dl[j][i[2]]
    res= min(res,temp)
print(res)

n , c = list(map(int,input().split()))
iwaka = [list(map(int,input().split())) for i in range(c)]
masu = [list(map(int,input().split())) for i in range(n)]
amari = [{} for i in range(3)]

for i in range(n):
    for j in range(n):
        amari[(i+j)%3][masu[i][j]] = amari[(i+j)%3].get(masu[i][j],0) + 1

kouho = []
for i in range(c):
    for j in range(c):
        for k in range(c):
            if i != j and j != k and k != i:
                kouho.append((i+1,j+1,k+1))
ans = 10**9
for p in kouho:
    cou = 0
    for i in range(3):
        for k , v in list(amari[i].items()):
            cou += iwaka[k-1][p[i]-1]*v
    ans = min(ans,cou)
print(ans)


n,c = map(int,input().split())
d = [list(map(int,input().split())) for i in range(c)]
s = [list(map(int,input().split())) for i in range(n)]
x = [0] * c
y = [0] * c
z = [0] * c
for i in range(n):
    for j in range(n):
        a = (i+j) % 3
        if a == 0:
            x[s[i][j]-1] += 1
        if a == 1:
            y[s[i][j]-1] += 1
        if a == 2:
            z[s[i][j]-1] += 1
ans = 10 ** 16
for i in range(c):
    for j in range(c):
        for k in range(c):
            if i != j and i != k and j != k:
                o = 0
                for l in range(c):
                    o += d[l][i] * x[l]
                p = 0
                for l in range(c):
                    p += d[l][j] * y[l]
                q = 0
                for l in range(c):
                    q += d[l][k] * z[l]
                ans = min(ans,o+p+q)
print(ans)

from itertools import permutations

N, C = map(int, input().split())

D = []
for _ in range(C):
  Ds = list(map(int, input().split()))
  D.append(Ds)

grid = []
for _ in range(N):
  c = list(map(lambda x: int(x)-1, input().split()))
  grid.append(c)

color = [[0]*C for _ in range(3)]

for i in range(N):
  for j in range(N):
    color[(i+j)%3][grid[i][j]] += 1

INF = 10**9
ans = INF

for cols in permutations(range(C), 3):
  temp = 0
  for i, Y in enumerate(cols):
    for X, cnt in enumerate(color[i]):
      temp += D[X][Y] * cnt
  ans = min(ans, temp)

print(ans)

from sys import stdin
import numpy as np
def main():
    #入力
    readline=stdin.readline
    n,max_c=map(int,readline().split())
    d=[list(map(int,readline().split())) for _ in range(max_c)]
    d=np.array(d,dtype=np.int64)
    c=[list(map(lambda x:int(x)-1,readline().split())) for _ in range(n)]

    #前処理
    color_table=np.zeros((3,max_c),dtype=np.int64)
    for i in range(n):
        for j in range(n):
            color_table[(i+j+2)%3,:]+=d[c[i][j],:]

    #全探索
    ans=float("inf")
    for i in range(max_c):
        for j in range(max_c):
            for k in range(max_c):
                if i==j or j==k or k==i:
                    continue
                ans=min(ans,color_table[0][i]+color_table[1][j]+color_table[2][k])

    print(ans)

def __starting_point():
    main()
__starting_point()

from collections import Counter
from itertools import product, permutations
def main():
    n, c = map(int, input().split())
    D = [list(map(int, input().split())) for _ in range(c)]
    C = [list(map(lambda x:int(x)-1, input().split())) for _ in range(n)]

    group = [Counter([C[i][j] for i,j in product(range(n), range(n)) if (i+j+2) %3 == k]) for k in range(3)] 
    
    ans = float('inf')
    for color in permutations(range(c), 3):
        diff = 0
        for i in range(3):
            diff += sum(D[before_color][color[i]]*count for before_color, count in group[i].items())
        ans = min(ans, diff)
    print(ans)

main()

import sys
import heapq, math
from itertools import zip_longest, permutations, combinations, combinations_with_replacement
from itertools import accumulate, dropwhile, takewhile, groupby
from functools import lru_cache
from copy import deepcopy

N, C = map(int, input().split())
CM = [list(map(int, input().split())) for _ in range(C)]
NM = [list(map(int, input().split())) for _ in range(N)]

cnt = [[0] * (C + 1) for _ in range(3)]

for i in range(N):
    for j in range(N):
        cnt[(i + j + 2) % 3][NM[i][j]] += 1

ans = 1 << 28
for i in range(1, C + 1):
    for j in range(1, C + 1):
        for k in range(1, C + 1):
            if i == j or j == k or i == k:
                continue
            c = 0
            for l in range(1, C + 1):
                c += cnt[0][l] * CM[l - 1][i - 1]
                c += cnt[1][l] * CM[l - 1][j - 1]
                c += cnt[2][l] * CM[l - 1][k - 1]
            ans = min(ans, c)

print(ans)

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

dic=[[0]*c for _ in range(3)]

for i in range(n):
    for j in range(n):
        dic[(i+j)%3][color[i][j]-1]+=1

result=10**9

for aa in range(c):
    #%0の色をaaにする
    a_cost=0
    for j in range(c):
        a_cost+=dic[0][j]*diff[j][aa]


    for bb in range(c):
        if aa!=bb:
            #%1の色をbbにする
            b_cost=0
            for j in range(c):
                b_cost+=dic[1][j]*diff[j][bb]

            for cc in range(c):
                if aa!=bb and bb!=cc and cc!=aa:
                    #%2の色をccにする
                    c_cost=0
                    for j in range(c):
                        c_cost+=dic[2][j]*diff[j][cc]
                    result=min(result,a_cost+b_cost+c_cost)

print(result)



# # coding: utf-8
# # Your code here!

# //解説
# #include <iostream>
# #define rep(i,n) for(int i=0;i<n;i++)
# using namespace std;
# int N,C,X;
# int D[33][33];
# int t[3][33];
# int main(void)
# {
#     scanf("%d%d",&N,&C);
#     rep(i,C)rep(j,C)scanf("%d",&D[i][j]);
#     rep(i,N)rep(j,N)scanf("%d",&X),t[(i+j)%3][X-1]++;
#     int res=1<<30;
#     rep(i,C)rep(j,C)if(i!=j)rep(k,C)if(i!=k&&j!=k)
#     {
#         int tt=0;
#         rep(l,C)tt+=D[l][i]*t[0][l];
#         rep(l,C)tt+=D[l][j]*t[1][l];
#         rep(l,C)tt+=D[l][k]*t[2][l];
#         if(tt<res)res=tt;
#     }
#     printf("%d\n",res);
# }


from collections import defaultdict
N,C=list(map(int,input().split()))
D=defaultdict(int)
t=defaultdict(int)

for i in range(C):
    s=list(map(int,input().split()))
    for j in range(C):
        D[(i,j)]=s[j]
for i in range(N):
    s=list(map(int,input().split()))
    for j in range(N):
        t[((i+j)%3,s[j]-1)]+=1
ans=1<<30
for i in range(C):
    for j in range(C):
        for k in range(C):
            if i!=j!=k!=i:
                res=0
                for l in range(C):res+=D[(l,i)]*t[(0,l)]
                for l in range(C):res+=D[(l,j)]*t[(1,l)]
                for l in range(C):res+=D[(l,k)]*t[(2,l)]
                ans=min(ans,res)

                
print(ans)
                



import sys
from itertools import permutations

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


def main():
    N, C = list(map(int, readline().split()))
    D = [0] * C
    for i in range(C):
        D[i] = list(map(int, readline().split()))
    G = [0] * N
    for i in range(N):
        G[i] = [int(s) - 1 for s in readline().split()]

    cost = [[0] * C for _ in range(3)]
    for x in range(N):
        for y in range(N):
            color = G[x][y]
            cost_current = cost[(x + y) % 3]
            for i in range(C):
                cost_current[i] += D[color][i]

    ans = INF
    for c1, c2, c3 in permutations(list(range(C)), 3):
        if ans > cost[0][c1] + cost[1][c2] + cost[2][c3]:
            ans = cost[0][c1] + cost[1][c2] + cost[2][c3]

    print(ans)
    return


def __starting_point():
    main()

__starting_point()

#愚直回 ３重ループ 30x30x30x500x500=6.75*10**9 厳しいか。。。
#メモ化しとけばいける？-->python TLE, pypy3 262ms #17206796
#出現するものをカウントしておく
memo_mod = [[-1]*31 for _ in range(3)]
memo_app = [[0]*31 for _ in range(3)]

N,C = list(map(int,input().split()))
D = [list(map(int,input().split())) for _ in range(C)]
c = [list(map(int,input().split())) for _ in range(N)]
fa=float('inf')

for i in range(N):
    for j in range(N):
        memo_app[(i+j)%3][c[i][j]] +=1

for mod0 in range(1,C+1):
    for mod1 in range(1,C+1):
        if mod0 == mod1:
            continue
        for mod2 in range(1,C+1):
            if  mod1==mod2 or mod2==mod0:
                continue
            else:
                ans = 0
                if memo_mod[0][mod0]== -1:
                    tmp = 0
                    for idx in range(1,C+1):
                        tmp += memo_app[0][idx]*D[idx-1][mod0-1]
                    ans += tmp
                else:
                    ans += memo_mod[0][mod0]

                if memo_mod[1][mod1]== -1:
                    tmp = 0
                    for idx in range(1,C+1):
                        tmp += memo_app[1][idx]*D[idx-1][mod1-1]
                    ans += tmp
                else:
                    ans += memo_mod[1][mod1]


                if memo_mod[2][mod2]== -1:
                    tmp = 0
                    for idx in range(1,C+1):
                        tmp += memo_app[2][idx]*D[idx-1][mod2-1]
                    ans += tmp
                else:
                    ans += memo_mod[2][mod2]
                fa = min(fa,ans)
print(fa)


# Python3 (3.4.3)
import sys
input = sys.stdin.readline

# -------------------------------------------------------------
# function
# -------------------------------------------------------------


# -------------------------------------------------------------
# main
# -------------------------------------------------------------
# 入力の C は M とする
N,M = map(int,input().split())
D = [list(map(int,input().split())) for _ in range(M)]
C = [list(map(int,input().split())) for _ in range(N)]

# X[x][y] : (i+j)%3 == x の, 初期状態での色が y(0-indexed) のマスの数
X = [[0 for _ in range(M)] for _ in range(3)]
for i in range(N):
    for j in range(N):
        x = (i+1 + j+1)%3
        y = C[i][j] - 1
        X[x][y] += 1

# Y[x][y] : (i+j)%3 == x の領域を y で塗る場合に必要なコスト
Y = [[0 for _ in range(M)] for _ in range(3)]
for i in range(3):
    for c_to in range(M):
        total = 0
        for c_from in range(M):
            total += X[i][c_from] * D[c_from][c_to]
        Y[i][c_to] = total

ans = 10**10
# 塗る色の組み合わせで全探索
for i in range(M):
    for j in range(M):
        for k in range(M):
            # 全ての色が異なる場合のみ考える
            if i != j and j != k and k != i:
                ans = min(ans, Y[0][i] +Y[1][j] + Y[2][k] )

print(ans)

import sys


def input():
    return sys.stdin.readline().strip()


sys.setrecursionlimit(20000000)

MOD = 10 ** 9 + 7
INF = float("inf")


def main():
    N, C = list(map(int, input().split()))
    D = [list(map(int, input().split())) for _ in range(C)]
    c = [list(map(int, input().split())) for _ in range(N)]
    R = [[] for _ in range(3)]

    for i in range(N):
        for j in range(N):
            r = (i + 1) + (j + 1)
            if r % 3 == 0:
                R[0].append(c[i][j])
            elif r % 3 == 1:
                R[1].append(c[i][j])
            else:
                R[2].append(c[i][j])
    Diff = [[] for _ in range(3)]
    for i in range(3):
        l = len(R[i])

        for color in range(C):
            cnt = 0
            for j in range(l):
                cnt += D[R[i][j] - 1][color]
            Diff[i].append(cnt)
    answer = INF
    for i in range(C):
        for j in range(C):
            for k in range(C):
                if i == j or j == k or k == i:
                    continue
                else:
                    ans = Diff[0][i] + Diff[1][j] + Diff[2][k]
                    if ans < answer:
                        answer = ans
    print(answer)


def __starting_point():
    main()

__starting_point()

N,C=map(int, input().split())
D=[list(map(int, input().split())) for _ in range(C)]
c=[list(map(int, input().split())) for _ in range(N)]
C0=[0]*C
C1=[0]*C
C2=[0]*C
for i in range(N):
  for j in range(N):
    if (i+j)%3==0:
      C0[c[i][j]-1]+=1
    elif (i+j)%3==1:
      C1[c[i][j]-1]+=1
    else:
      C2[c[i][j]-1]+=1
      
import itertools
A=list(itertools.permutations(range(1,C+1),3))
ans=1000*250000
for a,b,c in A:
  d=0
  for i in range(C):
    d+=C0[i]*D[i][a-1]
    d+=C1[i]*D[i][b-1]
    d+=C2[i]*D[i][c-1]
  ans=min(ans,d)
print(ans)


from collections import defaultdict

N,C = list(map(int, input().split()))
D = [tuple(map(int, input().split())) for _ in range(C)]
grid = [tuple(map(int, input().split())) for _ in range(N)]


# mod_x : (i+j)%3がxで、keyは色、valueは個数
mod_0 = defaultdict(int)
mod_1 = defaultdict(int)
mod_2 = defaultdict(int)


for i in range(N):
    for j in range(N):
        if (i+1 + j+1) % 3 == 0:
            mod_0[grid[i][j]] += 1
        elif (i+1 + j+1) % 3 == 1:
            mod_1[grid[i][j]] += 1
        elif (i+1 + j+1) % 3 == 2:
            mod_2[grid[i][j]] += 1

ans = float("inf")
# mod_0のマスにあるものをiに、mod_1のものをjに、mod_2のものをkに塗り替える
for i in range(C):
    for j in range(C):
        if i == j: continue
        for k in range(C):
            if k in [i,j]:
                continue

            total = 0
            for prev,cnt in list(mod_0.items()):
                total += D[prev-1][i] * cnt
            for prev,cnt in list(mod_1.items()):
                total += D[prev-1][j] * cnt
            for prev,cnt in list(mod_2.items()):
                total += D[prev-1][k] * cnt

            ans = min(ans, total)

print(ans)


from itertools import *
N,C = map(int,input().split())
D = [list(map(int,input().split())) for c in range(C)]
G = [list(map(int,input().split())) for n in range(N)]
H = [C*[0] for n in range(3)]

for i in range(N):
  for j,k in enumerate(G[i]):
    H[(i+j)%3][k-1]+=1

ans = float("inf")

for i in permutations(range(C),3):
  c = 0
  for j in range(3):
    for k in range(C):
      c+=D[k][i[j]]*H[j][k]
  ans = min(ans,c)

print(ans)

# 目指すグリッドは
# ABCABCABC..
# BCABCABCA..
# CABCABCAB..
# ABCABCABC..
# ...
# N = 500なので総マス数は250000
# 色の種類は30種類
# すべてのマスをあまりごとに3グループに分ける
# 各グループにおいて、各色が何マスずつあるかを計算する。250000回
# 長さ30の配列 * 3になるのであとは変更先の色をすべて試す。30 * 3回
# 隣あったマスを同じ色にすることができないため、
# グループごとに候補を3位まで用意し、3 * 3 * 3 = 27通りをすべて試す。
# 3位と4位がタイのときはどっちを取っても大丈夫

N,C = list(map(int,input().split()))

D = [[0]*C for i in range(C)] # 違和感
for i in range(C):
  D[i] = list(map(int,input().split())) # 色は0-indexで指定
  # D[i][j]で、iをjに変えるときの違和感を算出

# print(D)

groups = [[0]*C for i in range(3)]

for i in range(N):
  line = list(map(int,input().split()))
  for j in range(len(line)):
    groups[(i+j)%3][line[j] - 1] += 1

# groups[i(グループ名)][j(色 0-index)] = 該当する個数 が出来た。
# 各グループに対して、各色に塗り替えたときの違和感を計算する
pattern = [[[0]*2 for j in range(C)] for i in range(3)]
# pattern[i(グループ名)][j(色 0-index))] = 対象の色に塗り替えたときの違和感
# 30 * 30 = 900, 900 * 3 = 2700

for i in range(len(groups)):
  # グループごとのループ
  for j in range(C):
    # 変更後の色j
    iwakan = 0 # 色jに変えるときの違和感を累積
    for k in range(len(groups[i])):
      # グループiには色kがいくつあるか
      iwakan += groups[i][k] * D[k][j]
    pattern[i][j][0] = iwakan
    pattern[i][j][1] = j # あとで並び替えるため、何色に変えるかをメモしておく

for i in range(len(pattern)):
  pattern[i] = sorted(pattern[i],key = lambda x:x[0])

ans = 10 ** 9 + 7
for a in range(3): # グループ1が何位の数字を使うか
  for b in range(3): # 同2
    if pattern[0][a][1] == pattern[1][b][1]:
      continue
    for c in range(3): # 同3
      if pattern[0][a][1] == pattern[2][c][1]:
        continue
      if pattern[1][b][1] == pattern[2][c][1]:
        continue
      val = pattern[0][a][0] + pattern[1][b][0] + pattern[2][c][0]
      if val < ans:
        ans = val
print(ans)
    


from collections import defaultdict

N,C=map(int,input().split())
D=[list(map(int,input().split())) for _ in range(C)]
grid=[list(map(int,input().split())) for _ in range(N)]

mod_0=defaultdict(int)
mod_1=defaultdict(int)
mod_2=defaultdict(int)

for i in range(N):
    for j in range(N):
        n=(i+j+2)%3
        if n==0:
            mod_0[grid[i][j]]+=1
        elif n==1:
            mod_1[grid[i][j]]+=1
        else:
            mod_2[grid[i][j]]+=1

ans=float("inf")
for i in range(C):
    for j in range(C):
        if i==j:
            continue
        for k in range(C):
            if k in [i,j]:
                continue

            total=0
            for prev,cnt in mod_0.items():
                total+=D[prev-1][i]*cnt
            for prev,cnt in mod_1.items():
                total+=D[prev-1][j]*cnt
            for prev,cnt in mod_2.items():
                total+=D[prev-1][k]*cnt
            
            ans=min(ans,total)
print(ans)

import itertools


def calc(colo, target, d_mtx):
    ret = 0
    for i, item in enumerate(colo):
        ret += item * d_mtx[i][target]
    return ret


n, c = list(map(int, input().split()))
d_mtx = []
c_mtx = []

for i in range(c):
    d_mtx.append(list(map(int, input().split())))

for i in range(n):
    c_mtx.append(list(map(int, input().split())))

color = [[0] * c for _ in range(3)]

for i in range(n):
    for j in range(n):
        color[((i+1)+(j+1)) % 3][c_mtx[i][j]-1] += 1

ret = 10 ** 10
for item in itertools.permutations(list(range(c)), 3):
    tmp = 0
    for i in range(3):
        tmp += calc(color[i], item[i], d_mtx)
    ret = min(ret, tmp)

print(ret)


# D - Good Grid

from collections import defaultdict
import itertools

N, C = map(int, input().split())
D = [[0] * C for _ in range(C)]
for i in range(C):
    D[i] = list(int(d) for d in input().split())

# MOD3の世界で0,1,2ごとに、最初の値の数をカウントしておく
dict_c = [defaultdict(int) for _ in range(3)]
for i in range(N):
    c = list(int(x) for x in input().split())
    for j in range(N):
        dict_c[(i+j)%3][c[j]-1] += 1

# ここからは全探索。
# 0, 1, 2の各配列に対して、全ての色を試す(C**3)
list_C = list(range(C))
ans = 10**18
for (p, q, r) in itertools.permutations(list_C, 3):
    tmp = 0
    for i, j in enumerate((p, q, r)):
        for m, n in dict_c[i].items():
            tmp += D[m][j] * n
    ans = min(ans, tmp)

print(ans)

# 目指すグリッドは
# ABCABCABC..
# BCABCABCA..
# CABCABCAB..
# ABCABCABC..
# ...
# N = 500なので総マス数は250000
# 色の種類は30種類
# すべてのマスをあまりごとに3グループに分ける
# 各グループにおいて、各色が何マスずつあるかを計算する。250000回
# 長さ30の配列 * 3になるのであとは変更先の色をすべて試す。30 * 3回
# 隣あったマスを同じ色にすることができないため、
# グループごとに候補を3位まで用意し、3 * 2 * 1は6通りをすべて試す。
# 3位と4位がタイのときはどっちを取っても大丈夫

N,C = list(map(int,input().split()))

D = [[0]*C for i in range(C)] # 違和感
for i in range(C):
  D[i] = list(map(int,input().split())) # 色は0-indexで指定
  # D[i][j]で、iをjに変えるときの違和感を算出

# print(D)

groups = [[0]*C for i in range(3)]

for i in range(N):
  line = list(map(int,input().split()))
  for j in range(len(line)):
    groups[(i+j)%3][line[j] - 1] += 1

# groups[i(グループ名)][j(色 0-index)] = 該当する個数 が出来た。
# 各グループに対して、各色に塗り替えたときの違和感を計算する
pattern = [[[0]*2 for j in range(C)] for i in range(3)]
# pattern[i(グループ名)][j(色 0-index))] = 対象の色に塗り替えたときの違和感
# 30 * 30 = 900, 900 * 3 = 2700

for i in range(len(groups)):
  # グループごとのループ
  for j in range(C):
    # 変更後の色j
    iwakan = 0 # 色jに変えるときの違和感を累積
    for k in range(len(groups[i])):
      # グループiには色kがいくつあるか
      iwakan += groups[i][k] * D[k][j]
    pattern[i][j][0] = iwakan
    pattern[i][j][1] = j # あとで並び替えるため、何色に変えるかをメモしておく

for i in range(len(pattern)):
#  print("bef",pattern[i])
  pattern[i] = sorted(pattern[i],key = lambda x:x[0])
#  print("after",pattern[i])

ans = 10 ** 9 + 7
for a in range(3): # グループ1が何位の数字を使うか
  for b in range(3): # 同2
    if pattern[0][a][1] == pattern[1][b][1]:
      continue
    for c in range(3): # 同3
      if pattern[0][a][1] == pattern[2][c][1]:
        continue
      if pattern[1][b][1] == pattern[2][c][1]:
        continue
      val = pattern[0][a][0] + pattern[1][b][0] + pattern[2][c][0]
      if val < ans:
        ans = val
print(ans)
    


# リファクタ
from collections import defaultdict
import itertools
n, c = map(int, input().split())
D = [list(map(int, input().split()))for _ in range(c)]

# 集計
diago = [defaultdict(int)for _ in range(3)]
for i in range(n):
    for j, color in enumerate(map(int, input().split())):
        diago[(i+j) % 3][color-1] += 1

# 0列目をcにするときのcにするときの最小コスト
costs = [[0]*c for _ in range(3)]
for i in range(3):
    for j in range(c):
        for k, v in diago[i].items():
            costs[i][j] += D[k][j]*v

INF = 10**18
ans = INF
for trio in itertools.combinations(range(c), 3):
    for color in itertools.permutations(trio, 3):
        cost = sum(costs[i][j] for i, j in enumerate(color))
        if cost < ans:
            ans = cost
print(ans)

N,C=map(int,input().split())

Dmat=[]
for i in range(C):
  array=list(map(int,input().split()))
  Dmat.append(array)
#print(Dmat)

cmat=[]
for i in range(N):
  array=list(map(int,input().split()))
  cmat.append(array)
#print(cmat)
grid_list=[{},{},{}]
for i in range(N):
  for j in range(N):
    c=cmat[i][j]-1
    mod=(i+j)%3
    if c in grid_list[mod]:
      grid_list[mod][c]+=1
    else:
      grid_list[mod][c]=1
#print(grid_list)

min_cost=10**9
for i in range(C):
  for j in range(C):
    if i==j:
      continue
      
    for k in range(C):
      if i==k or j==k:
        continue
          
      cost=0 
      for c in grid_list[0]:
        num=grid_list[0][c]
        cost+=Dmat[c][i]*num
      for c in grid_list[1]:
        num=grid_list[1][c]
        cost+=Dmat[c][j]*num
      for c in grid_list[2]:
        num=grid_list[2][c]
        cost+=Dmat[c][k]*num
          
      if cost<min_cost:
        #print(i,j,k,cost)
        min_cost=cost
          
print(min_cost)

import sys
import math
from collections import deque
from itertools import permutations

sys.setrecursionlimit(1000000)
MOD = 10 ** 9 + 7
input = lambda: sys.stdin.readline().strip()
NI = lambda: int(input())
NMI = lambda: map(int, input().split())
NLI = lambda: list(NMI())
SI = lambda: input()


def main():
    N, C = NMI()
    D = [NLI() for _ in range(C)]
    grid = [list(map(lambda x: int(x)-1, NMI())) for _ in range(N)]

    grid_mod = [{i:0 for i in range(C)} for _ in range(3)]
    for h in range(N):
        for w in range(N):
            t = (h+w) % 3
            grid_mod[t][grid[h][w]] += 1

    ans = 10**10
    for colors in permutations(range(C), 3):
        diff = 0
        for i in range(3):
            for c, n in grid_mod[i].items():
                diff += D[c][colors[i]] * n
        ans = min(ans, diff)

    print(ans)


def __starting_point():
    main()
__starting_point()

import math,string,itertools,fractions,heapq,collections,re,array,bisect,sys,random,time, copy,bisect
from operator import itemgetter
from heapq import heappush, heappop
import numpy as np
from scipy.sparse.csgraph import shortest_path, floyd_warshall, dijkstra, bellman_ford, johnson
from scipy.sparse import csr_matrix

sys.setrecursionlimit(10**7)
inf = 10**20
mod = 10**9 + 7

stdin = sys.stdin

ni = lambda: int(ns())
nf = lambda: float(ns())
na = lambda: list(map(int, stdin.readline().split()))
nb = lambda: list(map(float, stdin.readline().split()))
ns = lambda: stdin.readline().rstrip()  # ignore trailing spaces

N, C = na()
D = [na() for _ in range(C)]
c = [na() for _ in range(N)]

z = {}
o = {}
t = {}
for i in range(1, N+1):
    for j in range(1, N+1):
        q = (i + j) % 3
        now = c[i - 1][j - 1] - 1
        if q == 0:
            if now not in list(z.keys()):
                z[now] = 1
            else:
                z[now] += 1
        if q == 1:
            if now not in list(o.keys()):
                o[now] = 1
            else:
                o[now] += 1
        if q == 2:
            if now not in list(t.keys()):
                t[now] = 1
            else:
                t[now] += 1

ans = inf
for i, j, l in itertools.permutations(list(range(C)), 3):
    tmp = 0
    for k, v in list(z.items()):
        tmp += v * D[k][i]
    for k, v in list(o.items()):
        tmp += v * D[k][j]
    for k, v in list(t.items()):
        tmp += v * D[k][l]
    ans = min(tmp, ans)
print(ans)



import itertools
n, cs = list(map(int, input().split()))
d = [list(map(int, input().split())) for i in range(cs)]
c = [list(map(int, input().split())) for i in range(n)]
color_count = [[0] * cs for i in range(3)]
for i, j in itertools.product(list(range(n)), repeat=2):
  color_count[(i + j) % 3][c[i][j] - 1] += 1
ans = 10**20
for t in itertools.permutations(list(range(cs)), 3):
  s = 0
  for l in range(3):
    for m in range(cs):
      s += color_count[l][m] * d[m][t[l]]
  ans = min(ans, s)
print(ans)


import itertools

N,C =map(int,input().split())
D = [0]+[[0]+list(map(int,input().split())) for i in range(C)]
c = [list(map(int,input().split())) for i in range(N)]
 
grid = [[],[],[]]
for i in range(N):
  for j in range(N):
    grid[(i+j)%3].append(c[i][j])

s = [[0]*(C+1) for i in range(3)]
 
for i in range(3):
  for j in range(1,C+1,1):
    for k in range(len(grid[i])):
      s[i][j]+=D[grid[i][k]][j]

ans = float("inf")
for p in itertools.permutations(list(range(1,C+1)),3):
  tmp = 0
  for i in range(3):
     tmp +=s[i][p[i]]
  ans = min(tmp,ans)

print(ans)

from itertools import permutations


def main():
    n, c = list(map(int, input().split()))
    d = [[int(x) for x in input().split()] for _ in range(c)]
    g = [[int(x) - 1 for x in input().split()] for _ in range(n)]
    count = [{}, {}, {}]
    for i in range(n):
        for j in range(n):
            now = g[i][j]
            index = (i + j + 2) % 3
            if now in count[index % 3]:
                count[index % 3][now] += 1
            else:
                count[index % 3][now] = 1
    answer = float("inf")
    for color in permutations([i for i in range(c)], 3):
        now_answer = 0
        for i in range(3):
            for before_color, num in list(count[i].items()):
                now_answer += d[before_color][color[i]] * num
        answer = min(answer, now_answer)
    print(answer)


def __starting_point():
    main()


__starting_point()

n, C = map(int, input().split())
d = []
for i in range(C):
    d.append(list(map(int, input().split())))
c = []
for i in range(n):
    c.append(list(map(int, input().split())))
c0 = {}
c1 = {}
c2 = {}
for i in range(0, n * 2 - 1, 3):
    for j in range(max(0, i - n + 1), min(n, i + 1)):
        c0.setdefault(c[j][i - j], 0)
        c0[c[j][i - j]] += 1
for i in range(1, n * 2 - 1, 3):
    for j in range(max(0, i - n + 1), min(n, i + 1)):
        c1.setdefault(c[j][i - j], 0)
        c1[c[j][i - j]] += 1
for i in range(2, n * 2 - 1, 3):
    for j in range(max(0, i - n + 1), min(n, i + 1)):
        c2.setdefault(c[j][i - j], 0)
        c2[c[j][i - j]] += 1
D = []
for i in range(C):
    for j in range(C):
        for k in range(C):
            if i == j or j == k or k == i:
                continue
            temp = 0
            for p, q in c0.items():
                temp += d[p - 1][i] * q
            for p, q in c1.items():
                temp += d[p - 1][j] * q
            for p, q in c2.items():
                temp += d[p - 1][k] * q
            D.append(temp)
print(min(D))

#計算量 max(N ** 2, C ** 3)
N, C = list(map(int, input().split()))
D = [0] * C
for i in range(C):
  D[i] = list(map(int, input().split()))
grid = [0] * N
for i in range(N):
  grid[i] = list(map(int, input().split()))
  
#print(D, grid) 
grid3 = [[0] * C for i in range(3)]
#grid[i][j]:3で割って余りが i のマスで、色がjであるマスの個数
for i in range(N):
  for j in range(N):
    nn = (i + j) % 3
    color = grid[i][j] - 1
    grid3[nn][color] += 1
#print(grid3)  

score = [[0] * C for i in range(3)]
#score[i][j]:3で割って余りが i のマスを、色jにするときの違和感
#3 * C * C
for j in range(C):
  for i in range(3):
    for k in range(C): 
      score[i][j] += grid3[i][k] * D[k][j]
#print(score)            
ans = 10 ** 10  
for i in range(C):
  for j in range(C):
    if i != j:
      for k in range(C):
        if (i != k) and (j != k):
          now = score[0][i] + score[1][j] + score[2][k]
          ans = min(ans, now)
print(ans)      





N,C=map(int,input().split())

Dmat=[]
for i in range(C):
  array=list(map(int,input().split()))
  Dmat.append(array)
#print(Dmat)

grid_list=[{},{},{}]
for i in range(N):
  array=list(map(int,input().split()))
  for j in range(N):
    c=array[j]-1    
    mod=(i+j)%3
    if c in grid_list[mod]:
      grid_list[mod][c]+=1
    else:
      grid_list[mod][c]=1
#print(grid_list)

min_cost=10**9
for i in range(C):
  for j in range(C):
    if i==j:
      continue
      
    for k in range(C):
      if i==k or j==k:
        continue
          
      cost=0 
      for c,num in grid_list[0].items():
        cost+=Dmat[c][i]*num
      for c,num in grid_list[1].items():
        cost+=Dmat[c][j]*num
      for c,num in grid_list[2].items():
        cost+=Dmat[c][k]*num
          
      if cost<min_cost:
        #print(i,j,k,cost)
        min_cost=cost
          
print(min_cost)

import sys
from itertools import permutations

input = sys.stdin.readline


def main():
    N, C = list(map(int, input().split()))
    D = [None] * C
    for i in range(C):
        D[i] = tuple(map(int, input().split()))
    A = [None] * N
    for i in range(N):
        A[i] = tuple(map(int, input().split()))

    R = [[0] * C for _ in range(3)]
    for i in range(N):
        for j in range(N):
            R[(i + j + 2) % 3][A[i][j] - 1] += 1

    cost = [[0] * C for _ in range(3)]
    for r in range(3):
        for Y in range(C):
            tmp = 0
            for X, num in enumerate(R[r]):
                tmp += D[X][Y] * num
            cost[r][Y] = tmp

    ans = float("inf")
    for c0, c1, c2 in permutations(list(range(C)), r=3):
        ans = min(ans, cost[0][c0] + cost[1][c1] + cost[2][c2])

    print(ans)


def __starting_point():
    main()

__starting_point()

N, C = map(int, input().split())
d = [list(map(int , input().split())) for _ in range(C)]
c = [list(map(int , input().split())) for _ in range(N)]
#print(d)
#print(c)

from collections import defaultdict
cd = [defaultdict(int), defaultdict(int), defaultdict(int)]
for i in range(N):
    for j in range(N):
        k = (i+1+j+1) % 3
        cd[k][c[i][j]] += 1

ans = 10 ** 10
import itertools
for p in itertools.permutations(list(range(C)), 3):
    iwa = 0
    for ci in cd[0].items():
        iwa += d[ci[0]-1][p[0]] * ci[1]
    for ci in cd[1].items():
        iwa += d[ci[0]-1][p[1]] * ci[1]
    for ci in cd[2].items():
        iwa += d[ci[0]-1][p[2]] * ci[1]
    ans = min(ans, iwa)
#print(cd)
print(ans)

from collections import defaultdict
import itertools

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

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

d = [defaultdict(int), defaultdict(int), defaultdict(int)]

for i in range(n):
    for j in range(n):
        r = (i + j) % 3
        d[r][C[i][j]] += 1

cost = [[0] * c for _ in range(3)]

for i in range(3):
    dic = d[i]
    for j in range(c):
        for k, v in list(dic.items()):
            cost[i][j-1] += v * D[k-1][j-1]

ans = 1e9

for i, j, k in itertools.permutations(list(range(c)), 3):
    ans = min(cost[0][i] + cost[1][j] + cost[2][k], ans)

print(ans)




import itertools


def main():
    N, C = list(map(int, input().split(' ')))
    D = [list(map(int, input().split(' '))) for _ in range(C)]
    grids = [list([int(c) - 1 for c in input().split(' ')]) for _ in range(N)]
    color_counts = [[0 for _ in range(C)] for _ in range(3)]
    for i in range(N):
        for j in range(N):
            g = ((i + 1) + (j + 1)) % 3
            c = grids[i][j]
            color_counts[g][c] += 1
    min_d = 1000 * 500 * 500
    for dest_colors in itertools.permutations(list(range(C)), 3):
        d = 0
        for g in range(3):
            for c in range(C):
                d += color_counts[g][c] * D[c][dest_colors[g]]
        min_d = min([min_d, d])
    print(min_d)


def __starting_point():
    main()

__starting_point()

import itertools as it
n,c= map(int,input().split())
dtab = []
dtab.append([0 for _ in range(c+1)])
for i in range(c):dtab.append([0] + list(map(int,input().split())))
ctab = []
ctab.append([0 for _ in range(n+1)])
for i in range(n):ctab.append([0]+list(map(int,input().split())))
ssd = [{},{},{}]
for i in range(1,n+1):
    for j in range(1,n+1):
        temp = (i+j)%3
        temp2 = ctab[i][j]
        ssd[temp][temp2] = ssd[temp].get(temp2,0) + 1
e = [i+1 for i in range(c)]
cpm = it.permutations(e, 3)
ming=999999999
for f in cpm:
    fl=list(f)
    cg = 0
    for i in range(3):
        for p in ssd[i].keys():cg += dtab[p][fl[i]] * ssd[i][p]
    ming = min(ming,cg)
print(ming)

n,c=map(int,input().split())
d=[list(map(int,input().split())) for _ in range(c)]
g0=[0]*c
g1=[0]*c
g2=[0]*c
for i in range(n):
    col=list(map(int,input().split()))
    for j in range(n):
        col[j]-=1
        if (i+j)%3==0:
            g0[col[j]]+=1
        elif (i+j)%3==1:
            g1[col[j]]+=1
        else:
            g2[col[j]]+=1
ans=10**18
for i in range(c):
    for j in range(c):
        for k in range(c):
            if i==j or j==k or i==k:
                continue
            s=0
            for l in range(c):
                s+=d[l][i]*g0[l]+d[l][j]*g1[l]+d[l][k]*g2[l]
            ans=min(ans,s)
print(ans)

# coding: utf-8
import sys
import numpy as np
from itertools import permutations

sr = lambda: sys.stdin.readline().rstrip()
ir = lambda: int(sr())
lr = lambda: list(map(int, sr().split()))

N, C = lr()
feeling = np.array([lr() for _ in range(C)])
Cij = [lr() for _ in range(N)]
three = [[0] * C for _ in range(3)]
for i in range(N):
    for j in range(N):
        remain = (i+j) % 3
        num = Cij[i][j] - 1
        three[remain][num] += 1

three = np.array(three)
answer = 10 ** 10
for X in permutations(list(range(C)), 3):
    temp = 0
    for i in range(3):
        # X[i]の色にする
        x = X[i]
        y = feeling[:, x]
        temp += (three[i] * y).sum()
    if temp < answer:
        answer = temp

print(answer)
# 13


N, C = list(map(int,input().split()))
D = [list(map(int,input().split())) for _ in range(C)]
G = [list(map(int,input().split())) for _ in range(N)]
Z = [0]*C
O = [0]*C
T = [0]*C
for x in range(N):
    for y in range(N):
        if (x+y)%3 == 0:
            Z[G[x][y]-1] += 1
        elif (x+y)%3 == 1:
            O[G[x][y]-1] += 1
        else:
            T[G[x][y]-1] += 1

ans = 10**9
for c1 in range(C):
    for c2 in range(C):
        for c3 in range(C):
            if c1 == c2 or c2 == c3 or c3 == c1:
                continue
            temp = 0
            for k in range(C):
                temp += Z[k]*D[k][c1]
            for k in range(C):
                temp += O[k]*D[k][c2]
            for k in range(C):
                temp += T[k]*D[k][c3]
            ans = min(ans,temp)

print(ans)


from collections import defaultdict

n, c = map(int, input().split())
d_s = [list(map(int, input().split())) for _ in range(c)]
c_s = [list(map(int, input().split())) for _ in range(n)]
zot = [defaultdict(int) for _ in range(3)]
for i in range(n):
    for j in range(n):
        zot[(i + j) % 3][c_s[i][j] - 1] += 1


change = [[], [] ,[]]
for i in range(3):
    for j in range(c):
        cnt = 0
        for num, cnt2 in zot[i].items():
            cnt += d_s[num][j] * cnt2
        change[i].append((cnt, j))
    change[i].sort()

ans = 10 ** 10
for z, i in change[0][:3]:
    for o, j in change[1][:3]:
        if i == j:
            continue
        for t, k in change[2][:3]:
            if k == i or k == j:
                continue
            ans = min(ans, z + o + t)
            
print(ans)

import sys
from collections import Counter
from itertools import permutations

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


def main():
    N, C = list(map(int, readline().split()))
    D = [0] * C
    for i in range(C):
        D[i] = list(map(int, readline().split()))
    G = [0] * N
    for i in range(N):
        G[i] = [int(s) - 1 for s in readline().split()]

    counter = [[0] * C for _ in range(3)]
    cost = [[0] * C for _ in range(3)]
    for x in range(N):
        for y in range(N):
            counter[(x + y) % 3][G[x][y]] += 1

    for cur_cost, cur_counter in zip(cost, counter):
        for i in range(C):
            for j in range(C):
                cur_cost[i] += cur_counter[j] * D[j][i]

    ans = INF
    for c1, c2, c3 in permutations(list(range(C)), 3):
        if ans > cost[0][c1] + cost[1][c2] + cost[2][c3]:
            ans = cost[0][c1] + cost[1][c2] + cost[2][c3]

    print(ans)
    return


def __starting_point():
    main()

__starting_point()

LI = lambda: list(map(int, input().split()))

N, C = LI()
D = [LI() for _ in range(C)]
c = [LI() for _ in range(N)]

INF = 10 ** 15


def main():
    w = [[0] * C for i in range(3)]
    for i in range(N):
        for j in range(N):
            x = (i + j) % 3
            for k in range(C):
                w[x][k] += D[c[i][j] - 1][k]
    
    ans = INF
    for i in range(C):
        for j in range(C):
            if i == j:
                continue
            for k in range(C):
                if i == k or j == k:
                    continue
                ans = min(ans, w[0][i] + w[1][j] + w[2][k])
    print(ans)


def __starting_point():
    main()

__starting_point()

#!/usr/bin python3
# -*- coding: utf-8 -*-

from collections import Counter
from itertools import permutations

n, c = list(map(int, input().split()))
d = [list(map(int,input().split())) for _ in range(c)]
ci = [[] for _ in range(3)]
for i in range(n):
    cl = list(map(int, input().split()))
    for j in range(3):
        ci[(i+j)%3].extend(cl[j::3])
for i in range(3):
    ci[i] = Counter(ci[i])

def iwa(cols):
    ret = 0
    for i in range(3):
        for x, v in list(ci[i].items()):
            ret += v * d[x-1][cols[i]]
    return ret

L = list(permutations(list(range(c)), 3))
ret = 500*500*1000
for cols in L:
    ret = min(ret, iwa(cols))
print(ret)


def main():
    from itertools import permutations

    N, C = list(map(int, input().split()))
    change_cost = [[int(x) for x in input().split()] for _ in range(C)]
    init_color = [[int(x) - 1 for x in input().split()] for _ in range(N)]

    ctr = [[0] * C for _ in range(3)]
    for r in range(N):
        for c in range(N):
            p = (r + c) % 3
            color = init_color[r][c]
            ctr[p][color] += 1

    mi = 1000 * 500 * 500 + 1
    for perm in permutations(list(range(C)), r=3):
        it = iter(perm)
        t = 0
        for p in range(3):
            color_to_be = next(it)
            for color, count in enumerate(ctr[p]):
                t += change_cost[color][color_to_be] * count
        mi = min(mi, t)
    print(mi)


def __starting_point():
    main()

__starting_point()

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

a = [[0]*c for _ in range(3)]
b = [[[0,i] for i in range(c)] for _ in range(3)]

for i in range(n):
  l = list(map(int,input().split()))
  for j in range(n):
    a[(i+j)%3][l[j]-1] += 1
    
for i in range(3):
  for k in range(c):
    b[i][k][0] = sum([a[i][t]*d[t][k] for t in range(c)])
p = [[],[],[]]
for i in range(3):
  p[i] = sorted(b[i])[:3]
m = []
for t in p[0]:
  for s in p[1]:
    for u in p[2]:
      if (t[1] != s[1]) and (t[1] != u[1]) and (s[1] != u[1]):
        m.append(t[0]+s[0]+u[0])
print(min(m))

from itertools import permutations

N,C = map(int,input().split())
D = list(list(map(int,input().split())) for _ in range(C))
c = list(list(map(int,input().split())) for _ in range(N))

rem = [[] for _ in range(3)]
for i in range(N):
    for j in range(N):
        rem[(i+j+2)%3].append(c[i][j])

cost = [[] for _ in range(3)]

for i in range(3):
    for s in range(C):
        tmp = 0
        for t in rem[i]:
            tmp += D[t-1][s]
        cost[i].append((tmp,s+1))

for i in cost:
    i.sort()
    i = i[:3]

ans = 1e10
for i in cost[0]:
    for j in cost[1]:
        for h in cost[2]:
            if i[1] != j[1] and j[1] != h[1] and h[1] != i[1]:
                ans = min(ans,i[0]+j[0]+h[0])
print(ans)

from itertools import permutations

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

a = [[0] * C for _ in range(3)]
for y in range(N):
    for x in range(N):
        t = ((x + 1) + (y + 1)) % 3
        a[t][c[y][x] - 1] += 1

result = float('inf')
for b in permutations(list(range(C)), 3):
    t = 0
    for i in range(3):
        ai = a[i]
        bi = b[i]
        for j in range(C):
            t += ai[j] * D[j][bi]
    result = min(result, t)
print(result)


#!/usr/bin/env python3

from itertools import permutations

N, C = list(map(int, input().split()))

D = [list(map(int, input().split())) for i in range(C)]
# c = [list(map(int, input().split())) for i in range(N)]

colors = [[0]*C for i in range(3)]
for i in range(N):
    tmp = list(map(int, input().split()))
    for j, color in enumerate(tmp):
        num = ((i+1) + (j+1)) % 3
        colors[num][color-1] += 1
# print(colors)

data = [[0]*C for i in range(3)]


for i in range(3):
    # color[i]
    for j in range(C):
        for k in range(C):
            data[i][k] += colors[i][j] * D[j][k]
# print(data)

ans = 10**10
for iter_ in permutations(list(range(C)), 3):
    # print(iter_)
    tmp = []
    for i, j in enumerate(iter_):
        tmp.append(data[i][j])
    ans = min(ans, sum(tmp))
print(ans)


# coding: utf-8

# https://atcoder.jp/contests/abc099/tasks
# 15:00-


def main():
    N, C = list(map(int, input().split()))
    D = [None] * C
    for i in range(C):
        D[i] = list(map(int, input().split()))

    c = [None] * N
    for i in range(N):
        c[i] = list(map(int, input().split()))
        c[i] = [x-1 for x in c[i]]  # 0-index

    STU = [[0] * C, [0] * C, [0] * C]

    for k in range(C):
        for i in range(N):
            for j in range(N):
                STU[(i+j) % 3][k] += D[c[i][j]][k]

    ans = 1000 * N * N
    for i in range(C):

        for j in range(C):
            if j == i:
                continue

            for k in range(C):
                if k == i or k == j:
                    continue
                cand = STU[0][i] + STU[1][j] + STU[2][k]

                if cand < ans:
                    ans = cand

    return ans


print((main()))


N,C = map(int, input().split())
d = [list(map(int, input().split())) for _ in range(C)]

# 3色を保持するための変数
g0=[0]*C # 斜め列1
g1=[0]*C # 斜め列2
g2=[0]*C # 斜め列3

# 以下のような斜めごとに列を3色に分けようとしたときの違和感(コスト)を考える
# □ ○ △ □
# ○ △ □ ○
# △ □ ○ △
# □ ○ △ □

for i in range(N):
    col=list(map(int,input().split()))
    # 各マスの各色を見ていく
    #   斜めの列3種類ごとに持つ色を保持しておく
    for j in range(N):
        col[j]-=1
        if (i+j)%3==0:
            g0[col[j]]+=1
        elif (i+j)%3==1:
            g1[col[j]]+=1
        else:
            g2[col[j]]+=1

ans=float('inf')
# 全探索して、何色に変えるのが最もコストが低いかを出す
for i in range(C): # g0の色(をiにした場合)
    for j in range(C): # g1の色(をjにした場合)
        for k in range(C): # g2の色(をkにした場合)
            if i==j or j==k or i==k: # g0とg1が同じ色になる、みたいなパターンはないのでその場合の色分けは考えなくて良いので飛ばす
                continue
            s=0
            for l in range(C):
                # d[l][i]*g0[l]: lの色をiに変えるのに必要なコストの合計
                #  lをiに変えるコスト * g0にあるlの色の数
                #  d[l][j], d[l][k]も同様の計算
                #    l(全色)を特定のiやjに変えたときのコストの合計を算出
                s+=d[l][i]*g0[l]+d[l][j]*g1[l]+d[l][k]*g2[l]
            ans=min(ans,s)
print(ans)

N,C = map(int,input().split())
D = [list(map(int,input().split())) for i in range(C)]
E = [list(map(int,input().split())) for i in range(N)]

from collections import Counter
ctrs = [Counter() for _ in range(3)]
for i,row in enumerate(E):
    for j,c in enumerate(row):
        ctrs[(i+j)%3][c] += 1

ans = float('inf')
from itertools import permutations
for ptn in permutations(range(1,C+1), 3):
    t = 0
    for p,c in zip(ptn,ctrs):
        for k,v in c.items():
            t += D[k-1][p-1] * v
    ans = min(ans, t)
print(ans)

import itertools

N, C = map(int, input().split())
D = [list(map(int, input().split())) for i in range(C)]
c = [list(map(int, input().split())) for i in range(N)]#kokomadeha wakaru

indices = [2, 0, 1]
count_color = [[0] * C for i in range(3)]
for i in range(N):
  idx = indices[i%3]
  for j in range(N):
    count_color[idx][c[i][j]-1] += 1#1 minus surunoha list ni awaserutame iro to amari no kakezan
    idx = (idx + 1) % 3#koreha indices wo yatteirudake
    
# 色の対応関係をC_P_3通り全て試す
ans = float('inf')
correspondence = list(itertools.permutations(range(C), 3))
# (i+j)%3のマス目をcorr[(i+j)%3]に書き換える
for corr in correspondence:
  cost = 0
  for idx in range(3): # idx : (i+j)%3
    for color in range(C):
      cost += count_color[idx][color] * D[color][corr[idx]]
  ans = min(ans, cost)

print(ans)

n, c = map(int, input().split())
d_s = [list(map(int, input().split())) for _ in range(c)]
c_s = [list(map(int, input().split())) for _ in range(n)]
zot = [[], [] ,[]]
for i in range(n):
    for j in range(n):
        zot[(i + j) % 3].append(c_s[i][j] - 1)

change = [[], [] ,[]]
for i in range(3):
    for j in range(c):
        cnt = 0
        for num in zot[i]:
            cnt += d_s[num][j]
        change[i].append((cnt, j))
    change[i].sort()
    
ans = 10 ** 10
for z, i in change[0][:3]:
    for o, j in change[1][:3]:
        if i == j:
            continue
        for t, k in change[2][:3]:
            if k == i or k == j:
                continue
            ans = min(ans, z + o + t)
            
print(ans)

from itertools import product, permutations

def main():
    N, C = list(map(int, input().split()))
    D = [list(map(int, input().split())) for _ in range(C)]
    c = [list(map(int, input().split())) for _ in range(N)]
    T = [[0] * C for _ in range(3)]
    for x, y in product(list(range(N)), repeat=2):
        r = (x + y) % 3
        for i in range(C):
            T[r][i] += D[c[x][y] - 1][i]
    Q = []
    for j in range(3):
        Q.append(sorted((t, i) for i, t in enumerate(T[j])))
    m = 10**10
    for x, y, z in product(list(range(3)), repeat=3):
        X, Y, Z = Q[0][x], Q[1][y], Q[2][z]
        if X[1] == Y[1] or Y[1] == Z[1] or Z[1] == X[1]:
            continue
        m = min(m, X[0] + Y[0] + Z[0])
    return m


print((main()))


import sys
input = sys.stdin.readline
from itertools import permutations

def main():
    N, C = map(int, input().split())
    D = [list(map(int, input().split())) for _ in range(C)]
    grid = [list(map(int, input().split())) for _ in range(N)]

    sup0 = [0] * C
    sup1 = [0] * C
    sup2 = [0] * C
    for i in range(N):
        for j in range(N):
            if (i + j) % 3 == 0:
                sup2[grid[i][j] - 1] += 1
            elif (i + j) % 3 == 1:
                sup0[grid[i][j] - 1] += 1
            elif (i + j) % 3 == 2:
                sup1[grid[i][j] - 1] += 1

    ans = 10 ** 18
    for i, j, k in permutations(range(C), 3):
        tmp = 0
        for c in range(C):
            tmp += D[c][i] * sup0[c]
            tmp += D[c][j] * sup1[c]
            tmp += D[c][k] * sup2[c]
        ans = min(ans, tmp)
    print(ans)

def __starting_point():
    main()
__starting_point()

# 色の塗り方は全部で何通りか。O(C^3)で、C^3 = 27000通り。
# 各塗り方に対していちいち計算していると最大25000マスで、これだと間に合わない。
# 3つに別れた各部分を各色に変えるコスト合計を前計算しておけば良い。O(C^3 + N^2 C)。
# 一ひねりした全探索。

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

cost = [[0 for _ in range(c)] for _ in range(3)]

for row in range(n):
    for col in range(n):
        before = init_color[row][col] - 1
        for after in range(c):
            idx = (row + col) % 3
            cost[idx][after] += change_cost[before][after]

ans = 1000 * 500 * 500 * 10
for ci in range(c):
    for cj in range(c):
        for ck in range(c):
            if (ci != cj != ck != ci):
                ans = min(ans, cost[0][ci] + cost[1][cj] + cost[2][ck])

print(ans)


import bisect, collections, copy, heapq, itertools, math, string, sys
input = lambda: sys.stdin.readline().rstrip() 
sys.setrecursionlimit(10**7)
INF = float('inf')
def I(): return int(input())
def F(): return float(input())
def SS(): return input()
def LI(): return [int(x) for x in input().split()]
def LI_(): return [int(x)-1 for x in input().split()]
def LF(): return [float(x) for x in input().split()]
def LSS(): return input().split()

def resolve():
    N, C = LI()
    D = [LI() for _ in range(C)]
    c = [LI_() for _ in range(N)]

    # 座標グループごとに、その色に塗り替えるとかかるコストを前計算
    a = [[0] * C for _ in range(3)]
    for i, j in itertools.product(list(range(N)), repeat=2):
        for k in range(C):
            a[(i+j)%3][k] += D[c[i][j]][k]

    # 座標グループごとに色の割当とそのコストを全探索
    ans = INF
    for i, j, k in itertools.permutations(list(range(C)), 3):
        ans = min(a[0][i] + a[1][j] + a[2][k], ans)

    print(ans)

def __starting_point():
    resolve()

__starting_point()

import itertools

n, cc = list(map(int, input().split()))
d = [list(map(int, input().split())) for i in range(cc)]
c = [list(map(int, input().split())) for i in range(n)]

counter = [[0 for i in range(cc)] for j in range(3)]
for i in range(n):
    for j in range(n):
        counter[(i+j)%3][c[i][j]-1] += 1

m = 250000000
for y in itertools.permutations(range(cc), 3):
    new = 0
    for i in range(3):
        for x in range(cc):
            new += counter[i][x-1]*d[x-1][y[i]]
    m = min(m, new)

print(m)

from itertools import permutations

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

a = [[0] * C for _ in range(3)]
for y in range(N):
    for x in range(N):
        t = ((x + 1) + (y + 1)) % 3
        a[t][c[y][x] - 1] += 1

result = float('inf')
for b in permutations(list(range(C)), 3):
    t = 0
    for i in range(3):
        for j in range(C):
            t += a[i][j] * D[j][b[i]]
    result = min(result, t)
print(result)


N, C = list(map(int, input().split()))
D = [list(map(int, input().split())) for _ in range(C)]
color = [list(map(int, input().split())) for _ in range(N)]

cs = [[0]*C for _ in range(3)]
for i in range(N):
  for j in range(N):
    amari = (i+j)%3
    cs[amari][color[i][j]-1] += 1

ans = 500*500*1000
for i in range(C):
  for j in range(C):
    if i == j:
      continue
    for k in range(C):
      if (i==k) or (j==k):
        continue
      now = 0
      for ci in range(C):
        now += D[ci][i] * cs[0][ci]
        now += D[ci][j] * cs[1][ci]
        now += D[ci][k] * cs[2][ci]
          
      ans = min(ans, now)
      
print(ans)


from collections import defaultdict
import itertools
n, c = list(map(int, input().split()))
D = [list(map(int, input().split()))for _ in range(c)]


# 色は0始まりで管理する

# 入力の色を受け取って、それぞれの色毎にいくつあるか
diago0 = defaultdict(int)
diago1 = defaultdict(int)
diago2 = defaultdict(int)

for i in range(n):
    for j, color in enumerate(map(int, input().split())):
        color -= 1
        if (i+j) % 3 == 0:
            diago0[color] += 1
        elif (i+j) % 3 == 1:
            diago1[color] += 1
        else:
            diago2[color] += 1


# 0列目をcにするときのcにするときの最小コスト
cost0 = [0]*c
cost1 = [0]*c
cost2 = [0]*c

for i in range(c):
    for k, v in list(diago0.items()):
        cost0[i] += D[k][i]*v
for i in range(c):
    for k, v in list(diago1.items()):
        cost1[i] += D[k][i]*v
for i in range(c):
    for k, v in list(diago2.items()):
        cost2[i] += D[k][i]*v

INF = 10**18
ans = INF
for trio in itertools.combinations(list(range(c)), 3):
    for a, b, c in itertools.permutations(trio, 3):
        cost = cost0[a]+cost1[b]+cost2[c]
        if cost < ans:
            ans = cost
print(ans)


#!/usr/bin/env python3

def main():
    n, nc = list(map(int, input().split()))
    d = [list(map(int, input().split())) for i in range(nc)]
    c = [list(map(int, input().split())) for i in range(n)]

    cnt = [[0 for _ in range(nc)] for eta in range(3)]
    for i in range(n):
        for j in range(n):
            eta = (i + j) % 3
            cnt[eta][c[i][j] - 1] += 1

    iwamin = 10 ** 9
    for c1 in range(nc):
        for c2 in range(nc):
            for c3 in range(nc):
                if len(set([c1, c2, c3])) < 3:
                    continue
                iwa = 0
                for c4 in range(nc):
                    iwa += cnt[0][c4] * d[c4][c1]
                    iwa += cnt[1][c4] * d[c4][c2]
                    iwa += cnt[2][c4] * d[c4][c3]
                iwamin = min(iwamin, iwa)
    print(iwamin)

def __starting_point():
    main()

__starting_point()

n,c=map(int,input().split())
d=[list(map(int,input().split()))for _ in range(c)]
cc=[list(map(int,input().split()))for _ in range(n)]
ans=10**15
cnt=[[0]*c for _ in range(3)]
for i in range(n):
	for j in range(n):
		cnt[(i+j)%3][cc[i][j]-1]+=1
for i in range(c):
	for j in range(c):
		for k in range(c):
			pre_ans=0
			if i==j or j==k or k==i:
				continue
			for l in range(3):
				for m in range(c):
					if l%3==0 and m!=i:
						pre_ans+=cnt[l][m]*d[m][i]
					elif l%3==1 and m!=j:
						pre_ans+=cnt[l][m]*d[m][j]
					elif l%3==2 and m!=k:
						pre_ans+=cnt[l][m]*d[m][k]
			ans=min(ans,pre_ans)
print(ans)

N, C = map(int, input().split())
D = [list(map(int, input().split())) for _ in range(C)]
grid = [list(map(int, input().split())) for _ in range(N)]
D0 = {i: 0 for i in range(C)}
D1 = {i: 0 for i in range(C)}
D2 = {i: 0 for i in range(C)}
for i in range(N):
  for j in range(N):
    if (i+j) % 3 == 0:
      D0[grid[i][j]-1] += 1
    elif (i+j) % 3 == 1:
      D1[grid[i][j]-1] += 1
    elif (i+j) % 3 == 2:
      D2[grid[i][j]-1] += 1
m = int(1e11) + 23
for i in range(C):
  for j in range(C):
    for k in range(C):
      if i != j and j != k and k != i:
        differ = 0
        for l in range(C):
          differ += D0[l] * D[l][i]
          differ += D1[l] * D[l][j]
          differ += D2[l] * D[l][k]
        if m > differ:
          m = differ
print(m)

from itertools import permutations
n, C = map(int, input().split())
d = [list(map(int, input().split())) for i in range(C)]
c = [list(map(int, input().split())) for i in range(n)]
l = [[0] * C for i in range(3)]
for i in range(n):
    for j, k in enumerate(c[i]):
        l[(i + j) % 3][k - 1] += 1
ans = float("inf")
for i in permutations(range(C), 3):
    cnt = 0
    for j in range(3):
        for k in range(C):
            cnt += d[k][i[j]] * l[j][k]
    ans = min(ans, cnt)
print(ans)

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

CC = [[0] * c for _ in range(3)]

for h, line in enumerate(C):
  for w, i in enumerate(line):
    CC[(h + w) % 3][i - 1] += 1
    
ans = 10 ** 19
for i in range(c):
  for j in range(c):
    for k in range(c):
      if i != j and j != k and k != i:
        score = 0
        score += sum(D[itr][i] * val for itr, val in enumerate(CC[0]))
        score += sum(D[itr][j] * val for itr, val in enumerate(CC[1]))
        score += sum(D[itr][k] * val for itr, val in enumerate(CC[2]))
        ans = min(ans, score)

print(ans)

from itertools import permutations
n, c = map(int, input().split())

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

lst = [[0] * c for _ in range(3)]

for i in range(n):
    for j in range(n):
        lst[(i + j) % 3][c_lst[i][j]-1] += 1
        
cnt = []

for i in range(c):
    temp = []
    for j in range(3):
        cal = 0
        for k in range(c):
            cal += lst[j][k] * d_lst[k][i]
        temp.append(cal)
    cnt.append(temp) 

 
temp = []
for l in permutations(list(range(c)), 3):
    temp.append(cnt[l[0]][0] + cnt[l[1]][1] + cnt[l[2]][2])

print(min(temp))

from itertools import permutations
n,C=map(int,input().split())
d=[list(map(int,input().split())) for _ in range(C)]
c=[list(map(int,input().split())) for _ in range(n)]
a=[[0]*C for _ in range(3)]
for i in range(n):
	for j in range(n):
		a[(i+j)%3][c[i][j]-1]+=1
ans=10**9
for v in permutations(range(C),3):
	tmp=0
	for i in range(3):
		for j in range(C):
			tmp+=a[i][j]*d[j][v[i]]
	ans=min(ans,tmp)
print(ans)

import itertools

N,C =map(int,input().split())
D = [0]+[[0]+list(map(int,input().split())) for i in range(C)]

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

grids = [[],[],[]]#振り分ける
for i in range(N):
    for j in range(N):
        grids[(i+j)%3].append(c[i][j])

iwa = [[0]*(C+1) for i in range(3)]#grids[i]を色jにした時の違和感

for i in range(3):
    for j in range(1,C+1,1):
        for k in range(len(grids[i])):
            iwa[i][j]+=D[grids[i][k]][j]

ans = float("inf")
for bits in itertools.permutations(list(range(1,C+1)),3):
    tmpans = 0
    for i in range(3):
        tmpans +=iwa[i][bits[i]]
    ans = min(tmpans,ans)

print(ans)

n,c=list(map(int,input().split()))
d=[list(map(int,input().split())) for i in range(c)]
c_=[list(map(int,input().split())) for i in range(n)]
g=[[] for i in range(3)]
for i in range(n):
    for j in range(n):
        g[(i+j+2)%3].append(c_[i][j]-1)
#print(g)
'''
for i in range(c):
    for j in range(c):
        for k in range(c):
            d[i][j]=min(d[i][j],d[i][k]+d[k][j])
print(d)
'''
f=[[] for i in range(3)]
for i in range(3):
    for j in range(c):
        x=0
        for k in g[i]:
            x+=d[k][j]
        f[i].append((j,x))
    f[i]=sorted(f[i],key=lambda x:x[1])[:3]
ans=[]
#print()
for i in f[0]:
    for j in f[1]:
        for k in f[2]:
            if i[0]!=j[0] and k[0]!=j[0] and i[0]!=k[0]:
                #print(i[0],j[0],k[0])
                #print(i[1],j[1],k[1])
                ans.append(i[1]+j[1]+k[1])
print((min(ans)))


def main():
    from sys import stdin
    def input():
        return stdin.readline().strip()
    
    n, c = map(int, input().split())
    d = [list(map(int, input().split())) for _ in range(c)]

    '''
    # if I can change the color of the same square many times
    # Warshall-Floyd algorithm
    for k in range(c):
        for i in range(c):
            for j in range(c):
                if d[i][j] > d[i][k] + d[k][j]:
                    d[i][j] = d[i][k] + d[k][j]
    '''

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

    counters = [[0] * c for _ in range(3)]
    for i in range(n):
        for j in range(n):
            counters[(i+j) % 3][color[i][j] - 1] += 1
    
    # full search
    cost = []
    for group in counters:
        l = []
        # from j to i
        for i in range(c):
            num = 0
            for j in range(c):
                num += d[j][i] * group[j]
            l.append((num, i))
        l.sort()
        cost.append(l[:3])

    ans = 10 ** 9
    for i in range(3):
        for j in range(3):
            for k in range(3):
                if cost[0][i][1] != cost[1][j][1] and cost[1][j][1] != cost[2][k][1] and cost[2][k][1] != cost[0][i][1]:
                    if ans > cost[0][i][0] + cost[1][j][0] + cost[2][k][0]:
                        ans = cost[0][i][0] + cost[1][j][0] + cost[2][k][0]
    
    print(ans)

main()

n,c = map(int,input().split())
lis = [list(map(int,input().split())) for i in range(c)]
li = [list(map(int,input().split())) for i in range(n)]
ans = 10 ** 100
cnt = [0,0,0]
masu = [[0 for i in range(c)] for j in range(3)]
for i in range(n):
    for j in range(n):
        cnt[(i+j)%3] += 1
        masu[(i+j)%3][li[i][j]-1] += 1
for i in range(c):
    for j in range(c):
        if i != j:
            for k in range(c):
                if i != k and j != k:
                    tryans = 0
                    num = [i,j,k]
                    for l in range(3):
  #                         print(num[l], masu[l])
                        for h in range(c):
                            if h != num[l]:
                                tryans += lis[h][num[l]] * masu[l][h]
                    ans = min(ans,tryans)
  #                 print(i,j,k,ans)
print(ans)

from itertools import permutations
import numpy as np
N, C = map(int, input().split())
D = np.ndarray((C, C), dtype=int)
c = np.ndarray((N, N), dtype=int)
for i in range(C):
    D[i] = list(map(int,input().split()))
for i in range(N):
    c[i] = list(map(int,input().split()))
c -= 1
acc = np.zeros((3, C), dtype=int)
for i in range(N):
    for j in range(N):
        acc[(i+j) % 3] += D[c[i][j]]
ans = float("inf")
for i,j,k in permutations(range(C), r=3):
    ans = min(ans, acc[0][i]+acc[1][j]+acc[2][k])
print(ans)

N, C = map(int, input().split())

D = []
for i in range(C):
    D.append(list(map(int, input().split())))

cc = [[0]*C for i in range(3)]
for i in range(N):
    color = list(map(int, input().split()))
    for j in range(len(color)):
        cc[(i+j)%3][color[j]-1] += 1
    
iwakan = [[[0, 0] for _ in range(C)] for _ in range(3)]

for i in range(3):
    for j in range(C):
        tmp = 0
        for k in range(len(cc[i])):
            tmp += cc[i][k]*D[k][j]
        iwakan[i][j][0] = tmp
        iwakan[i][j][1] = j

ans = 10**15
for i in range(len(iwakan)):
    iwakan[i] = sorted(iwakan[i], key=lambda x:x[0])
    
for i in range(3):
    for j in range(3):
        if(iwakan[0][i][1] == iwakan[1][j][1]):
            continue
        for k in range(3):
            if(iwakan[0][i][1] == iwakan[2][k][1]):
                continue
            if(iwakan[1][j][1] == iwakan[2][k][1]):
                continue
            ans = min(ans, iwakan[0][i][0]+iwakan[1][j][0]+iwakan[2][k][0])
            
print(ans)

import sys
import collections
import itertools

input = sys.stdin.readline


def main():
    N, C = [int(x) for x in input().split()]
    D = [[int(x) for x in input().split()] for _ in range(C)]
    c = [[int(x) for x in input().split()] for _ in range(N)]

    A = [[] for j in range(3)]

    for j in range(N):
        for i in range(N):
            A[(i + j) % 3].append(c[j][i])

    one = collections.Counter(A[0])
    two = collections.Counter(A[1])
    three = collections.Counter(A[2])

    ans = float("inf")
    for x, y, z in itertools.permutations(list(range(C)), 3):
        tmp = 0
        for k in list(one.keys()):
            tmp += D[k - 1][x] * one[k]
        for k in list(two.keys()):
            tmp += D[k - 1][y] * two[k]
        for k in list(three.keys()):
            tmp += D[k - 1][z] * three[k]

        ans = min(ans, tmp)

    print(ans)




def __starting_point():
    main()

__starting_point()

from collections import Counter
from itertools import permutations

n,c = list(map(int,input().split()))
D = []
for i in range(c):
    D.append(list(map(int,input().split())))

co = [Counter() for i in range(3)]
for i in range(n):
    C = list(map(int,input().split()))
    for j in range(n):
        co[(i+j)%3][C[j]-1] +=1
ans = 10**15
perm = permutations([i for i in range(c)],3)

for t in perm:
    temp = 0
    for i in range(3):
        color = t[i]
        for num,cnt in list(co[i].items()):
            temp += D[num][color] * cnt
    ans = min(temp,ans)
print(ans)


from itertools import permutations
n,n_color = map(int,input().split())
change_cost = [list(map(int, input().split())) for i in range(n_color)]
color_grid = [list(map(int, input().split())) for i in range(n)]

mod0_colors = [0] * n_color
mod1_colors = [0] * n_color
mod2_colors = [0] * n_color
for y in range(n):
    for x in range(n):
        color = color_grid[y][x]-1
        if (y+x+2) % 3 == 0:
            mod0_colors[color]+= 1
        elif (y+x+2) % 3 == 1:
            mod1_colors[color]+= 1
        else:
            mod2_colors[color]+= 1

mod2color_cost = [[0]*n_color for _ in range(3)]
for mod,mod_colors in enumerate([mod0_colors,mod1_colors,mod2_colors]):
    for color_to in range(n_color):
        total_cost = 0
        for color_from in range(n_color):
            cost_per_node = change_cost[color_from][color_to]
            n_node = mod_colors[color_from]
            total_cost += n_node*cost_per_node
        mod2color_cost[mod][color_to] = total_cost

ans = float('inf')
for pettern in permutations([i for i in range(n_color)],3):
    total_cost = 0
    for from_ in range(3):
        to = pettern[from_]
        total_cost += mod2color_cost[from_][to]
    ans = min(ans, total_cost)
print(ans)

n,c = map(int,input().split())
d = [list(map(int,input().split())) for i in range(c)]
l = [list(map(int,input().split())) for i in range(n)]

ll = [[0]*c for i in range(3)]

for i in range(n):
    for j in range(n):
        x = (i+j+2)%3
        ll[x][l[i][j]-1] += 1

ans = float("INF")

for i in range(c):
    for j in range(c):
        if i == j:
            continue
        for k in range(c):
            if i == k or j == k:
                continue
            count = 0
            ch = [i,j,k]
            for m in range(3):
                for t in range(c):
                    count += ll[m][t]*d[t][ch[m]]
            ans = min(ans,count)
print(ans)

N, C = map(int, input().split())
D = []
for _ in range(C):
    D.append(list(map(int, input().split())))
c = []
for _ in range(N):
    c.append(list(map(int, input().split())))
colors = [[0]*C for _ in range(3)]
for i in range(N):
    for j in range(N):
        colors[(i+j)%3][c[i][j]-1] += 1
ans = 10**10
for i in range(C):
    for j in range(C):
        if i==j:
            continue
        for k in range(C):
            if j==k or k==i:
                continue
            tmp = 0
            for l in range(C):
                tmp += colors[0][l]*D[l][i]
                tmp += colors[1][l]*D[l][j]
                tmp += colors[2][l]*D[l][k]
            ans = min(ans, tmp)
print(ans)

3
# -*- coding:utf-8 -*-

from itertools import combinations, permutations

def main():
  n, nc = list(map(int, input().split()))
  md = [list(map(int, input().split())) for _ in range(nc)]
  mc = [list([int(c)-1 for c in input().split()]) for _ in range(n)]
  cnt_c = [[0] * nc for _ in range(3)]
  
  for i in range(n):
    for j in range(n):
      cnt_c[(i + j) % 3][mc[i][j]] += 1
  
  def calc_cost(lx, itarget):
    return sum([cnt*md[i][itarget] for i, cnt in enumerate(lx)])
  
  cost = 10**9
  for inds in combinations(list(range(nc)), 3):
    for itargets in permutations(inds):
      cost = min(cost, sum([calc_cost(cnt_c[i], itarget) for i, itarget in enumerate(itargets)]))
  print(cost)
    
      
  

def __starting_point():
  main()


__starting_point()

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

D_list = [[int(i) for i in input().split()] for _ in range(c)]
c_list = [[int(i) for i in input().split()] for _ in range(n)]

c_num=[[0 for _ in range(3)] for __ in range(c)]

for a in range(n):
    for b in range(n):
        c_num[c_list[b][a]-1][(a+b+2)%3] += 1


ans = 10 ** 10
for i in range(1,c**3):
    x=i%c
    y=(i%c**2)//c
    z=i//c**2
    if x==y or y==z or z==x:
        continue
    else:
        color=[x,y,z]
        count = 0
        for s in range(3):
            for t in range(c):
                count += c_num[t][s] *D_list[t][color[s]]

        if count < ans:
            ans = count

print(ans)