fun member x nil = false | member x (h::tl) = if x = h then true else member x tl fun readStr () = let fun scan reader stream = SOME (StringCvt.splitl (not o Char.isSpace) reader (StringCvt.skipWS reader stream)) in valOf (TextIO.scanStream scan TextIO.stdIn) end fun findAns s = let fun findAnsAux [] acc = findAnsAux acc [] | findAnsAux ((toTaken, toAdd)::tl) acc = case List.length toTaken = 0 of true => List.map (fn (_, allAdded) => String.implode (List.rev allAdded)) ((toTaken, toAdd)::tl) | false => let val first = List.hd toTaken val firstRemoved = List.tl toTaken val last = List.last toTaken val lastRemoved = List.rev (List.tl (List.rev toTaken)) in findAnsAux tl ((firstRemoved, first :: toAdd) :: (lastRemoved, last :: toAdd) :: acc) end in List.length ( List.foldl (fn (x, acc) => if member x acc then acc else x :: acc) [] (findAnsAux [(String.explode s, [])] []) ) end val () = let val s = readStr () val ans = findAns s in print (Int.toString ans ^ "\n") end