import Control.Applicative

type Row = [Int]

type Matrix = [Row]

type Problem = (Matrix, Matrix)

type Result = Matrix

access :: Matrix -> Int -> Int -> Int

access matrix row col
    = matrix !! row !! col
    
calcElement :: Matrix -> Matrix -> Int -> Int -> Int

calcElement mat1 mat2 row col
    = sum [access mat1 row x * access mat2 x col | x <- xs] where
        m = length mat2
        xs = [0..(m - 1)]

solve :: Problem -> Result

solve (mat1, mat2)
    = [[calcElement mat1 mat2 row col | col <- cols] | row <- rows] where
        n = length mat1
        l = length $ head mat2
        rows = [0..(n - 1)]
        cols = [0..(l - 1)]

output :: Result -> String

output matrix
    = init.concat $ [outputRow row ++ "\n" | row <- matrix]
    
outputRow :: Row -> String

outputRow row
    = init.concat $ [show x ++ " " | x <- row]
    
input :: IO Problem

input
    = do
        [n, m, _] <- map read.words <$> getLine
        mat1 <- inputMatrix n []
        mat2 <- inputMatrix m []
        return (mat1, mat2)
        
inputMatrix :: Int -> Matrix -> IO Matrix

inputMatrix 0 matrix
    = return matrix
    
inputMatrix rows matrix
    = do
        row <- map read.words <$> getLine
        inputMatrix (rows - 1) $ matrix ++ [row]
    
main :: IO ()

main
    = putStrLn.output =<< solve <$> input