import Data.Array.ST import Data.Array.Unboxed import Data.Graph import Data.ByteString.Char8 qualified as B import Control.Monad.ST import Control.Monad int = (\(Just(x,_)) -> x) . B.readInt readInput :: [[Int]] -> (Graph, Int, Int) readInput ([n,m,c]:fs) = (buildG (1,n+m) $ concat $ buildEdges 1 fs, m, c) where buildEdges _ [] = [] buildEdges i (_:es:es') = [ [(i,j+m), (j+m,i)] | j <- es ] ++ buildEdges (i+1) es' solve :: (Graph, Int, Int) -> IO () solve (g,m,c) | null bands = putStrLn "impossible" | otherwise = mapM_ putStrLn ["possible", show $ length bands, unwords $ show <$> bands] where (1,n) = bounds g bands = (\i -> i - m) <$> filter (attends!) [m+1..n] minDegree :: UArray Int Int = listArray (1,n) $ [quot (1 + indegree g ! i) 2 | i <- [1..m]] ++ replicate (n - m) c attends = runSTUArray $ do degree <- (thaw $ outdegree g) :: ST s (STUArray s Int Int) attends <- newArray (1,n) True let check i = do rm <- (&&) <$> readArray attends i <*> ((< (minDegree ! i)) <$> readArray degree i) when rm $ do writeArray attends i False forM_ (g!i) $ \j -> modifyArray' degree j pred >> check j forM_ [1..n] check return attends main = B.getContents >>= solve . readInput . map (map int . B.words) . B.lines