#define _USE_MATH_DEFINED
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

//typedef
typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef pair<int,int> ii;
typedef pair<ll,ll> pll;
typedef pair<int,ll> pil;
typedef vector<ii> vii;
typedef unsigned long long ull;
typedef tuple<int,int,int> iii;
typedef tuple<int,int,int,int> iiii;
template<typename T,typename Comp=less<T>>
using ordered_set = tree<T,null_type,Comp,rb_tree_tag,tree_order_statistics_node_update>;
//macros
#define sz(x) int((x).size())
#define fi get<0>
#define se get<1>
#define th get<2>
#define gcd __gcd
//functions
template<typename T>
T sq(T a) { return a*a; }
template<typename Arg,typename ...Args>
Arg min(const Arg& arg1,const Arg& arg2,const Arg& arg3,const Args&... args)
{
  auto il = {arg1,arg2,arg3,args...};
  return *min_element(il.begin(),il.end());
}
template<typename Arg,typename ...Args>
Arg max(const Arg& arg1,const Arg& arg2,const Arg& arg3,const Args&... args)
{
  auto il = {arg1,arg2,arg3,args...};
  return *max_element(il.begin(),il.end());
}
inline int bcount(int x)
{
  int r=0;
  __asm__ volatile("POPCNT %1, %0;" : "=r"(r) : "r"(x) );
  return r;
}
inline int clz(int x)
{
  int r=0;
  __asm__ volatile("LZCNT %1, %0;" : "=r"(r) : "r"(x) );
  return r;
}
inline int ctz(int x)
{
  int r=0;
  __asm__ volatile("TZCNT %1, %0;" : "=r"(r) : "r"(x) );
  return r;
}
//constants
constexpr ll LINF = 1e18;
constexpr ll INF = 1e9;
constexpr ll MOD = 1e9+7;
constexpr ld EPS = 1e-9;
//I/O
#ifdef EVAL
ifstream in("input.txt");
ofstream out("output.txt");
#define cin in
#define cout out
#endif
template<typename Arg>
void read(Arg& arg) { cin>>arg; }
template<typename ...Types>
void read(pair<Types...>&);
template<typename ...Types>
void read(tuple<Types...>&);
template<typename ...Types>
void read(vector<Types...>&);
template<typename ...Types>
void read(deque<Types...>&);
template<typename ...Types>
void read(array<Types...>&);
template<typename ...Types>
void read(list<Types...>&);
template<typename ...Types>
void read(forward_list<Types...>&);
template<size_t I=0,typename Tuple>
typename enable_if<I >= tuple_size<Tuple>::value>::type
  read_tuple(Tuple&) {}
template<size_t I=0,typename Tuple>
typename enable_if<I < tuple_size<Tuple>::value>::type
  read_tuple(Tuple& x)
{
  read(get<I>(x));
  read_tuple<I+1>(x);
}
template<typename ...Types>
void read(pair<Types...>& x) { read_tuple(x); }
template<typename ...Types>
void read(tuple<Types...>& x) { read_tuple(x); }
template<typename ...Types>
void read(vector<Types...>& x) { for(typename vector<Types...>::reference i : x) read(i); }
template<typename ...Types>
void read(valarray<Types...>& x) { for(typename valarray<Types...>::reference i : x) read(i); }
template<typename ...Types>
void read(deque<Types...>& x) { for(typename deque<Types...>::reference i : x) read(i); }
template<typename ...Types>
void read(array<Types...>& x) { for(typename array<Types...>::reference i : x) read(i); }
template<typename ...Types>
void read(list<Types...>& x) { for(typename list<Types...>::reference i : x) read(i); }
template<typename ...Types>
void read(forward_list<Types...>& x) { for(typename forward_list<Types...>::reference i : x) read(i); }
template<typename Arg,typename ...Args>
void read(Arg& arg,Args&... args) { read(arg); read(args...); }
template<typename Arg>
void print_var(const Arg& arg) { cout<<arg; }
template<typename ...Types>
void print_var(const pair<Types...>&);
template<typename ...Types>
void print_var(const tuple<Types...>&);
template<typename ...Types>
void print_var(const vector<Types...>&);
template<typename ...Types>
void print_var(const valarray<Types...>&);
template<typename ...Types>
void print_var(const array<Types...>&);
template<typename ...Types>
void print_var(const list<Types...>&);
template<typename ...Types>
void print_var(const forward_list<Types...>&);
template<typename ...Types>
void print_var(const deque<Types...>&);
template<typename ...Types>
void print_var(const set<Types...>&);
template<typename ...Types>
void print_var(const multiset<Types...>&);
template<typename ...Types>
void print_var(const map<Types...>&);
template<typename ...Types>
void print_var(const multimap<Types...>&);
template<typename ...Types>
void print_var(const unordered_set<Types...>&);
template<typename ...Types>
void print_var(const unordered_multiset<Types...>&);
template<typename ...Types>
void print_var(const unordered_map<Types...>&);
template<typename ...Types>
void print_var(const unordered_multimap<Types...>&);
template<typename ...Types>
void print_var(const stack<Types...>&);
template<typename ...Types>
void print_var(const priority_queue<Types...>&);
template<typename ...Types>
void print_var(const queue<Types...>&);
template<size_t I=0,typename Tuple>
typename enable_if<I >= tuple_size<Tuple>::value>::type
  print_tuple(const Tuple&)
{
  if
#if __cplusplus >= 201703
  constexpr
#endif
    (I == 0) cout.put('(');
  cout.put(')');
}
template<size_t I=0,typename Tuple>
typename enable_if<I < tuple_size<Tuple>::value>::type
  print_tuple(const Tuple& x)
{
  if
#if __cplusplus >= 201703
  constexpr
#endif
    (I == 0) cout.put('(');
  else cout.write(", ",2);
  print_var(get<I>(x));
  print_tuple<I+1>(x);
}
template<typename List>
void print_list(const List& x)
{
  cout.put('[');
  bool first = true;
  for(typename List::const_reference i : x)
  {
    if(!first) cout.write(", ",2);
    first = false;
    print_var(i);
  }
  cout.put(']');
}
template<typename Set>
void print_set(const Set& x)
{
  cout.put('{');
  bool first = true;
  for(typename Set::const_reference i : x)
  {
    if(!first) cout.write(", ",2);
    print_var(i);
  }
  cout.put('}');
}
template<typename Map>
void print_map(const Map& x)
{
  cout.put('{');
  bool first = true;
  for(typename Map::const_reference i : x)
  {
    if(!first) cout.write(", ",2);
    print_var(i.first);
    cout.put(':');
    print_var(i.second);
  }
  cout.put('}');
}
template<typename Stack>
void print_stack(const Stack& x)
{
  Stack y(x);
  cout.put('[');
  bool first = true;
  while(!y.empty())
  {
    if(!first) cout.write(", ",2);
    print_var(y.top());
    y.pop();
  }
  cout.put(']');
}
template<typename ...Types>
void print_var(const queue<Types...>& x)
{
  queue<Types...> y(x);
  cout.put('[');
  bool first = true;
  while(!y.empty())
  {
    if(!first) cout.write(", ",2);
    print_var(y.front());
    y.pop();
  }
  cout.put(']');
}
template<typename ...Types>
void print_var(const pair<Types...>& x) { print_tuple(x); }
template<typename ...Types>
void print_var(const tuple<Types...>& x) { print_tuple(x); }
template<typename ...Types>
void print_var(const vector<Types...>& x) { print_list(x); }
template<typename ...Types>
void print_var(const valarray<Types...>& x) { print_list(x); }
template<typename ...Types>
void print_var(const array<Types...>& x) { print_list(x); }
template<typename ...Types>
void print_var(const list<Types...>& x) { print_list(x); }
template<typename ...Types>
void print_var(const forward_list<Types...>& x) { print_list(x); }
template<typename ...Types>
void print_var(const deque<Types...>& x) { print_list(x); }
template<typename ...Types>
void print_var(const set<Types...>& x) { print_set(x); }
template<typename ...Types>
void print_var(const multiset<Types...>& x) { print_set(x); }
template<typename ...Types>
void print_var(const map<Types...>& x) { print_map(x); }
template<typename ...Types>
void print_var(const multimap<Types...>& x) { print_map(x); }
template<typename ...Types>
void print_var(const unordered_set<Types...>& x) { print_set(x); }
template<typename ...Types>
void print_var(const unordered_multiset<Types...>& x) { print_set(x); }
template<typename ...Types>
void print_var(const unordered_map<Types...>& x) { print_map(x); }
template<typename ...Types>
void print_var(const unordered_multimap<Types...>& x) { print_map(x); }
template<typename ...Types>
void print_var(const stack<Types...>& x) { print_stack(x); }
template<typename ...Types>
void print_var(const priority_queue<Types...>& x) { print_stack(x); }
template<typename Arg>
void print(const Arg& arg) { print_var(arg); cout.put('\n'); }
template<typename Arg,typename ...Args>
void print(const Arg& arg,const Args&... args) { print_var(arg); cout.put(' '); print(args...); }
template<typename Arg>
void print_raw(const Arg& arg) { cout<<arg; }
template<typename ...Types>
void print_raw(const pair<Types...>&);
template<typename ...Types>
void print_raw(const tuple<Types...>&);
template<typename ...Types>
void print_raw(const vector<Types...>&);
template<typename ...Types>
void print_raw(const valarray<Types...>&);
template<typename ...Types>
void print_raw(const array<Types...>&);
template<typename ...Types>
void print_raw(const list<Types...>&);
template<typename ...Types>
void print_raw(const forward_list<Types...>&);
template<typename ...Types>
void print_raw(const deque<Types...>&);
template<typename ...Types>
void print_raw(const set<Types...>&);
template<typename ...Types>
void print_raw(const multiset<Types...>&);
template<typename ...Types>
void print_raw(const map<Types...>&);
template<typename ...Types>
void print_raw(const multimap<Types...>&);
template<typename ...Types>
void print_raw(const unordered_set<Types...>&);
template<typename ...Types>
void print_raw(const unordered_multiset<Types...>&);
template<typename ...Types>
void print_raw(const unordered_map<Types...>&);
template<typename ...Types>
void print_raw(const unordered_multimap<Types...>&);
template<typename ...Types>
void print_raw(const stack<Types...>&);
template<typename ...Types>
void print_raw(const priority_queue<Types...>&);
template<typename ...Types>
void print_raw(const queue<Types...>&);
template<size_t I=0,typename Tuple>
typename enable_if<I >= tuple_size<Tuple>::value>::type
  print_raw_tuple(const Tuple&) {}
template<size_t I=0,typename Tuple>
typename enable_if<I < tuple_size<Tuple>::value>::type
  print_raw_tuple(const Tuple& x)
{
  if
#if __cplusplus >= 201703
  constexpr
#endif
    (I != 0) cout.put(' ');
  print_raw(get<I>(x));
  print_raw_tuple<I+1>(x);
}
template<typename List>
void print_raw_list(const List& x)
{
  bool first = true;
  for(typename List::const_reference i : x)
  {
    if(!first) cout.put(' ');
    first = false;
    print_raw(i);
  }
}
template<typename Stack>
void print_raw_stack(const Stack& x)
{
  Stack y(x);
  bool first = true;
  while(!y.empty())
  {
    if(!first) cout.put(' ');
    first = false;
    print_raw(y.top());
    y.pop();
  }
}
template<typename ...Types>
void print_raw(const queue<Types...>& x)
{
  queue<Types...> y(x);
  bool first = true;
  while(!y.empty())
  {
    if(!first) cout.put(' ');
    first = false;
    print_raw(y.front());
    y.pop();
  }
}
template<typename ...Types>
void print_raw(const pair<Types...>& x) { print_raw_tuple(x); }
template<typename ...Types>
void print_raw(const tuple<Types...>& x) { print_raw_tuple(x); }
template<typename ...Types>
void print_raw(const vector<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const valarray<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const array<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const list<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const forward_list<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const deque<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const set<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const multiset<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const map<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const multimap<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const unordered_set<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const unordered_multiset<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const unordered_map<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const unordered_multimap<Types...>& x) { print_raw_list(x); }
template<typename ...Types>
void print_raw(const stack<Types...>& x) { print_raw_stack(x); }
template<typename ...Types>
void print_raw(const priority_queue<Types...>& x) { print_raw_stack(x); }
template<typename Arg,typename ...Args>
void print_raw(const Arg& arg,const Args&... args) { print_raw(arg); print_raw(args...); }
#ifdef DEBUG
void print_dbg(string) { cout.put('\n'); }
template<typename Arg,typename ...Args>
void print_dbg(string name,const Arg& arg,const Args&... args)
{
  typename string::size_type idx = 0;
  for(stack<char> stk; idx<name.size() && (name[idx]!=',' || !stk.empty()); ++idx)
  {
    if(name[idx]=='\\')
    {
      ++idx;
      continue;
    }
    if(name[idx]=='\'' || name[idx]=='\"')
    {
      if(!stk.empty() && stk.top()==name[idx])
        stk.pop();
      else
        stk.push(name[idx]);
    }
    if((stk.empty() || (stk.top()!='\'' && stk.top()!='\"')) && (name[idx]=='{' || name[idx]=='('))
      stk.push(name[idx]);
    if(name[idx]==')' || name[idx]=='}')
      stk.pop();
  }
  print_raw(name.substr(0,idx),": ");
  print(arg);
  print_dbg(name.substr(idx==name.size() ? 0 : idx+1),args...);
}
#define dbg(...) print_dbg(#__VA_ARGS__,__VA_ARGS__)
#else
#define dbg(...) asm("nop")
#endif
template<typename ...Args>
void print_case(size_t t,const Args&... args) { cout<<"Case #"<<t<<": "; print_raw(args...); cout.put('\n'); }
// END I/O

constexpr int MAXN = 505, MAXC = 35;

int wrong[MAXC][MAXC];
int change[3][MAXC];

int main()
{
  int N, C;
  read(N,C);
  for(int i=1; i<=C; i++)
    for(int j=1; j<=C; j++)
      read(wrong[i][j]);
  for(int i=1; i<=N; i++)
  {
    for(int j=1; j<=N; j++)
    {
      int x; read(x);
      for(int k=1; k<=C; k++)
        change[(i+j)%3][k] += wrong[x][k];
    }
  }
  int res = INF;
  for(int i=1; i<=C; i++)
  {
    for(int j=1; j<=C; j++)
    {
      for(int k=1; k<=C; k++)
      {
        if(set<int>{i,j,k}.size() < 3) continue;
        res = min(res,change[0][i]+change[1][j]+change[2][k]);
      }
    }
  }
  print(res);
  return 0;
}

Measured memory_bytes: 256