{-# OPTIONS_GHC -O2 -funbox-strict-fields #-}
import           Control.Monad         (forM_, replicateM)
import qualified Data.Array.ST         as AM
import           Data.Array.Unboxed    ((!))
import qualified Data.Array.Unboxed    as AU
import qualified Data.ByteString.Char8 as BC
import           Data.Maybe            (fromJust)
default (Int, Double)


main :: IO ()
main = do
  [n, c] <- getInts
  dss <- replicateM c getInts
  css <- replicateM n getInts
  print $ solve n c dss css

solve :: Int -> Int -> [[Int]] -> [[Int]] -> Int
solve n c dss css = minimum [f i j k | i <- [1 .. c]
                                     , j <- [1 .. c]
                                     , i /= j
                                     , k <- [1 .. c]
                                     , i /= k
                                     , j /= k] where
  f i j k = sum $ [dss' ! (l, i) * css' ! (0, l)
                  | l <- [1 .. c]]
            ++ [dss' ! (l, j) * css' ! (1, l)
               | l <- [1 .. c]]
            ++ [dss' ! (l, k) * css' ! (2, l)
               | l <- [1 .. c]]
  dss' = AU.array ((1, 1), (c, c)) [((i, j), d)
                                   | (ds, i) <- zip dss [1 .. c]
                                   , (d, j) <- zip ds [1 .. c]] :: AU.UArray (Int, Int) Int
  css' = AM.runSTUArray $ do
    arr <- AM.newArray ((0, 1), (2, c)) 0
    forM_ (zip css [1 .. ]) $ \(cs, i) ->
      forM_ (zip cs [1 .. ]) $ \(c, j) -> do
        let k = (i + j) `mod` 3
        AM.writeArray arr (k, c) .
          (+ 1) =<< AM.readArray arr (k, c)
    return arr

readInt :: BC.ByteString -> Int
readInt = fst . fromJust . BC.readInt

getInts :: IO [Int]
getInts = map readInt . BC.words <$> BC.getLine
