#include <bits/stdc++.h>
using namespace std;

#define mp              make_pair
#define pb              push_back
#define ff              first
#define ss              second
#define inc(A,B)        A=(A+(B))%MOD
#define mul(A,B)        (ll(A)*ll(B)%ll(MOD))
#define sub(a,b)        (((a)-(b)+MOD)%MOD)

typedef long long ll;
typedef pair < ll ,int > pli;
typedef pair < int ,int > pii;
typedef complex < ll > pt;

const int MAX_N = 500;
const int MOD = 1e9 + 7;

int n, c;
int col[MAX_N][MAX_N];
int mat[MAX_N][MAX_N];
int cost[3][MAX_N];
vector <pii> groups[3];

void floydWarshall () {
  for ( int k = 0; k < c; ++k )
    for ( int i = 0; i < c; ++i )
      for ( int h = 0; h < c; ++h )
        col[i][h] = min ( col[i][h], col[i][k] + col[k][h] );
}

void divide () {
  for ( int i = 0; i < n; ++i )
    for ( int h = 0; h < n; ++h )
      groups[(i+h+2)%3].pb ( mp ( i, h ) );
}

void doCostFor ( int ind ) {
  for ( pii &it : groups[ind] )
    for ( int i = 0; i < c; ++i )
      cost[ind][i] += col[mat[it.ff][it.ss]][i];
}

int genRes () {
  int res = INT_MAX;
  for ( int i = 0; i < c; ++i ){
    for ( int h = 0; h < c; ++h ) {
      if ( h == i ) continue;
      for ( int j = 0; j < c; ++j ) {
        if ( j == h or j == i ) continue;
        res = min ( res, cost[0][i]+cost[1][h]+cost[2][j] );
      }
    }
  }
  return res;
}

int main() {

//  freopen ( "in.txt" , "r" , stdin );
//  freopen ( "out.txt" , "w" , stdout );

  scanf ( "%d%d", &n, &c );
  for ( int i = 0; i < c; ++i )
    for ( int h = 0; h < c; ++h )
      scanf ( "%d", &col[i][h] );

  for ( int i = 0; i < n; ++i ) {
    for ( int h = 0; h < n; ++h ) {
      scanf ( "%d", &mat[i][h] );
      --mat[i][h];
    }
  }

  for ( int i = 0; i < c; ++i )
    col[i][i] = 0;

//  floydWarshall ();
  divide ();
  for ( int i = 0; i < 3; ++i )
    doCostFor ( i );

  printf ( "%d\n", genRes () );


  return 0;

}
