CodeEff/ECCO huggingface dataset:
# Original solution
N, C = [int(x) for x in input().split()]
D = [[0] * C for _ in range(C)]
c = [[0] * N for _ in range(N)]

for i in range(C):
    D[i] = [int(x) for x in input().split()]
for i in range(N):
    c[i] = [int(x) for x in input().split()]

I = [[0, 0, 0] for _ in range(C)]


for i in range(N):
    for j in range(N):
        pattern = (i + j) % 3
        for toC in range(C):
            I[toC][pattern] += D[c[i][j] - 1][toC]


ans = 99999999999999999999
for p1 in range(C):
    for p2 in range(C):
        if p1 == p2:
            continue
        a = I[p1][0] + I[p2][1]
        for p3 in range(C):
            if p1 == p3 or p2 == p3:
                continue
            ans = min(ans, a + I[p3][2])

print(ans)


# Optimized solution
N, C = [int(x) for x in input().split()]
D = [[0] * C for _ in range(C)]
c = [[0] * N for _ in range(N)]

for i in range(C):
    D[i] = [int(x) for x in input().split()]
for i in range(N):
    c[i] = [int(x) for x in input().split()]

I = [[0, 0, 0] for _ in range(C)]

COL = [[0, 0, 0] for _ in range(C)]

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

for p in range(3):
    for toC in range(C):
        for fromC in range(C):
            I[toC][p] += D[fromC][toC] * COL[fromC][p]

# I[toC][pattern] += D[c[i][j] - 1][toC]

ans = 99999999999999999999
for p1 in range(C):
    for p2 in range(C):
        if p1 == p2:
            continue
        a = I[p1][0] + I[p2][1]
        for p3 in range(C):
            if p1 == p3 or p2 == p3:
                continue
            ans = min(ans, a + I[p3][2])

print(ans)
# Original solution
from itertools import *
N, C = list(map(int, input().split()))
D = [list(map(int, input().split())) for _ in [0]*C]
c = [list(map(int, input().split())) for _ in [0]*N]
tri = [[] for _ in [0]*3]
for i in range(1, N+1):
    for j in range(1, N+1):
        tri[(i+j) % 3] += [c[i-1][j-1] - 1]
incom = [[0]*C for _ in [0]*3]
for i in range(3):
    for color in range(C):
        incom[i][color] = sum(D[x][color] for x in tri[i])
ans = 1<<30
for p in permutations(list(range(C)), 3):
    t = sum(incom[x][y]for x,y in enumerate(p))
    if t < ans: ans = t
print(ans)

# Optimized solution
from itertools import *
N, C = list(map(int, input().split()))
D = [list(map(int, input().split())) for _ in [0]*C]
tri = [[0]*C for _ in [0]*3]
for i in range(N):
    for j,x in enumerate(map(int, input().split())):
        tri[(i+j)%3][x-1] += 1
res = 1<<30
for p in permutations(list(range(C)), 3):
    tt = sum(D[l][p[m]] * tri[m][l] for l in range(C) for m in range(3))
    if tt < res: res = tt
print(res)
# Original solution
def run(N, C, D, c):
    '''
    マス番号に応じて3色に塗る必要がある
    (i+j)%3が0, 1, 2それぞれに対して、ある色に塗るコストを計算する
    0, 1, 2それぞれのC色のコストのパターンができる
    上記コストに対してC色から3色を選択する全パターンのうち最小のコストを求める
    '''
    cost0 = {}
    cost1 = {}
    cost2 = {}
    for k in range(C):
        cost0[k] = 0
        cost1[k] = 0
        cost2[k] = 0
        for i in range(N):
            for j in range(N):
                if (i+j+2) % 3 == 0:
                    color = c[i][j] - 1
                    cost = D[color][k]
                    cost0[k] += cost
                elif (i+j+2) % 3 == 1:
                    color = c[i][j] - 1
                    cost = D[color][k]
                    cost1[k] += cost
                elif (i+j+2) % 3 == 2:
                    color = c[i][j] - 1
                    cost = D[color][k]
                    cost2[k] += cost
    ret = max(cost0.values()) + max(cost1.values()) + max(cost2.values())
    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:
                    ret = min(ret, cost0[i]+cost1[j]+cost2[k])
    return ret


def main():
    N, C = list(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())))
    print((run(N, C, D, c)))


if __name__ == '__main__':
    main()

# Optimized solution
def run(N, C, D, c):
    '''
    マス番号に応じて3色に塗る必要がある
    (i+j)%3が0, 1, 2それぞれに対して、何色が何個あるか計算しておく
    ある色に塗るコストを計算する
    0, 1, 2それぞれのC色のコストのパターンができる
    上記コストに対してC色から3色を選択する全パターンのうち最小のコストを求める
    '''
    color0 = {}
    color1 = {}
    color2 = {}
    for k in range(C):
        color0[k] = 0
        color1[k] = 0
        color2[k] = 0
    for i in range(N):
        for j in range(N):
            color = c[i][j] - 1
            if (i+j+2) % 3 == 0:
                color0[color] += 1
            elif (i+j+2) % 3 == 1:
                color1[color] += 1
            elif (i+j+2) % 3 == 2:
                color2[color] += 1
    cost0 = {}
    cost1 = {}
    cost2 = {}
    for k in range(C):
        cost0[k] = 0
        cost1[k] = 0
        cost2[k] = 0
        for i in range(C):
            cost = D[i][k]
            cost0[k] += cost * color0[i] 
            cost1[k] += cost * color1[i] 
            cost2[k] += cost * color2[i] 
    ret = max(cost0.values()) + max(cost1.values()) + max(cost2.values())
    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:
                    ret = min(ret, cost0[i]+cost1[j]+cost2[k])
    return ret


def main():
    N, C = list(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())))
    print((run(N, C, D, c)))


if __name__ == '__main__':
    main()
# Original solution
from collections import Counter,defaultdict,deque
import sys,heapq,bisect,math,itertools,string,queue
sys.setrecursionlimit(10**8)
mod = 10**9+7
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpl_str(): return list(sys.stdin.readline().split())
def inpln(n): return list(int(sys.stdin.readline()) for i in range(n))

n,C = inpl()
d = []
c = []
for i in range(C):
    d.append(inpl())
for i in range(n):
    c.append(inpl())
d0 = defaultdict(int)
d1 = defaultdict(int)
d2 = defaultdict(int)
for y in range(n):
    for x in range(n):
        if (x+y+2) % 3 == 0:
            d0[c[x][y]] += 1
        elif (x+y+2) % 3 == 1:
            d1[c[x][y]] += 1
        else:
            d2[c[x][y]] += 1
# print(d0)
# print(d1)
# print(d2)
res0 = []
res1 = []
res2 = []
for i in range(C):
    tmp = 0
    for key in list(d0.keys()):
        tmp += d[key-1][i] * d0[key]
    res0.append([i,tmp])
    tmp = 0
    for key in list(d1.keys()):
        tmp += d[key-1][i] * d1[key]
    res1.append([i,tmp])
    tmp = 0
    for key in list(d2.keys()):
        tmp += d[key-1][i] * d2[key]
    res2.append([i,tmp])
res0.sort(key=lambda x:x[1])
res1.sort(key=lambda x:x[1])
res2.sort(key=lambda x:x[1])
# print(res0)
# print(res1)
# print(res2)
ans = mod
for i in range(3):
    for j in range(3):
        for k in range(3):
            if res0[i][0] == res1[j][0] or res0[i][0] == res2[k][0] or res2[k][0] == res1[j][0]:
                continue
            ans = min(res0[i][1]+res1[j][1]+res2[k][1], ans)
print(ans)            

# Optimized solution
from collections import Counter,defaultdict,deque
import sys,heapq,bisect,math,itertools,string,queue
sys.setrecursionlimit(10**8)
mod = 10**9+7
def inp(): return int(sys.stdin.readline())
def inpl(): return list(map(int, sys.stdin.readline().split()))
def inpl_str(): return list(sys.stdin.readline().split())
def inpln(n): return list(int(sys.stdin.readline()) for i in range(n))

n,C = inpl()
d = []
c = []
for i in range(C):
    d.append(inpl())
for i in range(n):
    c.append(inpl())
d0 = defaultdict(int)
d1 = defaultdict(int)
d2 = defaultdict(int)
dd = [d0,d1,d2]
for y in range(n):
    for x in range(n):
        t = (x+y+2) % 3 
        dd[t][c[x][y]] += 1
# print(dd)
res = [[] for i in range(3)]
for i in range(C):
    for j in range(3):
        tmp = 0
        for key in list(dd[j].keys()):
            tmp += d[key-1][i] * dd[j][key]
        res[j].append([i,tmp])   
for i in range(3):
    res[i].sort(key=lambda x:x[1])
# print(res)
ans = mod
for i in range(3):
    for j in range(3):
        for k in range(3):
            if res[0][i][0] == res[1][j][0] or res[0][i][0] == res[2][k][0] or res[2][k][0] == res[1][j][0]:
                continue
            ans = min(res[0][i][1]+res[1][j][1]+res[2][k][1], ans)
print(ans)
# Original solution
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)]
    mod_0 = [0 for _ in range(C)]
    mod_1 = [0 for _ in range(C)]
    mod_2 = [0 for _ in range(C)]
    for i in range(N):
        for j in range(N):
            if (i+j)%3 == 0:
                mod_2[c[i][j]-1] += 1
            if (i+j)%3 == 1:
                mod_0[c[i][j]-1] += 1
            if (i+j)%3 == 2:
                mod_1[c[i][j]-1] += 1
    INF = 10**10
    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,sum(mod_0[n]*D[n][i] for n in range(C))+\
                              sum(mod_1[n]*D[n][j] for n in range(C))+\
                              sum(mod_2[n]*D[n][k] for n in range(C)))
    print(ans)

if __name__ == "__main__":
    main()

# Optimized solution
import sys
input = sys.stdin.readline

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)]
    mod_0 = [0 for _ in range(C)]
    mod_1 = [0 for _ in range(C)]
    mod_2 = [0 for _ in range(C)]
    for i in range(N):
        for j in range(N):
            if (i+j)%3 == 0:
                mod_2[c[i][j]-1] += 1
            if (i+j)%3 == 1:
                mod_0[c[i][j]-1] += 1
            if (i+j)%3 == 2:
                mod_1[c[i][j]-1] += 1
    INF = 10**10
    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,sum(mod_0[n]*D[n][i] for n in range(C))+\
                              sum(mod_1[n]*D[n][j] for n in range(C))+\
                              sum(mod_2[n]*D[n][k] for n in range(C)))
    print(ans)

if __name__ == "__main__":
    main()
# Original solution
import sys
input = sys.stdin.buffer.readline
from itertools import permutations

def main():
    N,C = list(map(int,input().split()))
    D = [list(map(int,input().split())) for _ in range(C)]
    col = [list(map(int,input().split())) for _ in range(N)]
    
    mod_color = [[],[],[]]
    for i in range(N):
        for j in range(N):
            mod_color[(i+j)%3].append(col[i][j]-1)

    ans = 10**10
    for x,y,z in permutations(list(range(C)),3):
        ret = 0
        for num in mod_color[0]:
            ret += D[num][x]
        for num in mod_color[1]:
            ret += D[num][y]
        for num in mod_color[2]:
            ret += D[num][z]
        ans = min(ans,ret)
        
    print(ans)
    
if __name__ == "__main__":
    main()


# Optimized solution
import sys
input = sys.stdin.buffer.readline
from itertools import permutations

def main():
    N,C = list(map(int,input().split()))
    D = [list(map(int,input().split())) for _ in range(C)]
    col = [list(map(int,input().split())) for _ in range(N)]
    
    mod_color = [[0]*C,[0]*C,[0]*C]
    for i in range(N):
        for j in range(N):
            mod_color[(i+j)%3][col[i][j]-1] += 1

    ans = 10**10
    for x,y,z in permutations(list(range(C)),3):
        ret = 0
        ret += sum(mod_color[0][i]*D[i][x] for i in range(C))
        ret += sum(mod_color[1][i]*D[i][y] for i in range(C))
        ret += sum(mod_color[2][i]*D[i][z] for i in range(C))
        ans = min(ans,ret)
        
    print(ans)
    
if __name__ == "__main__":
    main()
# Original solution
n,C = list(map(int,input().split()))
d = [[int(i) for i in input().split()] for _ in range(C)]
c = [[int(i)-1 for i in input().split()] for _ in range(n)]

cnt = [[0]*C for _ in range(3)]
for i in range(n):
    for j in range(n):
        for k in range(C):
            for r in range(3):
                if (i+j)%3 == r: cnt[r][k] += d[c[i][j]][k]

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
            ans = min(ans, cnt[0][i] + cnt[1][j] + cnt[2][k])
print(ans)

# Optimized solution
n,C = list(map(int,input().split()))
d = [[int(i) for i in input().split()] for _ in range(C)]
c = [[int(i)-1 for i in input().split()] for _ in range(n)]

cnt = [[0]*C for _ in range(3)]
for i in range(n):
    for j in range(n):
        for k in range(C):
            cnt[(i+j)%3][k] += d[c[i][j]][k]

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
            ans = min(ans, cnt[0][i] + cnt[1][j] + cnt[2][k])
print(ans)
# Original solution
N,C=list(map(int,input().split()))
D=[[int(x) for x in input().split()] for y in range(C)]
c=[[int(x)-1 for x in input().split()] for y in range(N)]

a=10**9
for c0 in range(C):
  for c1 in range(c0+1,C):
    for c2 in range(c1+1,C):
      s1,s2,s3=0,0,0
      for i in range(N):
        for j in range(N):
          m = (i+j+2)%3
          if m==0:
            s1 += D[c[i][j]][c0]
            s2 += D[c[i][j]][c1]
            s3 += D[c[i][j]][c2]
          elif m==1:
            s1 += D[c[i][j]][c1]
            s2 += D[c[i][j]][c2]
            s3 += D[c[i][j]][c0]
          else:
            s1 += D[c[i][j]][c2]
            s2 += D[c[i][j]][c0]
            s3 += D[c[i][j]][c1]
      a=min(a,s1,s2,s3)
print(a)


# Optimized solution
N,C=list(map(int,input().split()))
D=[[int(x) for x in input().split()] for y in range(C)]
c=[[int(x)-1 for x in input().split()] for y in range(N)]

d=[[0 for x in range(C)] for y in range(3)]
for i in range(N):
  for j in range(N):
    d[(i+j)%3][c[i][j]] += 1

a=10**9
for c0 in range(C):
  for c1 in range(c0+1,C):
    for c2 in range(c1+1,C):
      s1,s2,s3,s4,s5,s6=0,0,0,0,0,0
      for c in range(C):
        s1 += d[0][c]*D[c][c0]+d[1][c]*D[c][c1]+d[2][c]*D[c][c2]
        s2 += d[0][c]*D[c][c0]+d[1][c]*D[c][c2]+d[2][c]*D[c][c1]
        s3 += d[0][c]*D[c][c1]+d[1][c]*D[c][c0]+d[2][c]*D[c][c2]
        s4 += d[0][c]*D[c][c1]+d[1][c]*D[c][c2]+d[2][c]*D[c][c0]
        s5 += d[0][c]*D[c][c2]+d[1][c]*D[c][c0]+d[2][c]*D[c][c1]
        s6 += d[0][c]*D[c][c2]+d[1][c]*D[c][c1]+d[2][c]*D[c][c0]
      a=min(a,s1,s2,s3,s4,s5,s6)
print(a)
# Original solution
N,C=list(map(int,input().split()))
D=[[int(x) for x in input().split()] for y in range(C)]
c=[[int(x)-1 for x in input().split()] for y in range(N)]

d=[[0 for x in range(C)] for y in range(3)]
for i in range(N):
  for j in range(N):
    d[(i+j)%3][c[i][j]] += 1

a=10**9
for c0 in range(C):
  for c1 in range(C):
    for c2 in range(C):
      if c0==c1 or c1==c2 or c0==c2:
        continue
      s=0
      for c in range(C):
        s += d[0][c]*D[c][c0]+d[1][c]*D[c][c1]+d[2][c]*D[c][c2]
      a=min(a,s)
print(a)


# Optimized solution
N,C=list(map(int,input().split()))
D=[[int(x) for x in input().split()] for y in range(C)]
c=[[int(x)-1 for x in input().split()] for y in range(N)]

d=[[0 for x in range(C)] for y in range(3)]
for i in range(N):
  for j in range(N):
    d[(i+j)%3][c[i][j]]+=1

a=10**9
for c0 in range(C):
  for c1 in range(C):
    for c2 in range(C):
      if c0!=c1 and c1!=c2 and c0!=c2:
        a=min(a,sum([d[0][c]*D[c][c0]+d[1][c]*D[c][c1]+d[2][c]*D[c][c2] for c in range(C)]))
print(a)
# Original solution
n,c = list(map(int,input().split()))
d = [list(map(int,input().split())) for i in range(c)]
g = [list(map(int,input().split())) for i in range(n)]
# mod=0,1,2について、色iに変えた時のコストをまとめておく
cost = [[0]*c for i in range(3)]
for i in range(3):
    for j in range(c):
        cost[i][j] = sum([d[g[a][b]-1][j] for a in range(n) for b in range(n) if (a+b)%3==i])
# mod=0,1,2について、どの色で塗るか全探索
ret=10**10
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
            ret=min(ret, cost[0][i]+cost[1][j]+cost[2][k])
print(ret)

# Optimized solution
n,c = list(map(int,input().split()))
d = [list(map(int,input().split())) for i in range(c)]
g = [list(map(int,input().split())) for i in range(n)]
# mod=0,1,2について、色iに変えた時のコストをまとめておく
cost = [[0]*c for i in range(3)]
for i in range(3):
    for j in range(c):
        for a in range(n):
            for b in range(n):
                if (a+b)%3==i:
                    cost[i][j]+=d[g[a][b]-1][j]
# mod=0,1,2について、どの色で塗るか全探索
ret=10**10
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
            ret=min(ret, cost[0][i]+cost[1][j]+cost[2][k])
print(ret)
# Original solution
import itertools

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_0=[]
c_1=[]
c_2=[]

for i in range(N):
    for j in range(N):
        if (i+j+2)%3==0:
            c_0+=[c[i][j]]
        elif (i+j+2)%3==1:
            c_1+=[c[i][j]]
        else:
            c_2+=[c[i][j]]

L=[]
for i in range(C):
    L+=[i+1]

ROOP=list(itertools.permutations(L,3))


ANS=float("inf")


for i in range(len(ROOP)):
    IWA=0
    for j in c_0:
        IWA+=D[j-1][ROOP[i][0]-1]
    for j in c_1:
        IWA+=D[j-1][ROOP[i][1]-1]
    for j in c_2:
        IWA+=D[j-1][ROOP[i][2]-1]
    if ANS>IWA:
        ANS=IWA

print(ANS)
    

# Optimized solution
import itertools

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_0=[]
c_1=[]
c_2=[]

for i in range(N):
    for j in range(N):
        if (i+j+2)%3==0:
            c_0+=[c[i][j]]
        elif (i+j+2)%3==1:
            c_1+=[c[i][j]]
        else:
            c_2+=[c[i][j]]

clist_0=[0]*(C+1)
clist_1=[0]*(C+1)
clist_2=[0]*(C+1)

for i in c_0:
    clist_0[i]+=1
for i in c_1:
    clist_1[i]+=1    
for i in c_2:
    clist_2[i]+=1



L=[]
for i in range(C):
    L+=[i+1]

ROOP=list(itertools.permutations(L,3))


ANS=float("inf")


for i in range(len(ROOP)):
    IWA=0
    for j in range(1,C+1):
        IWA+=D[j-1][ROOP[i][0]-1]*clist_0[j]+D[j-1][ROOP[i][1]-1]*clist_1[j]+D[j-1][ROOP[i][2]-1]*clist_2[j]
        
    if ANS>IWA:
        ANS=IWA

print(ANS)
# Original solution
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)]
for i, j in itertools.product(list(range(n)), repeat=2):
  c[i][j] -= 1
ans = 10**20
for i, j, k in itertools.permutations(list(range(cs)), 3):
  s = 0
  for l, m in itertools.product(list(range(n)), repeat=2):
    if (l + m) % 3 == 0:
      s += d[c[l][m]][i]
    elif (l + m) % 3 == 1:
      s += d[c[l][m]][j]
    else:
      s += d[c[l][m]][k]
  ans = min(ans, s)
print(ans)


# Optimized solution
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)
# Original solution
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)]

memo = [[0 for i in range(C)]for j in range(3)]

for i in range(N):
    for j in range(N):
        cij = c[i][j]
        a = (i + j + 2) % 3
        for k in range(C):
            memo[a][k] += d[cij-1][k]

ans = float('inf')

for c1, c2, c3 in itertools.permutations(list(range(C)), 3):
    ans = min(ans, memo[0][c1] + memo[1][c2] + memo[2][c3])

print(ans)

# Optimized solution
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)]

memo = [[0 for i in range(C)]for j in range(3)]

for i in range(N):
    for j in range(N):
        cij = c[i][j]
        a = (i + j + 2) % 3
        for k in range(C):
            memo[a][k] += d[cij-1][k]

ans = 250000001

for c1, c2, c3 in itertools.permutations(list(range(C)), 3):
    ans = min(ans, memo[0][c1] + memo[1][c2] + memo[2][c3])

print(ans)
# Original solution
import itertools

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


min_diff = float("inf")
for ccs in itertools.permutations(list(range(C)), 3):
    diff = 0
    for i in range(N):
        for j in range(N):
            diff += D[c[i][j]][ccs[(i + j) % 3]]
    min_diff = min(min_diff, diff)

print(min_diff)


# Optimized solution
import itertools

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

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

diff_by_pos_color_pair = [[0 for _ in range(C)] for _ in range(3)]
for i in range(N):
    for j, color_from in enumerate([int(x) - 1 for x in input().split()]):
        # for j, color_from in enumerate([0] * N):
        pos = (i + j) % 3
        for color_to in range(C):
            diff_by_pos_color_pair[pos][color_to] += D[color_from][color_to]


min_diff = float("inf")
for ccs in itertools.permutations(list(range(C)), 3):
    diff = 0
    for pos, color in enumerate(ccs):
        diff += diff_by_pos_color_pair[pos][color]
    min_diff = min(min_diff, diff)

print(min_diff)
# Original solution
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 clr in range(1,C+1):
    for i in range(N):
        for j in range(N):
            cst[clr-1][(i+j+2)%3] += D[c[i][j]-1][clr-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
            ans = min(ans,cst[i][0]+cst[j][1]+cst[k][2])

print(ans)


# Optimized solution
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)