import Data.List

main = getContents >>= \x -> mapM_ putStr (makeIndex x)

makeIndex :: String -> [String]
makeIndex = map tuple2IndexStr.sort.groupWords.map (makePair.words).lines

makePair :: [String] -> (String, Int)
makePair [x,y] = (x, read y)

groupWords :: [(String,Int)] -> [(String,[Int])]
groupWords list = group' [] list
group' list [] = list
group' list (x:xs) = case lookup (fst x) list of
                       Just _ -> group' (addpage list (fst x) (snd x)) xs
                       Nothing -> group' newlist xs
                           where 
                               newlist       = (fst x, [snd x]): list
addpage :: [(String, [Int])] -> String -> Int -> [(String, [Int])]
addpage list key page = takeWhile (\x -> fst x /= key) list ++ new ++ ( tail $ dropWhile (\x -> fst x /= key) list)
    where new = [(key, page:pagelist)]
          (Just pagelist) = lookup key list


tuple2IndexStr :: (String, [Int]) -> String
tuple2IndexStr (word, pages) = unlines [word, unwords (map show (sort pages))]