import Control.Applicative
import qualified Control.Monad as Monad
import qualified Control.Monad.Trans as Trans
import qualified Control.Monad.State as State
import qualified Data.List.Split as Split

type Room = (Int, Int, Int, Int)

main = do
    n <- getLine
    rs <- putRooms (read n)
    let rs' = Split.chunksOf limitRoom $ zipWith (++) (repeat " ") (show . getValue <$> rs)
    Monad.forM_ [1..(limitBuilding*limitFloor)] $ \bf -> do
        putStrLn $ concat $ rs' !! (bf-1)
        if ((bf `mod` limitFloor == 0) && bf /= (limitBuilding*limitFloor))
            then putStrLn "####################"
            else return ()

putRooms :: Int -> IO [Room]
putRooms n = (`State.execStateT` officialHouse) $ do
    Monad.forM_ [1..n] $ \_ -> do
        room <- Trans.lift $ toRoom . map (read :: String -> Int) . words <$> getLine
        State.modify (`updateRoom` room)

limitBuilding :: Int
limitBuilding = 4

limitFloor :: Int
limitFloor = 3

limitRoom :: Int
limitRoom = 10

officialHouse :: [Room]
officialHouse = [ (b,f,r,0) | b <- [1..limitBuilding],
                              f <- [1..limitFloor],
                              r <- [1..limitRoom] ]

toRoom :: [Int] -> Room
toRoom [b,f,r,v] = (b,f,r,v)

getValue :: Room -> Int
getValue (_, _, _, v) = v

updateRoom :: [Room] -> Room -> [Room]
updateRoom [] _ = []
updateRoom (room1@(b1,f1,r1,v1):rs) room2@(b2,f2,r2,v2)
    | (b1,f1,r1) == (b2,f2,r2) = (b1,f1,r1,(v1 + v2)) : rs
    | otherwise                = room1 : updateRoom rs room2