Problem:
 Score : 400 points    Problem Statement 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 1 2 3
0 1 1
1 0 1
1 4 0
1 2
3 3      Sample Output 1 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.       Sample Input 2 4 3
0 12 71
81 0 53
14 92 0
1 1 2 1
2 1 1 2
2 2 1 3
1 1 2 2      Sample Output 2 428

Solution (Python):
import numpy as np
N, C = map(int, input().split())
D = np.array(list(map(int, input().split())), dtype=int)
for i in range(C-1):
    D = np.vstack((D, np.array(list(map(int, input().split())), dtype=int)))
Z = np.array(list(map(int, input().split())), dtype=int)
for i in range(N-1):
    Z = np.vstack((Z, np.array(list(map(int, input().split())), dtype=int)))
num = np.zeros((3,C), dtype=int)
for i in range(3):
    X = np.array([[(x+y+2)%3==i for y in range(N)] for x in range(N)])
    for c in range(C):
        Y = ((Z*X)==(c+1))
        num[i,c] = Y.sum()
costs = np.dot(num, D)
mincost = 10**10
for c0 in range(C):
    for c1 in range(C):
        if c1 ==c0:
            continue
        for c2 in range(C):
            if c2 == c0 or c2 == c1:
                continue
            cost = costs[0,c0]+costs[1,c1]+costs[2,c2]
            mincost = min(mincost, cost)
print(mincost)

Solution (Python):
N,C=map(int,input().split())
s=[list(map(int,input().split())) for i in range(C)]
t=[[0]*C for i in range(3)]
ll,kk=[],[[0]*C for i in range(3)]
for k in range(N):
    for i,j in enumerate(list(map(int,input().split()))):
        t[(i+k)%3][j-1]+=1
for j in range(3):
    for i in range(C):
        for k in range(C):
            kk[j][k]+=(s[i][k]*t[j][i])
from itertools import permutations
ans=10**9
for i,j,k in permutations(range(C),3):
    p=kk[0][i]+kk[1][j]+kk[2][k]
    ans=min(ans,kk[0][i]+kk[1][j]+kk[2][k])
print(ans)

Solution (Python):
import numpy as np
ans=10**9
N,C=map(int,input().split())
s=[list(map(int,input().split())) for i in range(C)]
t=[list(map(int,input().split())) for i in range(N)]
u=[np.zeros((C)) for i in range(3)]
for i in range(N):
    for j in range(N):
        u[(i+j)%3]+=np.array(s[t[i][j]-1])
from itertools import permutations
for i,j,k in list(permutations(range(C),3)):
    p=u[0][i]+u[1][j]+u[2][k]
    ans=min(ans,p)
print(int(ans))

Solution (Python):
import numpy as np
N,C=map(int,input().split())
ans=10**9
a=np.array([0]*C)
b=np.array([0]*C)
c=np.array([0]*C)
s=[]
t=[]
for i in range(C):
    s.append(list(map(int,input().split())))
for i in range(N):
    t.append(list(map(int,input().split())))
for j in range(N):
    for i in range(N):
        if (i+j)%3==0:
            a+=np.array(s[t[i][j]-1])
        elif (i+j)%3==1:
            b+=np.array(s[t[i][j]-1])
        else:
            c+=np.array(s[t[i][j]-1])
from itertools import permutations
for i,j,k in permutations(range(C),3):
    p=a[i]+b[j]+c[k]
    ans=min(p,ans)
print(ans)

Solution (Python):
N,C=map(int,input().split(' '))
D=[]
for _ in range(C):
  D.append([ x for x in map(int,input().split(' '))])

c=[]
for _ in range(N):
  c.append([ x for x in map(int,input().split(' '))])

x=float('inf')

memo={}

counter=[[0]*C for _ in range(3)]
for i in range(N):
  for j in range(N):
    b=i%3
    cur=c[i][j]
    counter[(j+b)%3][cur-1]+=1
    

for c0 in range(C):
  for c1 in range(C):
    if c1==c0:
      continue
    for c2 in range(C):
      if c2==c0 or c2==c1:
        continue
      s=0
      for i, cx in enumerate(counter[0]):
        s+=D[i][c0]*cx
      for i, cx in enumerate(counter[1]):
        s+=D[i][c1]*cx
      for i, cx in enumerate(counter[2]):
        s+=D[i][c2]*cx
      if s<x:
        x=s


print(x)

Solution (Python):
import numpy as np                                                                                                                                                    
if __name__ == '__main__':
    N, C = map(int, input().split(' '))
    D = []
    for i in range(C):
        D.append(list(map(int, input().split(' '))))

    field = []
    for i in range(N):
        field.append(list(map(int, input().split(' '))))
    field = np.array(field) - 1

    res0 = {}
    res1 = {}
    res2 = {}
    for i in range(N):
        for j in range(N):
            if (i + j) % 3 == 0:
                if field[i][j] in res0.keys():
                    res0[field[i][j]] += 1
                else:
                    res0[field[i][j]] = 1
            if (i + j) % 3 == 1:
                if field[i][j] in res1.keys():
                    res1[field[i][j]] += 1
                else:
                    res1[field[i][j]] = 1
            if (i + j) % 3 == 2:
                if field[i][j] in res2.keys():
                    res2[field[i][j]] += 1
                else:
                    res2[field[i][j]] = 1

    res = 1e+10
    
    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
                temp = 0
                for color in res0.keys():
                    temp += D[color][i] * res0[color]
                for color in res1.keys():
                    temp += D[color][j] * res1[color]
                for color in res2.keys():
                    temp += D[color][k] * res2[color]
                if temp < res:
                    res = temp
    print(res)

Solution (Python):

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

D = [[0 for i in range(C)] for j in range(C)]
c = [[0 for i in range(N)] for j in range(N)]


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

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







'''
Gij0 : (i + j) % 3 == 0 となる場所
Gij1 : (i + j) % 3 == 1 となる場所
Gij2 : (i + j) % 3 == 2 となる場所
とした時に、
Gijnに属する場所全ての色をaに塗り替える場合の違和感の合計を
iwakan[n][a]とする。
iwakan[n][a]を全て求めるための計算量は、30*500*500 = 7500000
iwakan を用いて全ての色の塗り替えの組み合わせを求めるための計算量は
30 * 29 * 28 = 24360
'''




numOfColors = [[0 for i in range(C)] for j in range(3)]
for i in range(N):
    for j in range(N):
        if (i + j) % 3 == 0:
            numOfColors[0][c[i][j] - 1] = numOfColors[0][c[i][j] - 1] + 1
        if (i + j) % 3 == 1:
            numOfColors[1][c[i][j] - 1] = numOfColors[1][c[i][j] - 1] + 1
        if (i + j) % 3 == 2:
            numOfColors[2][c[i][j] - 1] = numOfColors[2][c[i][j] - 1] + 1

iwakan = [[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in range(C):
        for a in range(C):
            iwakan[i][j] = iwakan[i][j] + numOfColors[i][a] * D[a][j]



sum_min = float("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):
                pass
            else:
                sum_tmp = iwakan[0][i] + iwakan[1][j] + iwakan[2][k]
                if sum_min > sum_tmp:
                    sum_min = sum_tmp



print(sum_min)

Solution (Python):
import itertools

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


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

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(map(lambda x: int(x) - 1, input().split())):
        
        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(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)

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for k in range(C)]
G = [list(map(int, input().split())) for k in range(N)]

M = [[0,0,0] for k in range(C)]
for x in range(N):
    for y in range(N):
        M[G[x][y]-1][(x+y)%3] += 1

ans = 10**9
for p in range(C):
    for q in range(C):
        for r in range(C):
            if p!=q and q!=r and r!=p:
                t = 0
                for s in range(C):
                    t += D[s][p]*M[s][0]+ D[s][q]*M[s][1] + D[s][r]*M[s][2]
                ans = min(t,ans)

print(ans)

Solution (Python):
from pprint import pprint


N, C = [int(i) for i in input().split()]
D_xy = []
for _ in range(C):
    D_xy.append([int(i) for i in input().split()])
c_ij = []
for _ in range(N):
    c_ij.append([int(i) for i in input().split()])






clusters = [[] for _ in range(3)]
for i in range(N):
    for j in range(N):
         if (i+j) % 3 == 0:
             clusters[0].append(c_ij[i][j])
         elif (i+j) % 3 == 1:
             clusters[1].append(c_ij[i][j])
         elif (i+j) % 3 == 2:
             clusters[2].append(c_ij[i][j])
         else:
             
             
             pass



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

for i in range(3):
    for c in range(C):
        cost = 0
        for item in clusters[i]:
            cost += D_xy[item-1][c] 
        
        cost_matrix[i][c] = cost





min = float('infinity')
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
            score = cost_matrix[0][i] + cost_matrix[1][j] + cost_matrix[2][k]
            
            if score < min:
                min = score
print(min)

Solution (Python):

import sys
def debug(*args): print(*args, file=sys.stderr)
def exit(): sys.exit(0)

N, C = map(int, input().split())
D = []
col = []

for c in range(C):
    Drow = list(map(int, input().split()))
    D.append(Drow)
for i in range(N):
    crow = list(map(int, input().split()))
    crow = list(map(lambda x: x-1,
                    crow))
    col.append(crow)


count = [[0]*C for m in range(3)]

for i in range(N):
    for j in range(N):
        m = (i + j) % 3
        count[m][col[i][j]] += 1

def iwakan(y):
    res = 0
    for m in range(3):
        for c in range(C):
            res += D[c][y[m]] * count[m][c]
    return res

iwakan_list = []
for c1 in range(C):
    for c2 in range(C):
        if c1 == c2:
            continue
        for c3 in range(C):
            if (c3 == c1) or (c3 == c2):
                continue
            y = [c1, c2, c3]
            debug(y, iwakan(y))
            iwakan_list.append(iwakan(y))

print(min(iwakan_list))

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

ct = [{}, {}, {}]

for i in range(1, N+1):
  for j, c in enumerate(list(map(int, input().split()))):
    k = (i+j+1) % 3
    ct[k][c] = ct[k].get(c, 0) + 1

ans = float('inf')
for c1 in range(1, C+1):
  d1 = 0
  for c, v in ct[0].items():
    if c != c1:
      d1 += D[c][c1] * v
  for c2 in range(1, C+1):
    if c1 == c2:
      continue
    d2 = 0
    for c, v in ct[1].items():
      if c != c2:
        d2 += D[c][c2] * v
    for c3 in range(1, C+1):
      if c1 == c3 or c2 == c3:
        continue
      d3 = 0
      for c, v in ct[2].items():
        if c != c3:
          d3 += D[c][c3] * v
      ans = min(ans, d1+d2+d3)

print(ans)

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

    group = [[0 for i in range(c)], [0 for i in range(c)], [0 for i in range(c)]]
    for i in range(n):
        for j in range(n):
            group[(i+j) % 3][grid[i][j]-1] += 1

    min_cost = 1 << 30
    for i in range(c):
        for j in range(c):
            if i != j:
                for k in range(c):
                    if j != k and k != i:
                        cost = 0
                        for color in range(c):
                            cost += group[0][color] * d[color][i]
                            cost += group[1][color] * d[color][j]
                            cost += group[2][color] * d[color][k]

                        min_cost = min(cost, min_cost)

    print(min_cost)


if __name__ == '__main__':
    main()

Solution (Python):
from collections import Counter
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)]

ls = [Counter ([c[i][j] for i in range(N) for j in range(N) if (i+j)%3 == k]) for k in range(3)]

result = 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
            tt = 0
            for l in range(1,C+1):
                tt += ls[0][l] * D[l-1][i]
                tt += ls[1][l] * D[l-1][j]
                tt += ls[2][l] * D[l-1][k]
            result = min(tt, result)
 
print(result)

Solution (Python):
n, c = [int(i) for i in input().split()]
D = [[int(i) for i in input().split()] for j in range(c)]
C = [[int(i) for i in input().split()] for j in range(n)]








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

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

for i in range(c):
    for j in range(c):
        for k in range(3):
            sum_d[k][j] += D[i][j] * mod_c[k][i]
      
max_d = 1000 * (n//3+1)
ans = max_d * n**2
      
for i in range(c):
  for j in range(c):
    for k in range(c):
      if i != j != k != i:
        ans = min(ans, sum_d[0][i] + sum_d[1][j] + sum_d[2][k])
        
print(ans)

Solution (Python):
from itertools import permutations
N, C = map(int, input().split())
D = []
for i in range(C):
    D.append([int(i) for i in input().split()])
c = []
for i in range(N):
    c.append([int(i) for i in input().split()])

counter = {i: {} for i in range(3)}
for i in range(N):
    for j in range(N):
        m = (i+j) % 3
        color = c[i][j] - 1
        if counter[m].get(color) is None: counter[m][color] = 0
        counter[m][color] += 1

ans = float('inf')

for i,j,k in permutations(range(C), 3):
    tmp = 0
    for l in range(C):
        tmp += D[l][i] * counter[0].get(l, 0)
        tmp += D[l][j] * counter[1].get(l, 0)
        tmp += D[l][k] * counter[2].get(l, 0)
    ans = min(tmp, ans)

print(ans)

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for _ in range(C)]
c_ = [[0 for _ in range(C)] for _ in range(3)]
for i in range(N):
  ci =list(map(int, input().split()))
  for j in range(N):
    cij = ci[j]
    c_[(i+j)%3][cij-1] += 1

cost = [[0 for _ in range(C)] for _ in range(3)]
for i in range(3):
  for j in range(C):
    for k in range(C):
      cost[i][k] += D[j][k] * c_[i][j]
      
ans = 1000*500*500
for i in range(C):
  if ans < cost[0][i]:
    continue
  for j in range(C):
    if i is j:
      continue
    if ans < (cost[0][i]+cost[1][j]):
      continue
    for k in range(C):
      if i is k or j is k:
      	continue
      ans = min(ans, cost[0][i]+cost[1][j]+cost[2][k])
print(ans)

Solution (Python):
N,C=[int(x) for x in str(input()).split()]
D=[[0 for x in range(0,C+1)]]
for i in range (0,C):
  D.append([0]+[int(x) for x in str(input()).split()])
c=[[0 for x in range(0,N+1)]]
for j in range(0,N):
  c.append([0]+[int(x) for x in str(input()).split()])



mod1=[0 for x in range(0,C+1)]
mod2=[0 for x in range(0,C+1)]
mod0=[0 for x in range(0,C+1)]

for x in range (1,N+1):
  for y in range(1,N+1):
    if (x+y)%3==0:
      mod0[c[x][y]]+=1
    elif (x+y)%3==1:
      mod1[c[x][y]]+=1
    else:
      mod2[c[x][y]]+=1



error=1000000000
for i in range(1,C+1):
  for j in range(1,C+1):
    if j!=i:
      for k in range(1,C+1):
        if k!=j:
          if k!=i:
            e=0

            for x in range(1,C+1):
              e+=mod0[x]*D[x][i]+mod1[x]*D[x][j]+mod2[x]*D[x][k]


       
            error=min(error,e)
print(error)

Solution (Python):
from itertools import permutations, product

def main():
    N, C = map(int, input().split())
    Dc = [tuple(map(int, input().split())) for _ in [0] * C]
    Cn = [tuple(map(int, input().split())) for _ in [0] * N]

    sum_ = [[0] * C for _ in [0] * 3]
    for i, j in product(range(N), repeat=2):
        c = Cn[i][j] - 1
        n = (i + j) % 3
        for k in range(C):
            sum_[n][k] += Dc[c][k]

    cost = float('inf')
    for i, j, k in permutations(range(C), 3):
        cost = min(cost, sum_[0][i] + sum_[1][j] + sum_[2][k])
    print(cost)

main()

Solution (Python):
from itertools import permutations

def main():
    N, C = map(int, input().split())
    Dc = [tuple(map(int, input().split())) for _ in [0] * C]
    Cn = [tuple(map(int, input().split())) for _ in [0] * N]

    sum_ = [[0] * C for _ in [0] * 3]
    for i, cn in enumerate(Cn):
        for j, c in enumerate(cn):
            n = (i + j) % 3
            for k in range(C):
                sum_[n][k] += Dc[c-1][k]

    cost = float('inf')
    for i, j, k in permutations(range(C), 3):
        cost = min(cost, sum_[0][i] + sum_[1][j] + sum_[2][k])
    print(cost)

main()

Solution (Python):
N, C = map(int, input().split())
d = []
c = []
t = [[0]*C, [0]*C, [0]*C]
for _ in range(C):
  d.append(list(map(int, input().split())))
for _ in range(N):
  c.append(list(map(int, input().split())))

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

ans=1000*N*N

for i in range(C):
  for j in range(C):
    if i!=j:
      for k in range(C):
        if i!=k and j!=k:
          tt=0
          for l in range(C):
            tt += d[l][i]*t[0][l] + d[l][j]*t[1][l]+d[l][k]*t[2][l]
          ans = min(ans, tt)
print(ans)

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

colorBucket=[[0]*C, [0]*C, [0]*C]
for i in range(1,N+1):
    for j in range(1,N+1):
        colorBucket[(i+j)%3][gridColor[i-1][j-1]-1] += 1

cost_change_color=[[0]*C, [0]*C, [0]*C]

for k in range(3):

    for m in range(C):
        total=0
        for l in range(C):
            total+=D[l][m]*colorBucket[k][l]
        cost_change_color[k][m] = total

cost = []
for s in range(C):
    for t in range(C):
        for r in range(C):
            if not(s==t or t==r or r==s):
                cost.append(cost_change_color[0][s]+cost_change_color[1][t]+cost_change_color[2][r])

print(min(cost))

Solution (Python):


    
from itertools import product
from collections import Counter

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

res = []
for r in range(3):
    color_count = Counter(matrix[i][j] - 1 for i in range(n) for j in range(n) if (i + j) % 3 == r)

    def color_cost(color):
        return sum(color_costs[ccolor][color] * ccount for ccolor, ccount in color_count.items())
    cx = [(color, color_cost(color)) for color in range(c)]
    sorted_by_cost = sorted(cx, key=lambda x:x[1])
    cheapest3 = sorted_by_cost[:3]
    res.append(cheapest3)


color_pickss = product(*res)


filtered_unique = (picks for picks in color_pickss if len(set(color for color, _ in picks)) == 3)
costs = (sum(cost for _, cost in picks) for picks in filtered_unique)
print(min(costs))

Solution (Python):
def main():
    N, C = map(int, input().split())
    D = []
    for i in range(C):
        D.append(list(map(int, input().split())))
        
    c_init = []
    for i in range(N):
        c_init.append(list(map(int,input().split())))
    
    group0 = [0]*C
    group1 = [0]*C
    group2 = [0]*C
    
    
    
    for i in range(N):
        for j in range(N):
            if (i+j+2)%3==0:
                group0[c_init[i][j] - 1] += 1
            elif (i+j+2)%3 == 1:
                group1[c_init[i][j] - 1] += 1
            else:
                group2[c_init[i][j] - 1] += 1
    
    
    iwakan =[]
    for color0 in range(C):
        for color1 in range(C):
            if color1 == color0:
                continue
            
            for color2 in range(C):
                if color2==color0 or color2==color1:
                    continue
                
                iwakan_temp = 0
                for colorN in range(C):
                    iwakan_temp += group0[colorN]*D[colorN][color0]
                    iwakan_temp += group1[colorN]*D[colorN][color1]
                    iwakan_temp += group2[colorN]*D[colorN][color2]
                
                iwakan.append(iwakan_temp)
                
    print(min(iwakan))
    
if __name__ == "__main__":
    main()

Solution (Python):
import itertools
N,C=map(int,input().split())
D=[[int(i) for i in input().split()] for i in range(C)]
c=[[int(i)-1 for i in input().split()] for i in range(N)]
X=[[] for i in range(3)]
for i in range(N):
    for j in range(N):
        X[(i+j)%3].append(c[i][j])
for i in range(3):
    X[i].sort()
Z=[[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in X[i]:
        Z[i][j]+=1

I=[[0 for i in range(C)] for j in range(3)]
for i in range(3):
    for j in range(C):
        for k in range(C):
            I[i][j]+=Z[i][k]*D[k][j]
S=itertools.permutations(range(C),3)
ans=10**9
for sg in S:
    tmp=0
    for i in range(3):
        tmp+=I[i][sg[i]]
    if ans>tmp:
        ans=tmp
print(ans)

Solution (Python):
import itertools
N,C=map(int, input().split())
D=[list(map(int, input().split())) for _ in range(C)]
cl_cnt=[[0 for _ in range(C) ] for _ in range(3)]
for i in range(N):
    ci=list(map(int, input().split()))
    for j, cij in enumerate(ci):
        cl_cnt[(i+j)%3][cij-1]+=1 

cost=[[0 for _ in range(C) ] for _ in range(3)]
for i in range(3):
    for j in range(C):
        for k in range(C):
            cost[i][k]+=(D[j][k])*cl_cnt[i][j]

ans=1000*500*500
for i, j, k in itertools.permutations(range(C),3):
    ans=min(cost[0][i]+cost[1][j]+cost[2][k], ans)
print(ans)

Solution (Python):
N,C=map(int, input().split())
D=[list(map(int, input().split())) for _ in range(C)]
clr=[[0 for _ in range(C) ] for _ in range(3)]
cost=[[0 for _ in range(C) ] for _ in range(3)]

for i in range(N):
    ci=list(map(int, input().split()))
    for j, cij in enumerate(ci):
        clr[(i+j)%3][cij-1]+=1 

for i in range(3):
    for j in range(C):
        for k in range(C):
            cost[i][k]+=(D[j][k])*clr[i][j]

ans=1000*500*500
for i in range(C):
    for j in filter(lambda x:x!=i,range(C)):
        for k in filter(lambda x:x!=i and x!=j, range(C)):
            
            ans=min(cost[0][i]+cost[1][j]+cost[2][k], ans)
print(ans)

Solution (Python):
import numpy as np

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

zero_cnt_list = [0 for i in range(c)]
one_cnt_list = [0 for i in range(c)]
two_cnt_list = [0 for i in range(c)]

for i in range(n):
    for j in range(n):
        if ((i+1)+(j+1)) % 3 == 0:
            zero_cnt_list[c_mat[i][j] - 1] += 1
        elif ((i+1)+(j+1)) % 3 == 1:
            one_cnt_list[c_mat[i][j] - 1] += 1
        elif ((i+1)+(j+1)) % 3 == 2:
            two_cnt_list[c_mat[i][j] - 1] += 1

cost_list = []
for i in range(c):
    zero_cost = sum(np.array(zero_cnt_list) * np.array([d_mat[l][i] for l in range(c)]))
    for j in range(c):
        if j == i:
            continue
        one_cost = sum(np.array(one_cnt_list) * np.array([d_mat[l][j] for l in range(c)]))
        for k in range(c):
            if k == i or k == j:
                continue
            two_cost = sum(np.array(two_cnt_list) * np.array([d_mat[l][k] for l in range(c)]))
            cost_list.append(zero_cost + one_cost + two_cost)
print(min(cost_list))

Solution (Python):
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)]

ans = float('inf')

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
        if (i + j) % 3 == 1:
            c1[c[i][j] - 1] += 1
        if (i + j) % 3 == 2:
            c2[c[i][j] - 1] += 1


for x in range(C):
    for y in range(C):
        for z in range(C):
            if (x-y)*(y-z)*(z-x) != 0:
                iwakan = sum(D[i][x] * c0[i] for i in range(C)) + sum(D[j][y] * c1[j] for j in range(C))+sum(D[k][z] * c2[k] for k in range(C))                
                ans = min(ans, iwakan)
print(ans)

Solution (Python):
import numpy

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

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

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

mod = [ [ 0 for _ in range(m) ] for _ in range(3) ]

for i in range(n):
    for j in range(n):
        if ( i + j )% 3 == 0:
            mod[2][c[i][j] - 1] += 1
        elif ( i + j )% 3 == 1:
            mod[0][c[i][j] - 1] += 1
        else:
            mod[1][c[i][j] - 1] += 1

tri = []
num = []
for i in range(3):
    temp = [ 0 for _ in range(m) ]
    for j in range(m):
        for k in range(m):
            temp[j] += mod[i][k] * d[k][j]
    tri.append(list(numpy.argsort(temp)[:3]))
    num.append(list(numpy.sort(temp)[:3]))

if tri[0][0] != tri[1][0] and tri[1][0] != tri[2][0] and tri[2][0] != tri[0][0]:
    print(num[0][0] + num[1][0] + num[2][0])
    exit()

result = []
for i in range(3):
    for j in range(3):
        if tri[0][i] == tri[1][j]:
            continue
        for k in range(3):
            if tri[1][j] == tri[2][k] or tri[2][k] == tri[0][i]:
                continue
            else:
                result.append(num[0][i] + num[1][j] + num[2][k])

print(min(result))

Solution (Python):
N,C=map(int,input().split())
D=[]
for i in range(C):
    Dlist=list(map(int,input().split()))
    D.append(Dlist)
c=[[0]*(10**6) for i in range(3)]
x=[]
X=[]
for i in range(N):
    x=list(map(int,input().split()))
    X.append(x)
for i in range(N):
    for j in range(N):
        x=X[i][j]
        c[(i+j)%3][x-1]+=1
def func(res):
    for i in range(C):
        for j in range(C):
            if i!=j:
                for k in range(C):
                    if i!=k and j!=k:
                        total=0
                        for l in range(C):                           
                            total+=D[l][i]*c[0][l]
                            total+=D[l][j]*c[1][l]
                            total+=D[l][k]*c[2][l]
                        if total<res:
                            res=total
    return res
y=10**20
res=func(y)
print(res)

Solution (Python):
n, c = map(int, input().split())
arrD = list(list(map(int, input().split())) for i in range(c))
arrC = list(list(map(int, input().split())) for i in range(n))
 

    
        


 
arrCCnt = []
for r in range(3):
    arrCCnt.append([0] * (c + 1))
for i in range(1, n + 1):
    for j in range(1, n + 1):
        r = (i + j) % 3
        oriC = arrC[i - 1][j - 1]
        arrCCnt[r][oriC] += 1

ret = float('inf')
for c0 in range(1, c + 1):
    for c1 in range(1, c + 1):
        if (c0 != c1):
            for c2 in range(1, c + 1):
                 if (c1 != c2) and (c2 != c0):
                    arrToC = [c0, c1, c2]
                    buf = 0
                    for r in range(3):
                        for oriC in range(1, c + 1):
                            buf += arrD[oriC - 1][arrToC[r] - 1] * arrCCnt[r][oriC]
                    ret = min(ret, buf)
print(ret)

Solution (Python):
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)] 


c_listed = [{},{},{}]

for i in range(N):
    for j in range(N):
        index = (i + j) % 3
        c_listed[index][c[i][j]] = c_listed[index].get(c[i][j], 0) + 1


color_seq = permutations(range(C), 3)

ret = N * N * 1000
for color in color_seq:
    count = 0
    for line, line_color in zip(c_listed, color):
        for f, v in line.items():
            
            count += d[f-1][line_color] * v

    
    if count < ret:
        ret = count

print(ret)

Solution (Python):
N, C = map(int, input().split())
D = [list(map(int, input().split())) for _ in range(C)]
G = [list(map(int, input().split())) for _ in range(N)]

cost = [[0]*C for _ in range(3)]
for i in range(C):
    for a in range(N):
        for b in range(N):
            cost[(a+b)%3][i] += D[G[a][b]-1][i]

ans = 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:
                pass
            else:
                ans = min(ans, cost[0][i] + cost[1][j] + cost[2][k])

print(ans)

Solution (Python):
n,c = 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)]

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]

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)

Solution (Python):
from itertools import product
from collections import Counter
 
n, c = map(int, input().split())
color_costs = [list(map(int, input().split())) for _ in range(c)]
matrix = [list(map(int, input().split())) for _ in range(n)]

colord = {(i, j):cost for i, row in enumerate(color_costs)
                      for j, cost in enumerate(row)}
 
res = []
for n in range(3):
  color_count = Counter(c-1 for i, row in enumerate(matrix) 
                            for j, c in enumerate(row) 
                            if (i + j) % 3 == n)
  def color_cost(color):
    return sum(colord[ccolor, color] * ccount for ccolor, ccount in color_count.items())
  cx = [(color, color_cost(color)) for color in range(c)]
  sorted_by_cost = sorted(cx, key=lambda x:x[1])
  cheapest3 = sorted_by_cost[:3]
  res.append(cheapest3)

color_pickss = product(*res)
filtered_unique = (picks for picks in color_pickss if len(set(x[0] for x in picks)) == 3)
costs = (sum(x[1] for x in picks) for picks in filtered_unique)
print(min(costs))