import Data.List
import Data.List.Split

main :: IO ()
main = do
  input <- map lines . splitOn "\n\n" <$> readFile "input"
  let field = parseField $ head input
  let moves = parseMoves $ last input
  print $ map last $ doMoves reverse moves field
  print $ map last $ doMoves id moves field

parseField :: [String] -> [String]
parseField =
  filter (not . null) .
  map (reverse . filter (not . flip elem "[] ")) . transpose . init

parseMoves :: [String] -> [[Int]]
parseMoves =
  map
    (map (subtract 1 . read) .
     filter (not . null . intersect ['0' .. '9']) . words)

move :: (String -> String) -> [Int] -> [String] -> [String]
move f [p, a, b] field = newFieldA ++ [new] ++ newFieldB
  where
    line = field !! a
    (rmn, splt) = splitAt (length line - 1 - p) line
    new = field !! b ++ f splt
    (fieldA, _) = splitAt a field
    (_, fieldB) = splitAt (a + 1) field
    removedField = fieldA ++ [rmn] ++ fieldB
    (newFieldA, _) = splitAt b removedField
    (_, newFieldB) = splitAt (b + 1) removedField

doMoves :: (String -> String) -> [[Int]] -> [String] -> [String]
doMoves _ [] field = field
doMoves f (m:ms) field = doMoves f ms (move f m field)
