import Control.Monad
import Control.Monad.Trans.State.Strict
import Data.Char (isSpace)
import Data.Maybe (fromJust)
import qualified Data.ByteString.Lazy.Char8 as B
--
import Data.Array.Unboxed
import Data.Array.IO

type Parser a = StateT B.ByteString Maybe a

parseInt :: Parser Int
parseInt = StateT (B.readInt . B.dropWhile isSpace)

parseInt2 :: Parser (Int,Int)
parseInt2 = liftM2 (,) parseInt parseInt

parse :: Parser (Int, Int, [[Int]], [[Int]])
parse = do
  (n,c) <- parseInt2
  ds <- replicateM c $ replicateM c parseInt
  cs <- replicateM n $ replicateM n parseInt
  return (n,c,ds,cs)

main=do
  (n,c,ds,cs) <- fromJust.evalStateT parse <$> B.getContents
  let da = listArray ((1,1),(c,c)) $ concatMap id ds :: UArray (Int,Int) Int
  let ca = listArray ((1,1),(n,n)) $ concatMap id cs :: UArray (Int,Int) Int
  --
  cnum' <- newArray ((0,1),(2,c)) 0 :: IO (IOUArray (Int,Int) Int)
  forM_ [(i,j)|i<-[1..n],j<-[1..n]] $ \(i,j) -> do
    let c = ca ! (i,j)
    writeArray cnum' ((i+j)`mod`3, c) =<< (+1) <$> readArray cnum' ((i+j)`mod`3, c)
  cnum <- freeze cnum' :: IO (UArray (Int,Int) Int)
  --
  print $ minimum $ map (\(u,v,w) -> (cc c da cnum 0 u + cc c da cnum 1 v + cc c da cnum 2 w)) [(u,v,w)|u<-[1..c], v<-[1..c], w<-[1..c], u/=v, v/=w, u/=w]

cc c da cn k ct = sum $ map (\cf-> ((cn ! (k,cf)) * (da ! (cf,ct)))) [1..c]