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 in C++ (GCC 9.2.1) (judge verdict: Accepted)

#include <bits/stdc++.h>
#define rep(i,a,b) for(int i=a;i<b;i++)
#define rrep(i,b,a) for(int i=b;i>=a;i--)
#define fori(a) for(auto i : a )
#define all(a) begin(a), end(a)
#define set(a,b) memset(a,b,sizeof(a))
#define sz(a) a.size()
#define pi 3.14159
#define ll long long
#define ull unsigned long long
#define pb push_back
#define PF push_front //deque
#define mp make_pair
#define pq priority_queue
#define mod 1000000007
#define f first
#define s second
#define pii pair< int, int >
#define vi vector<int>
#define vpii vector<pii>
#define debug(v) for(auto i:v) cout<<i<<" ";
#define tc int t; cin >> t; while(t--)

using namespace std;
string repeat(string s, int n) {
    string s1 = "";
    for (int i=0; i<n;i++)
        s1+=s;
    return s1;
}
string getString(char x) {
    string s(1, x);
    return s;
}

void optimizeIO(){
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
}
int gcd(int a, int b){
    if (a == 0)  return b;
    return gcd(b % a, a);
}
void  solve(){
	int n,c;
	cin>>n>>c;
	int d[c+1][c+1];
	rep(i,1,c+1) rep(j,1,c+1) cin>>d[i][j];

	int C[n+1][n+1];
	rep(i,1,n+1) rep(j,1,n+1) cin>>C[i][j];
	map<int,vector<int>> m1;
	rep(i,1,n+1) rep(j,1,n+1) m1[(i+j)%3].push_back(C[i][j]);
	vector<pair<int,int>> v1,v2,v3;
	rep(f,1,c+1){
			int sum=0;
			for(auto i:m1[0]){
				sum+= d[i][f];
			}
			v1.push_back({sum,f});
	}
	rep(f,1,c+1){
			int sum=0;
			for(auto i:m1[1]){
				sum+= d[i][f];
			}
			v2.push_back({sum,f});
	}
	rep(f,1,c+1){
			int sum=0;
			for(auto i:m1[2]){
				sum+= d[i][f];
			}
			v3.push_back({sum,f});
	}
	sort(all(v1));
	sort(all(v2));
	sort(all(v3));
	int ans=INT_MAX;
	rep(i,0,3){
		rep(j,0,3){
			rep(k,0,3){
				if(v1[i].s!=v2[j].s && v1[i].s!=v3[k].s && v3[k].s!=v2[j].s) ans=min(ans,v1[i].f+v2[j].f+v3[k].f);
			}
		}
	}
	cout<<ans<<endl;
}
int main(){
    optimizeIO();
    // tc
    { solve();
    }
}