import Control.Monad
import Data.Char (isAlpha, toLower)
import qualified Data.Map as M
import qualified Data.IntSet as S
import System.Environment (getArgs)

main =  do
    (files, _: q) <- liftM (break (== "
    buildII files >>= mapM_ putStrLn . queryII q

data IIndex = IIndex
    [FilePath]              
    (M.Map String S.IntSet) 
  deriving Show

buildII :: [FilePath] -> IO IIndex
buildII files =
    liftM (IIndex files . foldl f M.empty . zip [0..]) $
    mapM readFile files
  where f m (i, s) =
            foldl g m $ map (lowercase . filter isAlpha) $ words s
          where g m word = M.insertWith S.union word (S.singleton i) m

queryII :: [String] -> IIndex -> [FilePath]
queryII q (IIndex files m) =
    map (files !!) $ S.toList $ intersections $
    map (\word -> M.findWithDefault S.empty (lowercase word) m) q

intersections [] = S.empty
intersections xs = foldl1 S.intersection xs

lowercase = map toLower