data Place = Place Int Int Int deriving (Eq,Ord,Show)
data Data = Data Place Int deriving (Eq,Show)
instance Ord Data where
	compare (Data a b) (Data c d) = compare a c

readData :: String -> Data
readData = (\[b,f,r,v] -> Data (Place b f r) v).map (read :: String->Int).words

quickSort :: (Ord a) => [a]->[a]
quickSort [] = []
quickSort xs = (smallerOrEqual xs) ++ [head xs] ++ (larger xs)
	where
	smallerOrEqual xs = quickSort $ filter (<= head xs) (tail xs)
	larger xs = quickSort $ filter (> head xs) xs

addData :: Data->Data->Data
addData (Data x a) (Data y b) = Data x (a+b)

takePlace :: Data->Place
takePlace (Data x _) = x

calcData :: [Data]->[Data]
calcData [] = []
calcData [x] = [x]
calcData (x:y:xs)
	|(takePlace x)/=(takePlace y) = x : calcData (y:xs)
	|(takePlace x)==(takePlace y) = calcData $ (addData x y):xs

placem :: [Place]
placem = [Place b f r|b<-[1..4],f<-[1..3],r<-[1..10]]

punct :: Place->String
punct (Place f b r)
	|r==1&&b==1&&f>1 = "\n" ++ (take 20 $ repeat '#') ++ "\n"
	|r==1&&f>1 = "\n"
	|r==1&&b>1 = "\n"
	|otherwise = ""

printData :: [Place]->[Data]->String
printData [] _ = []
printData (x:xs) [] = (punct x) ++ " " ++ "0" ++ printData xs []
printData (x:xs) yys@((Data y v):ys)
	|x==y = (punct x) ++ " " ++ (show v) ++ printData xs ys
	|x/=y = (punct x) ++ " " ++ "0" ++ printData xs yys
	
main = getContents >>= putStrLn.(printData placem).calcData.quickSort.map readData.tail.lines