import Data.List (sortBy, partition)
import Data.Function (on)
import Data.Functor ((<$>))
import Control.Monad (replicateM)

solve :: [(Int, Int)] -> [(Int, Int)] -> Int -> Int -> [Int] -> (Int, [Int])
solve ones twos cap accWt accItems
  | null ones = take' (cap `div` 2) twos
  | null twos = take' cap ones
  | cap < 2 = solve ones [] cap accWt accItems
  | twoOnes <= oneTwo =
      solve ones (tail twos) (cap - 2) (accWt + oneTwo) (snd (head twos) : accItems)
  | otherwise =
      solve (tail ones) twos (cap - 1) (accWt + fst (head ones)) (snd (head ones) : accItems)
  where
    take' n xs = (accWt + leftWt, leftItems ++ accItems)
      where
        leftWt = sum . map fst $ take n xs
        leftItems = map snd $ take n xs

    twoOnes = sum . map fst . take 2 $ ones
    oneTwo = fst . head $ twos

main :: IO ()
main = do
  [n, v] <- map read . words <$> getLine  -- n \leq 10^5, 1 \leq v \leq 10^9
  input <- replicateM n (map read . words <$> getLine)

  let (ones, twos) = partition ((== 1) . head . fst) $ zip input [1..]
      revSort = sortBy (flip compare `on` fst)
      unpack = map $ \([_, w], i) -> (w, i)
      (cost, items) = solve (revSort $ unpack ones) (revSort $ unpack twos) v 0 []

  print cost
  putStrLn . unwords . map show $ items

module Main where

import qualified Data.ByteString.Char8 as BS

import Data.Maybe (fromJust)
import Data.Ord (comparing, Down(..))
import Control.Monad (replicateM, forM_)
import Data.List (sortOn)

newtype Id = Id Int deriving (Show, Eq)
type Capacity = Int

data Boat = Boat {
    boatId :: Id,
    boatCapacity :: Capacity
  } deriving (Show, Eq)

data BoatPark = BoatPark {
    kayaks :: [Boat],
    catamarans :: [Boat]
  } deriving (Show)

sortByCapacity :: [Boat] -> [Boat]
sortByCapacity =  sortOn (Down . boatCapacity)

sortBoatPark :: BoatPark -> BoatPark
sortBoatPark (BoatPark k c) = BoatPark (sortByCapacity k) (sortByCapacity c)

getBoatPark :: Int -> IO BoatPark
getBoatPark n = do
  boats <- replicateM n getInts
  return . sortBoatPark $ foldr addBoat (BoatPark [] []) (zip [1..] boats)

addBoat :: (Int, [Int]) -> BoatPark -> BoatPark
addBoat (id, [t, c]) park@(BoatPark ks cs) | t == 1 = park { kayaks = boat:ks }
                                           | t == 2 = park { catamarans = boat:cs }
  where boat = Boat (Id id) c

solve :: Capacity -> BoatPark -> (Capacity, [Id])
solve 0 _  = (0, [])
solve _ (BoatPark [] []) = (0, [])
solve c park@BoatPark { kayaks = k1:ks, catamarans = [] } = k1 $+ solve (c - 1) park { kayaks = ks }
solve 1 park = solve 1 park { catamarans = [] }
solve c park@BoatPark { kayaks = [], catamarans = c1:cs } = c1 $+ solve (c - 2) park { catamarans = cs }
solve c park@(BoatPark [k1] (c1:cs)) | boatCapacity k1 > boatCapacity c1 = k1 $+ solve (c - 1) park { kayaks = [] }
                                     | otherwise = c1 $+ solve (c - 2) park { catamarans = cs }
solve c park@(BoatPark (k1:k2:ks) (c1:cs)) | c `mod` 2 == 1 && kayaksBetter = k1 $+ solve (c - 1) park { kayaks = k2:ks }
                                           | kayaksBetter = k1 $+ k2 $+ solve (c - 2) park { kayaks = ks }
                                           | otherwise = c1 $+ solve (c - 2) park { catamarans = cs }
  where kayaksBetter = boatCapacity k1  + boatCapacity k2 > boatCapacity c1

($+) :: Boat -> (Capacity, [Id]) -> (Capacity, [Id])
(Boat id c) $+ (total, ids) = (total + c, id:ids)
infixr 3 $+

getInts :: IO [Int]
getInts = map (fst . fromJust . BS.readInt) . BS.words <$> BS.getLine

printSolution :: (Capacity, [Id]) -> IO ()
printSolution (c, ids) = do
  print c
  forM_ ids $ \(Id i) -> print i

main :: IO ()
main = do
  [n, c] <- getInts
  park <- getBoatPark n
  printSolution $ solve c park

{-# LANGUAGE BangPatterns #-}
import Numeric
import Control.Monad
import Data.List
import Debug.Trace

fastRead :: String -> Int
fastRead ('-':s) = case readDec s of [(n, "")] -> -n
fastRead !s = case readDec s of [(n, "")] -> n

data Boat = One Int Int | Two Int Int deriving (Eq, Ord)

makeBoat n [1, x] = One x n
makeBoat n [2, x] = Two x n

even' s1 s2 v = fill s1 s2 v []

odd' [] s2 v = fill [] s2 v []
odd' (s:ss) s2 v = fill ss s2 (v-1) [s]

fill :: [Boat] -> [Boat] -> Int -> [Boat] -> [Boat]
fill [] [] _ a = a
fill _ _ 0 a = a
fill (o:os) [] x a = fill os [] (x - 1) (o:a)
fill [] _ 1 a = a
fill [] (t:ts) x a = fill [] ts (x - 2) (t:a)
fill unos@(aa@(One a _):bb@(One b _):ones) dos@(cc@(Two c _):twos) x acc =
  if a + b > c
  then fill ones dos (x - 2) (aa:bb:acc)
  else fill unos twos (x - 2) (cc:acc)
fill [aa@(One a _)] dos@(cc@(Two c _):twos) x acc =
  if a > c
  then fill [] dos (x - 1) (aa:acc)
  else fill [aa] twos (x - 2) (cc:acc)

solve :: Int -> [Boat] -> (Int, [Int])
solve v boats =
  foldBoats $ case v `mod` 2 of
    0 -> even' s1 s2 v
    1 -> odd' s1 s2 v
  where
    p (One _ _) = True
    p (Two _ _) = False
    (b1, b2) = partition p boats
    (s1, s2) = (reverse $ sort b1, reverse $ sort b2)
    value (One x _) = x
    value (Two x _) = x
    no (One _ x) = x
    no (Two _ x) = x
    foldBoats = mapAccumL (\a h-> (a + value h, no h)) 0

main = do
  [n, v] <- getLine >>= (return . map fastRead . words)
  things <- forM [1..n] (\n -> getLine >>= (return . makeBoat n . map fastRead . words))
  let (res, boats) = solve v things
  print res
  forM_ boats (\b -> putStr $ show b ++ " ")

-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html
-- http://en.wikibooks.org/wiki/Haskell/Next_steps
-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html
-- http://en.wikipedia.org/wiki/Haskell_features#Examples
-- http://en.wikibooks.org/wiki/Haskell/More_on_datatypes

import Data.List

data Boat =
	Boat {  t	:: Int,
			w	:: Int,
			num	:: Int
		 }

cmp :: Boat -> Boat -> Ordering
cmp a b
	| s == 0	= EQ
	| s < 0		= LT
	| otherwise	= GT
		where s = (t a) * (w b) - (t b) * (w a)

greedy :: Int -> [Boat] -> [Boat] -> (Int, [Boat])
greedy a [] []	= (0, [])
greedy 0 _ _	= (0, [])
greedy a (h1:tl1) [] = update h1 (greedy (a - 1) tl1 [])
greedy 1 [] _	= (0, [])
greedy a [] (h2:tl2) = update h2 (greedy (a - 2) [] tl2)
greedy a (h1:tl1) (h2:tl2)
	| mod a 2 == 1	= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| w1 < (w h2)	= update h2 (greedy (a - 2) (h1:tl1) tl2)
	| otherwise		= update h1 (update (head tl1) (greedy (a - 2) (tail tl1) (h2:tl2)))
		where w1 = firstTwo (h1:tl1)

firstTwo :: [Boat] -> Int
firstTwo [] = 0
firstTwo (a:[]) = w a
firstTwo (a:b:c) = w a + w b

update :: Boat -> (Int, [Boat]) -> (Int, [Boat])
update b (c, d) = (c + (w b), b : d)

process :: Int -> [Int] -> [Boat]
process _ [] 			= []
process n (a : (b : c))	= (Boat a b n) : (process (n + 1) c)

isSize :: Int -> Boat -> Bool
isSize n b = n == (t b)

printAns :: [Boat] -> IO()
printAns [] = do
	putStr "\n"
printAns (a : []) = do
	putStrLn (show (num a))
printAns (a : b) = do
	putStr (show (num a))
	putStr " "
	printAns (b)

main :: IO()
main = do
	str <- getContents
	let input = map read (words (str))
	let v = head (tail (input))
	let slist = sortBy cmp (process 1 (tail (tail (input))))
	let list1 = filter (isSize 1) slist
	let list2 = filter (isSize 2) slist
	let ans = greedy v list1 list2
	putStrLn (show (fst ans))
	printAns (snd ans)

import Data.List
default (Int)
data S = S {t::Int, p::Int, number::Int}
findSolution (v, v', p') [] sList' = (p', sList')
findSolution (v, v', p') sList@(s:ss) sList' =
	if v' + t s == v then (p' + p s, s:sList') else
		if v' + t s < v then findSolution (v, v' + t s, p' + p s) ss (s:sList') else
		let {[i1, i2] = map (findIndex (\s -> t s == 1)) [sList, sList']} in
		case (i1, i2) of {(Just i1', Just i2') ->
			if p (sList !! i1') + p (sList' !! i2') < p s then
				one2two i2' sList' p' s
			else (p' + p (sList !! i1'), (sList !! i1'):sList');
		(Nothing, Just i2') -> if p s > p (sList' !! i2') then
				one2two i2' sList' p' s
			else (p', sList');
		(Nothing, Nothing) -> (p', sList')} where
		one2two i2' sList' p' s = let s'' = sList' !! i2' in
			(p' - p s'' + p s, s:filter ((/= (number s'')) . number) sList')

main = do { [n, v] <- map read `fmap` (getLine >>= return . words)
	; l <- inputArr n 1 []
	; let l1 =  l `seq` sortBy (\a b -> compare (average2 b) (average2 a)) l where
		average2 a = case t a of {1 -> (p a * 2); _ -> p a}
	; let (p', s) = l1 `seq` findSolution (v, 0, 0) l1 []
	; print p'
	; case s of {[] -> return (); s':ss' -> do {
		; putStr $! show $ number $ s'
		; mapM_ (\n -> putChar ' ' >> (putStr $ show $ number n)) ss'
	}}
	; putChar '\n'
}

inputArr n i s = if i <= n then getLine >>= \line -> let [t', p'] = map read $ words line in
		inputArr n (i+1) (S t' p' i : s)
	else return s

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy, (\\))
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int} deriving (Show, Eq)
compute s = show finalTotalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing (\v->fromIntegral (cost v)/fromIntegral (capacity v))) [Vehical n t p | (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          chooseVehicals = if totalCost chooseVehicals1 == volume || null remain
                           then chooseVehicals1
                           else adjustVehicals chooseVehicals1 remain
          finalTotalCapacity = totalCapacity chooseVehicals

totalCost =  (foldr (+) 0).(map cost)
totalCapacity = (foldr (+) 0).(map capacity)

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` totalCapacity) $ [x | x<-subsequences vehicals, totalCost x <= v]

adjustVehicals chooseVehicals1 remain = (chooseVehicals1 \\ lastCost1) ++ chooseVehicalsRemain v competeVehicals
    where lastCost1 = take 1 $ filter (\x->cost x==1) $ reverse chooseVehicals1
          nextCost1 = take 1 $ filter (\x->cost x==1) $ remain
          nextCost2 = take 1 $ filter (\x->cost x==2) $ remain
          competeVehicals = lastCost1 ++ nextCost1 ++ nextCost2
          v = 1 + length lastCost1

main = interact $unlines.compute

module Main (main) where

import qualified Data.List as L

readInt :: String ->Int
readInt = read

readPair l = map readInt (words l)

main :: IO ()
main = do
    instr <- getLine
    let [n, v] = readPair instr
    instr <- getContents
    let lodki = zip (map readPair (take n (lines instr))) [1..n]
    printResult $ solve n v lodki
    where

        printResult res = do
            print $ sum (map (\(w, n) -> w) res)
            printWhile res where
                printWhile [] = return ()
                printWhile (x:xs) = do
                    putStr $ (show (snd x)) ++ " "
                    printWhile xs

        solve n v lodki = findMax (reverse (take fitCatam catam))
                                  (take fitBayd bayd)
                                  (drop fitBayd bayd) where

            findMax [] bs _     = bs
            findMax cs bs []    = cs ++ bs
            findMax (c:cs) bs [one] = if (fst one) > (fst c)
                then findMax cs (one:bs) []
                else (c:cs) ++ bs
            findMax (c:cs) bs (one:two:oth) = if ((fst one) + (fst two)) > (fst c)
                then findMax cs (one:two:bs) oth
                else (c:cs) ++ bs

            bayd = filterLodok 1
            baydLen = length bayd

            catam = filterLodok 2
            catamLen = length catam

            fitCatam = min (div v 2) catamLen
            fitBayd = min (v - (fitCatam * 2)) baydLen

            filterLodok tp = L.sortBy (\a b -> compare b a) $
                map (\([_,w],n) -> (w,n)) $
                    filter (\([t,w],n) -> t == tp) lodki

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy, (\\))
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show, Eq)
compute s = show finalTotalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          --totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          --vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume*2-totalCost1*2) $ filter (\x->cost x==1) remain)
          --chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          chooseVehicals = if totalCost chooseVehicals1 == volume || null remain
                           then chooseVehicals1
                           else adjustVehicals chooseVehicals1 remain
          finalTotalCapacity = totalCapacity chooseVehicals

totalCost =  (foldr (+) 0).(map cost)
totalCapacity = (foldr (+) 0).(map capacity)

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v && (foldr (+) 0 $ map cost x) >= v-1]

adjustVehicals chooseVehicals1 remain = (chooseVehicals1 \\ (lastCost1 ++ lastCost2)) ++ chooseVehicalsRemain v competeVehicals
    where lastCost1 = take 1 $ filter (\x->cost x==1) $ reverse chooseVehicals1
          lastCost2 = take 1 $ filter (\x->cost x==2) $ reverse chooseVehicals1
          nextCost1 = take 3 $ filter (\x->cost x==1) $ remain
          nextCost2 = take 1 $ filter (\x->cost x==2) $ remain
          competeVehicals = lastCost1 ++ lastCost2 ++ nextCost1 ++ nextCost2
          v = 1 + totalCost lastCost1 + totalCost lastCost2

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy, (\\))
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show, Eq)
compute s = show finalTotalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          chooseVehicals = if totalCost chooseVehicals1 == volume || null remain
                           then chooseVehicals1
                           else adjustVehicals chooseVehicals1 remain
          finalTotalCapacity = totalCapacity chooseVehicals

totalCost =  (foldr (+) 0).(map cost)
totalCapacity = (foldr (+) 0).(map capacity)

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v && (foldr (+) 0 $ map cost x) >= v-1]

adjustVehicals chooseVehicals1 remain = (chooseVehicals1 \\ (lastCost1 ++ lastCost2)) ++ chooseVehicalsRemain v competeVehicals
    where lastCost1 = take 1 $ filter (\x->cost x==1) $ reverse chooseVehicals1
          lastCost2 = take 1 $ filter (\x->cost x==2) $ reverse chooseVehicals1
          nextCost1 = take 3 $ filter (\x->cost x==1) $ remain
          nextCost2 = take 1 $ filter (\x->cost x==2) $ remain
          competeVehicals = lastCost1 ++ lastCost2 ++ nextCost1 ++ nextCost2
          v = 1 + totalCost lastCost1 + totalCost lastCost2

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy, (\\))
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int} deriving (Show, Eq)
compute s = show (total capacity chooseVehicals) : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing (\v->fromIntegral (cost v)/fromIntegral (capacity v))) [Vehical n t p | (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          chooseVehicals = if total cost chooseVehicals1 == volume || null remain
                           then chooseVehicals1
                           else adjustVehicals chooseVehicals1 remain

adjustVehicals chooseVehicals1 remain = (chooseVehicals1 \\ lastCost1) ++ chooseVehicalsRemain v competeVehicals
    where lastCost1 = kOut 1 $ reverse chooseVehicals1
          nextCost1 = kOut 1 remain
          nextCost2 = kOut 2 remain
          competeVehicals = lastCost1 ++ nextCost1 ++ nextCost2
          v = 1 + length lastCost1
          kOut c = (take 1).(filter $ \x->cost x==c)

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` total capacity) $ [x | x<-subsequences vehicals, total cost x <= v]

total f =  (foldr (+) 0).(map f)

main = interact $unlines.compute

{-# LANGUAGE BangPatterns #-}
import Data.Ord (comparing)
import Data.List (sortBy,delete)
import Control.Arrow (second)
import Control.Monad (guard)

main = do
  [n,v] <- fmap (map read . words) getLine
  bs <- fmap ( sortBy (flip $ comparing boatDensity) .
               pairs 1 . map read . words )
          getContents
  let (f,c,bs0,bs0') = greedy v bs
      (rc,rbs) = maximum $
                 (c,map boatId bs0) :
                 map (second (map boatId)) (
                   nextKayak v f c bs0 bs0' ++
                   fitCatamaran  v f c bs0 bs0'
                 )
  print rc
  putStrLn $ unwords $ map show rbs

greedy v bs = go v 0 [] bs where
  go r c a [] = (v-r,c,a,[])
  go r c a (b:bs)
    | boatSize b > r = (v-r,c,a,b:bs)
    | otherwise = go (r - boatSize b) (c + boatDensity b * boatSize b `div` 2)
                     (b : a) bs

nextKayak v f c bs bs' = do
  guard (f < v)
  k <- take 1 (filter ((== 1) . boatSize) bs')
  return (c + boatDensity k `div` 2,k : bs)

fitCatamaran v f c bs bs' = do
  guard (f < v)
  guard (not (null bs'))
  let ct = head bs'
  guard (boatSize ct == 2)
  k <- take 1 (filter ((== 1) . boatSize) bs)
  return (c - boatDensity k `div` 2 + boatDensity ct,ct : delete k bs)

pairs !i (x:y:z) = (i,x,2*y `div` x) : pairs (i+1) z
pairs _ [] = []

boatId (i,_,_) = i
boatSize (_,s,_) = s
boatDensity (_,_,d) = d

{-# LANGUAGE BangPatterns #-}
import Data.Ord (comparing)
import Data.List (sortBy,delete)
import Control.Arrow (second)
import Control.Monad (guard)

--import Debug.Trace
trace = curry snd
traceShow = curry snd
tr x = traceShow x x

main :: IO ()
main = do
  [n,v] <- fmap (map read . words) getLine
  bs <- fmap (sortBy (flip $ comparing boatDensity) . pairs 1 . map read . words) getContents
  let (f,c,bs0,bs0') = tr $ greedy v bs
      (rc,rbs) = maximum $
                 (c,map boatId bs0) :
                 map (second (map boatId)) (
                   tr (nextKayak v f c bs0 bs0') ++
                   tr (fitCatamaran v f c bs0 bs0') :: [(Int,[Boat])]
                 )
                 :: (Int,[Int])
  print rc
  putStrLn $ unwords $ map show rbs

type Boat = (Int,Int,Int)
greedy :: Int -> [Boat] -> (Int,Int,[Boat],[Boat])
greedy v bs = go v 0 [] bs where
  go r c a bs | traceShow (r,c,a,bs) False = undefined
  go r c a [] = trace "Exhausted list" (v-r,c,a,[])
  go r c a (b:bs)
    | boatSize b > r = trace "Next would overflow" (v-r,c,a,b:bs)
    | otherwise = trace "Fits. Taking." $
                  go (r - boatSize b) (c + boatDensity b * boatSize b `div` 2)
                     (b : a) bs

nextKayak :: Int -> Int -> Int -> [Boat] -> [Boat] -> [(Int,[Boat])]
nextKayak v f c bs bs' = do
  guard (f < v)
  trace "nextKayak: f<v" (return ())
  k <- take 1 (filter ((== 1) . boatSize) bs')
  trace "Next kayak taken" (return ())
  return (c + boatDensity k `div` 2,k : bs)

fitCatamaran :: Int -> Int -> Int -> [Boat] -> [Boat] -> [(Int,[Boat])]
fitCatamaran v f c bs bs' = do
  guard (f < v)
  guard (not (null bs'))
  let ct = head bs'
  guard (boatSize ct == 2)
  trace "Have candidate catamaran" (return ())
  traceShow ct (return ())
  k <- take 1 (filter ((== 1) . boatSize) bs)
  trace "Have kayak to spare" (return ())
  traceShow k (return ())
  return (c - boatDensity k `div` 2 + boatDensity ct,ct : delete k bs)

pairs :: Int -> [Int] -> [(Int,Int,Int)]
pairs !i (x:y:z) = (i,x,2*y `div` x) : pairs (i+1) z
pairs _ [] = []

boatId,boatSize,boatDensity :: Boat -> Int
boatId (i,_,_) = i
boatSize (_,s,_) = s
boatDensity (_,_,d) = d

import Data.List (sortBy, foldl')
import Data.Function (on)
import Data.Functor ((<$>))
import Control.Monad (replicateM)

solve :: [(Int, Int)] -> [(Int, Int)] -> Int -> Int -> [Int] -> (Int, [Int])
solve ones twos cap accWt accItems
  | null ones = take' (cap `div` 2) twos
  | null twos = take' cap ones
  | cap < 2 = solve ones [] cap accWt accItems
  | twoOnes <= oneTwo =
      solve ones (tail twos) (cap - 2) (accWt + oneTwo) (snd (head twos) : accItems)
  | otherwise =
      solve (tail ones) twos (cap - 1) (accWt + fst (head ones)) (snd (head ones) : accItems)
  where
    take' n xs = (accWt + leftWt, leftItems ++ accItems)
      where
        leftWt = sum . map fst $ take n xs
        leftItems = map snd $ take n xs

    twoOnes = sum . map fst . take 2 $ ones
    oneTwo = fst . head $ twos

partition :: [([Int], Int)] -> ([(Int, Int)], [(Int, Int)])
partition = foldl' partition' ([], [])
  where partition' (acc1, acc2) ([w, v], i) =
          if w == 1 then ((v, i) : acc1, acc2) else (acc1, (v, i) : acc2)

main :: IO ()
main = do
  [n, v] <- map read . words <$> getLine  -- n \leq 10^5, 1 \leq v \leq 10^9
  input <- replicateM n (map read . words <$> getLine)

  let (ones, twos) = partition $ zip input [1..]
      revSort = sortBy (flip compare `on` fst)
      (cost, items) = solve (revSort ones) (revSort twos) v 0 []

  print cost
  putStrLn . unwords . map show $ items

import Data.List (sortBy, foldl')
import Data.Function (on)
import Data.Functor ((<$>))
import Control.Monad (replicateM)

solve :: [(Int, Int)] -> [(Int, Int)] -> Int -> Int -> [Int] -> (Int, [Int])
solve ones twos cap accWt accItems
  | null ones = take' (cap `div` 2) twos
  | null twos = take' cap ones
  | cap < 2 = solve ones [] cap accWt accItems
  | twoOnes <= oneTwo =
      solve ones (tail twos) (cap - 2) (accWt + oneTwo) (snd (head twos) : accItems)
  | otherwise =
      solve (drop 2 ones) twos (cap - twoCost) (accWt + twoOnes) (map snd (take 2 ones) ++ accItems)
  where
    take' n xs = (accWt + leftWt, leftItems ++ accItems)
      where
        leftWt = sum . map fst $ take n xs
        leftItems = map snd $ take n xs

    twoOnes = sum . map fst . take 2 $ ones
    twoCost = length . take 2 $ ones
    oneTwo = fst . head $ twos

partition :: [([Int], Int)] -> ([(Int, Int)], [(Int, Int)])
partition = foldl' partition' ([], [])
  where partition' (acc1, acc2) ([w, v], i) =
          if w == 1 then ((v, i) : acc1, acc2) else (acc1, (v, i) : acc2)

main :: IO ()
main = do
  [n, v] <- map read . words <$> getLine  -- n \leq 10^5, 1 \leq v \leq 10^9
  input <- replicateM n (map read . words <$> getLine)

  let (ones, twos) = partition $ zip input [1..]
      revSort = sortBy (flip compare `on` fst)
      (cost, items) = solve (revSort ones) (revSort twos) v 0 []

  print cost
  putStrLn . unwords . map show $ items

import Data.List (sortBy, foldl')
import Data.Function (on)
import Data.Functor ((<$>))
import Control.Monad (replicateM)

solve :: [(Int, Int)] -> [(Int, Int)] -> Int -> Int -> [Int] -> (Int, [Int])
solve ones twos cap accWt accItems
  | null ones = take' (cap `div` 2) twos
  | null twos = take' cap ones
  | cap < 2 = solve ones [] cap accWt accItems
  | twoOnes <= oneTwo =
      solve ones (tail twos) (cap - 2) (accWt + oneTwo) (snd (head twos) : accItems)
  | otherwise =
      solve (drop 2 ones) twos (cap - 2) (accWt + twoOnes) (map snd (take 2 ones) ++ accItems)
  where
    take' n xs = (accWt + leftWt, leftItems ++ accItems)
      where
        leftWt = sum . map fst $ take n xs
        leftItems = map snd $ take n xs

    twoOnes = sum . map fst . take 2 $ ones
    oneTwo = fst . head $ twos

partition :: [([Int], Int)] -> ([(Int, Int)], [(Int, Int)])
partition = foldl' partition' ([], [])
  where partition' (acc1, acc2) ([w, v], i) =
          if w == 1 then ((v, i) : acc1, acc2) else (acc1, (v, i) : acc2)

main :: IO ()
main = do
  [n, v] <- map read . words <$> getLine  -- n \leq 10^5, 1 \leq v \leq 10^9
  input <- replicateM n (map read . words <$> getLine)

  let (ones, twos) = partition $ zip input [1..]
      revSort = sortBy (flip compare `on` fst)
      (cost, items) = solve (revSort ones) (revSort twos) v 0 []

  print cost
  putStrLn . unwords . map show $ items

-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html
-- http://en.wikibooks.org/wiki/Haskell/Next_steps
-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html
-- http://en.wikipedia.org/wiki/Haskell_features#Examples
-- http://en.wikibooks.org/wiki/Haskell/More_on_datatypes

import Data.List

data Boat =
	Boat {  t	:: Int,
			w	:: Int,
			num	:: Int
		 }

cmp :: Boat -> Boat -> Ordering
cmp a b
	| s == 0	= EQ
	| s < 0		= LT
	| otherwise	= GT
		where s = (t a) * (w b) - (t b) * (w a)

greedy :: Int -> [Boat] -> [Boat] -> (Int, [Boat])
greedy a [] []	= (0, [])
greedy 0 _ _	= (0, [])
greedy a (h1:tl1) [] = update h1 (greedy (a - 1) tl1 [])
greedy 1 [] _	= (0, [])
greedy a [] (h2:tl2) = update h2 (greedy (a - 2) [] tl2)
greedy a (h1:tl1) (h2:tl2)
	| a == 1		= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| w1 < (w h2)	= update h2 (greedy (a - 2) (h1:tl1) tl2)
	| null tl1		= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| otherwise		= update h1 (update (head (tail tl1)) (greedy (a - 2) (tail tl1) (h2: tl2)))
		where w1 = firstTwo (h1:tl1)

firstTwo :: [Boat] -> Int
firstTwo [] = 0
firstTwo (a:[]) = w a
firstTwo (a:b:c) = w a + w b

update :: Boat -> (Int, [Boat]) -> (Int, [Boat])
update b (c, d) = (c + (w b), b : d)

process :: Int -> [Int] -> [Boat]
process _ [] 			= []
process n (a : (b : c))	= (Boat a b n) : (process (n + 1) c)

isSize :: Int -> Boat -> Bool
isSize n b = n == (t b)

printAns :: [Boat] -> IO()
printAns (a : []) = do
	putStr (show (num a))
printAns (a : b) = do
	putStr (show (num a))
	putStr " "
	printAns (b)

main :: IO()
main = do
	str <- getContents
	let input = map read (words (str))
	let v = head (tail (input))
	let slist = sortBy cmp (process 1 (tail (tail (input))))
	let list1 = filter (isSize 1) slist
	let list2 = filter (isSize 2) slist
	let ans = greedy v list1 list2
	putStrLn (show (fst ans))
	printAns (snd ans)

-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html
-- http://en.wikibooks.org/wiki/Haskell/Next_steps
-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html
-- http://en.wikipedia.org/wiki/Haskell_features#Examples
-- http://en.wikibooks.org/wiki/Haskell/More_on_datatypes

import Data.List

data Boat =
	Boat {  t	:: Int,
			w	:: Int,
			num	:: Int
		 }

cmp :: Boat -> Boat -> Ordering
cmp a b
	| s == 0	= EQ
	| s < 0		= LT
	| otherwise	= GT
		where s = (t a) * (w b) - (t b) * (w a)

greedy :: Int -> [Boat] -> [Boat] -> (Int, [Boat])
greedy a [] []	= (0, [])
greedy 0 _ _	= (0, [])
greedy a (h1:tl1) [] = update h1 (greedy (a - 1) tl1 [])
greedy 1 [] _	= (0, [])
greedy a [] (h2:tl2) = update h2 (greedy (a - 2) [] tl2)
greedy a (h1:tl1) (h2:tl2)
	| a == 1		= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| w1 < (w h2)	= update h2 (greedy (a - 2) (h1:tl1) tl2)
	| null tl1		= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| a == 3 && (w (head tl1) < w h2) = update h1 (update (h2) (greedy 0 tl1 tl2))
	| otherwise		= update h1 (update (head tl1) (greedy (a - 2) (tail tl1) (h2: tl2)))
		where w1 = firstTwo (h1:tl1)

firstTwo :: [Boat] -> Int
firstTwo [] = 0
firstTwo (a:[]) = w a
firstTwo (a:b:c) = w a + w b

update :: Boat -> (Int, [Boat]) -> (Int, [Boat])
update b (c, d) = (c + (w b), b : d)

process :: Int -> [Int] -> [Boat]
process _ [] 			= []
process n (a : (b : c))	= (Boat a b n) : (process (n + 1) c)

isSize :: Int -> Boat -> Bool
isSize n b = n == (t b)

printAns :: [Boat] -> IO()
printAns (a : []) = do
	putStrLn (show (num a))
printAns (a : b) = do
	putStr (show (num a))
	putStr " "
	printAns (b)

main :: IO()
main = do
	str <- getContents
	let input = map read (words (str))
	let v = head (tail (input))
	let slist = sortBy cmp (process 1 (tail (tail (input))))
	let list1 = filter (isSize 1) slist
	let list2 = filter (isSize 2) slist
	let ans = greedy v list1 list2
	putStrLn (show (fst ans))
	printAns (snd ans)

-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html
-- http://en.wikibooks.org/wiki/Haskell/Next_steps
-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-List.html
-- http://en.wikipedia.org/wiki/Haskell_features#Examples
-- http://en.wikibooks.org/wiki/Haskell/More_on_datatypes

import Data.List

data Boat =
	Boat {  t	:: Int,
			w	:: Int,
			num	:: Int
		 }

cmp :: Boat -> Boat -> Ordering
cmp a b
	| s == 0	= EQ
	| s < 0		= LT
	| otherwise	= GT
		where s = (t a) * (w b) - (t b) * (w a)

greedy :: Int -> [Boat] -> [Boat] -> (Int, [Boat])
greedy a [] []	= (0, [])
greedy 0 _ _	= (0, [])
greedy a (h1:tl1) [] = update h1 (greedy (a - 1) tl1 [])
greedy 1 [] _	= (0, [])
greedy a [] (h2:tl2) = update h2 (greedy (a - 2) [] tl2)
greedy a (h1:tl1) (h2:tl2)
	| a == 1		= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| w1 < (w h2)	= update h2 (greedy (a - 2) (h1:tl1) tl2)
	| null tl1		= update h1 (greedy (a - 1) tl1 (h2:tl2))
	| otherwise		= update h1 (update (head tl1) (greedy (a - 2) (tail tl1) (h2: tl2)))
		where w1 = firstTwo (h1:tl1)

firstTwo :: [Boat] -> Int
firstTwo [] = 0
firstTwo (a:[]) = w a
firstTwo (a:b:c) = w a + w b

update :: Boat -> (Int, [Boat]) -> (Int, [Boat])
update b (c, d) = (c + (w b), b : d)

process :: Int -> [Int] -> [Boat]
process _ [] 			= []
process n (a : (b : c))	= (Boat a b n) : (process (n + 1) c)

isSize :: Int -> Boat -> Bool
isSize n b = n == (t b)

printAns :: [Boat] -> IO()
printAns (a : []) = do
	putStrLn (show (num a))
printAns (a : b) = do
	putStr (show (num a))
	putStr " "
	printAns (b)

main :: IO()
main = do
	str <- getContents
	let input = map read (words (str))
	let v = head (tail (input))
	let slist = sortBy cmp (process 1 (tail (tail (input))))
	let list1 = filter (isSize 1) slist
	let list2 = filter (isSize 2) slist
	let ans = greedy v list1 list2
	putStrLn (show (fst ans))
	printAns (snd ans)

-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Prelude.html
-- http://en.wikibooks.org/wiki/Haskell/Next_steps
-- http://hackage.haskell.org/packages/archive/base/latest/doc/html/Data-Int.html
-- http://en.wikipedia.org/wiki/Haskell_features#Examples
-- http://en.wikibooks.org/wiki/Haskell/More_on_datatypes

import Data.List

data Boat =
	Boat {  t	:: Int,
			w	:: Int,
			num	:: Int
		 }

cmp :: Boat -> Boat -> Ordering
cmp a b
	| s == 0	= EQ
	| s < 0		= LT
	| otherwise	= GT
		where s = (t a) * (w b) - (t b) * (w a)

greedy :: Int -> [Boat] -> (Int, [Boat])
greedy a [] = (0, [])
greedy a (h:tl)
	| a == 0				= (0, [])
	| a == 1 && (t h) == 2	= greedy a tl
	| otherwise				= update (w h) h (greedy (a - (t h)) tl)

update :: Int -> Boat -> (Int, [Boat]) -> (Int, [Boat])
update a b (c, d) = (c + a, b : d)

process :: Int -> [Int] -> [Boat]
process _ [] 			= []
process n (a : (b : c))	= (Boat a b n) : (process (n + 1) c)

printAns :: [Boat] -> IO()
printAns (a : []) = do
	putStr (show (num a))
printAns (a : b) = do
	putStr (show (num a))
	putStr " "
	printAns (b)

main :: IO()
main = do
	str <- getContents
	let input = map read (words (str))
	let v = head (tail (input))
	let ans = greedy v (sortBy cmp (process 1 (tail (tail (input)))))
	putStrLn (show (fst ans))
	printAns (snd ans)

module Main (main) where

import qualified Data.List as L

readInt :: String ->Int
readInt = read

readPair l = map readInt (words l)

main :: IO ()
main = do
    instr <- getLine
    let [n, v] = readPair instr
    instr <- getContents
    let lodki = zip (map readPair (take n (lines instr))) [1..n]
    printResult $ solve n v lodki
    where

        printResult res = do
            print $ sum (map (\(w, n) -> w) res)
            printWhile res where
                printWhile [] = return ()
                printWhile (x:xs) = putStr $ (show (snd x)) ++ " "

        solve n v lodki = findMax (reverse (take fitCatam catam))
                                  (take fitBayd bayd)
                                  (drop fitBayd bayd) where

            findMax [] bs _     = bs
            findMax cs bs []    = cs ++ bs
            findMax (c:cs) bs [one] = if (fst one) > (fst c)
                then findMax cs (one:bs) []
                else findMax (c:cs) bs []
            findMax (c:cs) bs (one:two:oth) = if ((fst one) + (fst two)) > (fst c)
                then findMax cs (one:two:bs) oth
                else findMax (c:cs) bs []

            bayd = filterLodok 1
            baydLen = length bayd

            catam = filterLodok 2
            catamLen = length catam

            fitCatam = min (div v 2) catamLen
            fitBayd = min (v - (fitCatam * 2)) baydLen

            filterLodok tp = L.sortBy (\a b -> compare b a) $
                map (\([_,w],n) -> (w,n)) $
                    filter (\([t,w],n) -> t == tp) lodki

import List (sortBy, partition)

{-
import HUnit

testEmpty  =  Test "TestEmpty" $ assertEq [] (solve 1 1 [(2,1)])

testOne  =  Test "TestOne" $ assertEq [(1,1,[1])] (solve 1 1 [(1,1)])

testInput  =  Test "TestInput" $ assertEq [(2,7,[2])] (solve 3 2 [(1,2),(2,7),(1,3)])

testDifficultChoose  =  Test "TestDifficultChoose" $
    assertEq [(2, 13, [3, 4]), (1, 5, [5])] (solve 5 3 [(2,1), (2,12), (1,7), (1,6), (1,5)])

test  =  mapM_ run
  [
    testEmpty,
    testOne,
    testInput,
    testDifficultChoose
  ]
-}
--------------------------------------------------------------------------------

solve :: Int -> Int -> [(Int, Int)] -> [(Int, Int, [Int])]
solve n k xs  =  solve' k catamaransAndBoatSort
  where
    xsWithNumbers  =  zipWith (\(v,c) n -> (v, c, [n])) xs [1..n]
    (catamarans, boats)  =  partition (\(v, _, _) -> v == 2) xsWithNumbers
    boatsSort  =  sortBy (\(_, c1, _) (_, c2, _) -> compare c2 c1) boats
    boats'  =  if odd $ length boats then [last boatsSort] else []
    catamaransAndBoat  =  boats' ++ getCatamaran boatsSort ++ catamarans
    getCatamaran ((_, c1, n1):(_, c2, n2):bs)  =  (2, c1+c2, n1 ++ n2) : getCatamaran bs
    getCatamaran _  =  []
    catamaransAndBoatSort  =  sortBy (\(_, c1, _) (_, c2, _) -> compare c2 c1) catamaransAndBoat
    solve' k []  =  []
    solve' k ((v, c, num):bs)
      | k >= v  =  (v, c, num) : solve' (k-v) bs
      | otherwise  =  solve' k bs

getPair :: IO (Int, Int)
getPair  =  do
    [x, y]  <-  getLine >>= return . map read . words
    return (x, y)

printAns :: [(Int, Int, [Int])] -> IO ()
printAns ans  =  do
    let res  =  sum $ map (\(_, c, _) -> c) ans
    print res
    printAns' ans
  where
    printAns' []  =  return ()
    printAns' ((_, _, [n]) : ans)  =  putStr (concat [show n, " "]) >> printAns' ans
    printAns' ((_, _, [n, m]) : ans)  =  putStr (concat [show n, " ", show m, " "]) >> printAns' ans

main :: IO ()
main  =  do
    (n, v)  <-  getPair
    boats  <-  mapM (const getPair) [1..n]
    printAns $ solve n v boats

import Data.List
import Control.Monad
import qualified Data.ByteString.Char8 as B
r = do
  l <- B.getLine
  let Just (a,l') = B.readInt l
      Just (b,_) = B.readInt (B.tail l')
  return (a,b)
f ((a,b),c) = (b,c)
main = do
  (n,v) <- r
  (ks,cs) <- liftM (partition ((==1) . fst . fst) . flip zip [1..]) (replicateM n r)
  let cp = uncurry (flip delete) $
           solve v (sortBy (flip compare) $ map f ks)
                   (sortBy (flip compare) $ map f cs)
                   [] (0,10^15)
  print $ sum $ map fst cp
  putStrLn $ unwords $ map (show . snd) cp
solve 0 _ _ vs _ = (vs,(0,0))
solve 1 (k:_) (c:_) vs p = if fst c - fst p > fst k
                           then ((c:vs),p)
                           else ((k:vs),(0,0))
solve 1 _ (c:_) vs p | fst c > fst p = ((c:vs),p)
solve 2 (k1:k2:_) (c:_) vs _ = if fst k1 + fst k2 > fst c
                               then ((k1:k2:vs),(0,0))
                               else ((c:vs),(0,0))
solve _ [] [] vs _ = (vs,(0,0))
solve v (k:ks) [] vs _ | v >= 1 = solve (v-1) ks [] (k:vs) k
solve v [] (c:cs) vs p | v >= 2 = solve (v-2) [] cs (c:vs) p
                       | otherwise = (vs,(0,0))
solve v (k:ks) (c:cs) vs p = if 2*fst k > fst c
                             then solve (v-1) ks (c:cs) (k:vs) k
                             else solve (v-2) (k:ks) cs (c:vs) p

import Data.List
import Control.Monad
r = liftM (map read . words) getLine >>= \[a,b] -> return (a,b)
f ((a,b),c) = (b,c)
main = do
  (n,v) <- r
  (ks,cs) <- liftM (partition ((==1) . fst . fst) . flip zip [1..]) (replicateM n r)
  let cp = solve v (sortBy (flip compare) $ map f ks)
                   (sortBy (flip compare) $ map f cs)
  print $ sum $ map fst cp
  putStrLn $ unwords $ map (show . snd) cp
solve 0 _ _ = []
solve _ [] [] = []
solve v (k:ks) [] | v >= 1 = k : solve (v-1) ks []
solve v [] (c:cs) | v >= 2 = c : solve (v-2) [] cs
                  | otherwise = []
solve 2 (k1:k2:_) (c:_) = if fst k1 + fst k2 > fst c then [k1,k2] else [c]
solve v (k:ks) (c:cs) = if 2*fst k > fst c
                        then k : solve (v-1) ks (c:cs)
                        else c : solve (v-2) (k:ks) cs

{-# LANGUAGE BangPatterns #-}
import Data.Ord (comparing)
import Data.List (sortBy,delete)
import Control.Arrow (second)
import Control.Monad (guard)
-- import Debug.Trace

trace = curry snd
traceShow = curry snd
tr x = traceShow x x

main :: IO ()
main = do
  [n,v] <- fmap (map read . words) getLine
  bs <- fmap (sortBy (flip $ comparing boatDensity) . pairs 1 . map read . words) getContents
  let (f,c,bs0,bs0') = tr $ greedy v bs
      (rc,rbs) = maximum $
                 (c,map boatId bs0) :
                 map (second (map boatId)) (
                   nextKayak v f c bs0 bs0' ++
                   fitCatamaran v f c bs0 :: [(Int,[Boat])]
                 )
                 :: (Int,[Int])
  print rc
  putStrLn $ unwords $ map show rbs

type Boat = (Int,Int,Int)
greedy :: Int -> [Boat] -> (Int,Int,[Boat],[Boat])
greedy v bs = go v 0 [] bs where
  go r c a bs | traceShow (r,c,a,bs) False = undefined
  go r c a [] = trace "Exhausted list" (v-r,c,a,[])
  go r c a (b:bs)
    | boatSize b > r = trace "Next would overflow" (v-r,c,a,b:bs)
    | otherwise = trace "Fits. Taking." $
                  go (r - boatSize b) (c + boatDensity b * boatSize b `div` 2)
                     (b : a) bs

nextKayak :: Int -> Int -> Int -> [Boat] -> [Boat] -> [(Int,[Boat])]
nextKayak v f c bs bs' = do
  guard (f < v)
  trace "nextKayak: f<v" (return ())
  k <- take 1 (filter ((== 1) . boatSize) bs')
  return (c + boatDensity k `div` 2,k : bs)

fitCatamaran :: Int -> Int -> Int -> [Boat] -> [(Int,[Boat])]
fitCatamaran v f c bs = do
  guard (f < v)
  k <- take 1 (filter ((== 1) . boatSize) bs)
  guard (not (null bs))
  let ct = head bs
  guard (boatSize ct == 2)
  return (c - boatDensity k `div` 2 + boatDensity ct,ct : delete k bs)

pairs :: Int -> [Int] -> [(Int,Int,Int)]
pairs !i (x:y:z) = (i,x,2*y `div` x) : pairs (i+1) z
pairs _ [] = []

boatId,boatSize,boatDensity :: Boat -> Int
boatId (i,_,_) = i
boatSize (_,s,_) = s
boatDensity (_,_,d) = d

import Data.Ord
import Data.List
main = interact $ unlines . solve . map read . words
solve (n:v:xs) = go is 0 v [] where
  is = sortBy (flip $ comparing (snd . snd)) $ zip [1..] $ parse xs
  go is c w bs | null is || w == 0 = present c bs
  go ((_,(2,d)):is) c 1 bs = go is c 1 bs
  go ((b,(t,d)):is) c w bs = go is (c + t*d`div`2) (w-t) (b:bs)
  present c bs = [show c,unwords (map show bs)]
parse (t:p:xs) = (t,2*p`div`t) : parse xs
parse [] = []

{-# LANGUAGE BangPatterns #-}
import Data.Ord (comparing)
import Data.List (sortBy,delete)
import Control.Arrow (second)
import Control.Monad (guard)
-- import Debug.Trace

trace = curry snd
traceShow = curry snd
tr x = traceShow x x

main :: IO ()
main = do
  [n,v] <- fmap (map read . words) getLine
  bs <- fmap (sortBy (flip $ comparing boatDensity) . pairs 1 . map read . words) getContents
  let (f,c,bs0,bs0') = tr $ greedy v bs
      (rc,rbs) = maximum $
                 (c,map boatId bs0) :
                 map (second (map boatId)) (
                   nextKayak v f c bs0 bs0' ++
                   fitCatamaran v f c bs0 :: [(Int,[Boat])]
                 )
                 :: (Int,[Int])
  print rc
  putStrLn $ unwords $ map show rbs

type Boat = (Int,Int,Int)
greedy :: Int -> [Boat] -> (Int,Int,[Boat],[Boat])
greedy v bs = go v 0 [] bs where
  go r c a bs | traceShow (r,c,a,bs) False = undefined
  go r c a [] = trace "Exhausted list" (v-r,c,a,[])
  go r c a (b:bs)
    | boatSize b > r = trace "Next would overflow" (v-r,c,a,b:bs)
    | otherwise = trace "Fits. Taking." $
                  go (r - boatSize b) (c + boatDensity b `div` boatSize b)
                     (b : a) bs

nextKayak :: Int -> Int -> Int -> [Boat] -> [Boat] -> [(Int,[Boat])]
nextKayak v f c bs bs' = do
  guard (f < v)
  trace "nextKayak: f<v" (return ())
  k <- take 1 (filter ((== 1) . boatSize) bs')
  return (c + boatDensity k `div` 2,k : bs)

fitCatamaran :: Int -> Int -> Int -> [Boat] -> [(Int,[Boat])]
fitCatamaran v f c bs = do
  guard (f < v)
  k <- take 1 (filter ((== 1) . boatSize) bs)
  guard (not (null bs))
  let ct = head bs
  guard (boatSize ct == 2)
  return (c - boatDensity k `div` 2 + boatDensity ct,ct : delete k bs)

pairs :: Int -> [Int] -> [(Int,Int,Int)]
pairs !i (x:y:z) = (i,x,x*y) : pairs (i+1) z
pairs _ [] = []

boatId,boatSize,boatDensity :: Boat -> Int
boatId (i,_,_) = i
boatSize (_,s,_) = s
boatDensity (_,_,d) = d

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-3)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCost1+1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) vehicals2
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile)
import Data.Ord(comparing)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume)  $ scanl1 (+) $ map cost vehicals
          chooseVehicals = take pos vehicals
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanr, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-3)  $ scanr (+) 0 $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCost1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) vehicals2
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show volume : []--show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          --pos = length $ takeWhile (<=volume-3)  $ scanl1 (+) $ map cost vehicals
          --(chooseVehicals1, remain) = splitAt pos vehicals
          --totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          --vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume*2-totalCost1*2) $ filter (\x->cost x==1) remain)
          --chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          chooseVehicals = chooseVehicalsRemain volume vehicals
          totalCapacity = scanl1 (+) $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v && (foldr (+) 0 $ map cost x) >= v-1]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-2)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume*2-totalCost1*2) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-2)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCost1+1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy, (\\))
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show, Eq)
compute s = show finalTotalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          --totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          --vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume*2-totalCost1*2) $ filter (\x->cost x==1) remain)
          --chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          chooseVehicals = if totalCost chooseVehicals1 == volume || null remain
                           then chooseVehicals1
                           else adjustVehicals chooseVehicals1 remain
          finalTotalCapacity = totalCapacity chooseVehicals

totalCost =  (foldr (+) 0).(map cost)
totalCapacity = (foldr (+) 0).(map capacity)

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v && (foldr (+) 0 $ map cost x) >= v-1]

adjustVehicals chooseVehicals1 remain = (chooseVehicals1 \\ (lastCost1 ++ lastCost2)) ++ chooseVehicalsRemain v competeVehicals
    where lastCost1 = take 1 $ filter (\x->cost x==1) $ reverse chooseVehicals1
          lastCost2 = take 1 $ filter (\x->cost x==2) $ reverse chooseVehicals1
          nextCost1 = take 3 $ filter (\x->cost x==1) $ remain
          nextCost2 = take 1 $ filter (\x->cost x==2) $ remain
          competeVehicals = lastCost1 ++ lastCost2 ++ nextCost1 ++ nextCost2
          v = 1 + totalCost lastCost1 + totalCost lastCost1

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show volume : []--show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          --pos = length $ takeWhile (<=volume-3)  $ scanl1 (+) $ map cost vehicals
          --(chooseVehicals1, remain) = splitAt pos vehicals
          --totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          --vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume*2-totalCost1*2) $ filter (\x->cost x==1) remain)
          --chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          chooseVehicals = chooseVehicalsRemain volume vehicals
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v && (foldr (+) 0 $ map cost x) >= v-1]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-2)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCost1+1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) vehicals2
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanr, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-2)  $ scanr (+) 0 $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCost1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) vehicals2
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl1, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-3)  $ scanl1 (+) $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume*2-totalCost1*2) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanr, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-3)  $ scanr (+) 0 $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCapacity1 = foldr (+) 0 $ map capacity chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCapacity1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCapacity1) vehicals2
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanr, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-2)  $ scanr (+) 0 $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCapacity1 = foldr (+) 0 $ map capacity chooseVehicals1
          vehicals2 = (take 1 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCapacity1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCapacity1) vehicals2
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

import Data.List.Split(splitOneOf, chunksOf)
import Data.List(sortBy, scanl, takeWhile, subsequences, maximumBy)
import Data.Ord(comparing)
import Data.Function(on)

data Vehical = Vehical {no::Int, cost::Int, capacity::Int, ratio::Float} deriving (Show)
compute s = show totalCapacity : map (show.no) chooseVehicals
    where nums = map read $ splitOneOf " \n" s
          volume = head.tail $ nums
          vehicals = sortBy (comparing ratio) [Vehical n t p (fromIntegral t/fromIntegral p)| (n, [t, p])<-zip [1..] $ chunksOf 2 $ drop 2 nums]
          pos = length $ takeWhile (<=volume-2)  $ scanl (+) 0 $ map cost vehicals
          (chooseVehicals1, remain) = splitAt pos vehicals
          totalCost1 = foldr (+) 0 $ map cost chooseVehicals1
          vehicals2 = (take 2 $ filter (\x->cost x==2) remain) ++ (take (volume-totalCost1+1) $ filter (\x->cost x==1) remain)
          chooseVehicals = chooseVehicals1 ++ chooseVehicalsRemain (volume-totalCost1) remain
          totalCapacity = foldr (+) 0 $ map capacity chooseVehicals
          --chooseVehicals = chooseVehicalsRemain volume vehicals
          --totalCapacity = foldr (+) 0 $ map capacity chooseVehicals

chooseVehicalsRemain:: Int->[Vehical]->[Vehical]
chooseVehicalsRemain v vehicals = maximumBy (compare `on` ((foldr (+) 0).(map capacity))) $ [x | x<-subsequences vehicals, (foldr (+) 0 $ map cost x) <= v]

main = interact $unlines.compute

{-# LANGUAGE BangPatterns #-}
import Numeric
import Control.Monad
import Data.List
import Debug.Trace

fastRead :: String -> Int
fastRead ('-':s) = case readDec s of [(n, "")] -> -n
fastRead !s = case readDec s of [(n, "")] -> n

data Boat = One Int Int | Two Int Int deriving (Eq, Ord)

makeBoat n [1, x] = One x n
makeBoat n [2, x] = Two x n

even' s1 s2 v = fill s1 s2 v []

odd' [] s2 v = fill [] s2 v []
odd' (s:ss) s2 v = fill ss s2 (v-1) [s]

fill :: [Boat] -> [Boat] -> Int -> [Boat] -> [Boat]
fill [] [] _ a = a
fill _ _ 0 a = a
fill (o:os) [] x a = fill os [] (x - 1) (o:a)
fill [] _ 1 a = a
fill [] (t:ts) x a = fill [] ts (x - 2) (t:a)
fill unos@(aa@(One a _):bb@(One b _):ones) dos@(cc@(Two c _):twos) x acc =
  if a + b > c
  then fill ones dos (x - 2) (aa:bb:acc)
  else fill unos twos (x - 2) (cc:acc)
fill [aa@(One a _)] dos@(cc@(Two c _):twos) x acc =
  if a > c
  then fill [] dos (x - 1) (aa:acc)
  else fill [aa] twos (x - 2) (cc:acc)

solve :: Int -> [Boat] -> (Int, [Int])
solve v boats =
  foldBoats $ case v `mod` 2 of
    0 -> even' s1 s2 v
    1 -> odd' s1 s2 v
  where
    p (One _ _) = True
    p (Two _ _) = False
    (b1, b2) = partition p boats
    (s1, s2) = (reverse $ sort b1, reverse $ sort b2)
    value (One x _) = x
    value (Two x _) = x
    no (One _ x) = x
    no (Two _ x) = x
    foldBoats = mapAccumL (\a h-> (a + value h, no h)) 0

main = do
  [n, v] <- getLine >>= (return . map fastRead . words)
  things <- forM [1..n] (\n -> getLine >>= (return . makeBoat n . map fastRead . words))
  let (res, boats) = solve v things
  print res
  forM_ boats (\b -> putStr $ show b)


{-# OPTIONS_GHC -O2 -XNoMonomorphismRestriction #-}
{-# LANGUAGE BangPatterns #-}
{-(c) gorlum0 [at] gmail.com-}
import qualified Data.ByteString.Char8 as BS
import qualified Data.IntSet as S
import Data.List
import Data.Array
import Data.Char
import Control.Monad
import Debug.Trace (trace)
import Data.Maybe (fromJust)
import Text.Printf (printf)

solve [t, b, e] = sum $ map S.size ss
    where
    len = BS.length
    [n, m] = map len [b, e]
    xs = BS.findSubstrings b t
    ys = map (+m) $ BS.findSubstrings e t

    h = listArray (0,len t) $ scanl g 0 (BS.unpack t)
        -- Int qualification gave ~3x speed up on codeforces
        where g x c = x*31 + (fI $ ord c) :: Int

    -- subsequences
    ss = [S.fromList $ f l xs ys | l <- [max n m .. len t]]

    f l (x:xs) (y:ys)
        | x + l < y  = f l xs (y:ys)
        | x + l > y  = f l (x:xs) ys
        | otherwise  = (h!y - h!x * 31^l) : f l xs ys
    f _ _ _ = []

    --ss = [S.fromList $ f' l 0 0 | l <- [max n m .. len t]]

    [u, v] = map length [xs, ys]
    xs' = listArray (0,u-1) xs
    ys' = listArray (0,v-1) ys

    f' l i j
        | i == u    = []
        | j == v    = []
        | x + l < y = f' l (i+1) j
        | x + l > y = f' l i (j+1)
        | otherwise = (h!y - h!x * 31^l) : f' l (i+1) (j+1)
        where x = xs'!i
              y = ys'!j

main = do
    ws <- BS.words `fmap` BS.getContents
    forM_ (splitEvery 3 ws) $
        print . solve

readNum = fst . fromJust . BS.readInteger
fI = fromIntegral
--- debug = flip trace
traceShow = trace . show
debug = flip traceShow
infixr 1 `debug2`
debug2 x msg = flip trace x (printf "%s: %s" msg $ show x)

infixr 1 ?
True ? x = const x
False ? _ = id

splitEvery _ [] = []
splitEvery n xs = ys : splitEvery n xs'
    where (ys, xs') = splitAt (fI n) xs

import Data.List
import Data.Function
import Data.Ord
import qualified Data.Set as Set

data Parsing a = Parsing
 (Maybe ((a -> Bool), (Parsing a))) -- success
 (Parsing a) -- fallback

stepParser ch (Parsing (Just (b, p)) _) | b ch = p
stepParser ch (Parsing _ fallback) = stepParser ch fallback

mkParsing :: Eq a => Parsing a  -- alternative parsing
             -> [a] -- primary parsing
             -> Parsing a
mkParsing prev [] = (Parsing Nothing prev)
mkParsing prev (ch:t) = Parsing (Just ((ch==), mkParsing (stepParser ch prev) t)) prev

parser str = p where p = mkParsing (Parsing (Just (const True, p)) undefined) str

parsed (Parsing Nothing _) = True
parsed _ = False

consumeOne ((h,t), p) = (t, stepParser h p)

ensureHeaded :: ([a], Parsing a) -> [((a, [a]), Parsing a)]
ensureHeaded (h : t, p) = [((h, t), p)]
ensureHeaded _ = []

ccNext :: Ord a => [([a], Parsing a)] -> [(a, [([a], Parsing a)])]
ccNext strs = map (\l -> (fst(fst(head l)), map consumeOne l)) $ groupBy ((==) `on` (fst . fst)) . sortBy (comparing (fst . fst)) $ (strs >>= ensureHeaded)

ccStep :: Ord a => [([a], Parsing a)] -> (Bool, [(a, [([a], Parsing a)])])
ccStep strs = (any (parsed . snd) strs, ccNext strs)

cc :: Ord a => Int -> [([a], Parsing a)] -> Int
cc skips strs = (if i && skips<=0 then 1 else 0) + sum (map (\(a,l) -> (cc (skips-1) l)) next) where
  (i, next) = ccStep strs

cnt prefix suffix str = cc (length prefix) (map (\s -> (s, ps)) $ (filter (prefix `isPrefixOf`) (tails str)))
 where
   ps = parser suffix

s[q,a,b]=cnt a b q
main = interact$show.s.words

{-# LANGUAGE MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-}
{-# OPTIONS_GHC -O2 #-}

import Data.List
import Data.Maybe
import Data.Char
import Data.Array.IArray
import Data.Array.Unboxed (UArray)
import Data.Int
import Data.Word
import Data.Ratio
import Data.Bits
import Data.Function
import Data.Ord
--import Control.Monad.State
import Control.Monad
import Control.Applicative
import Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as BS
import Data.Set (Set)
import qualified Data.Set as Set
import Data.Map (Map)
import qualified Data.Map as Map
import Data.IntMap (IntMap)
import qualified Data.IntMap as IntMap
import Data.Sequence (Seq, (<|), (|>), (><), ViewL(..), ViewR(..))
import qualified Data.Sequence as Seq
import qualified Data.Foldable as F
import Data.Graph

parseInput = do
    t <- readString
    sBegin <- readString
    sEnd <- readString
    return (t, sBegin, sEnd)
  where
    readInt = state $ fromJust . BS.readInt . BS.dropWhile isSpace
    readInteger = state $ fromJust . BS.readInteger . BS.dropWhile isSpace
    readString = state $ BS.span (not . isSpace) . BS.dropWhile isSpace
    readLine = state $ BS.span (not . isEoln) . BS.dropWhile isEoln
    isEoln ch = ch == '\r' || ch == '\n'

main = print =<< solve . evalState parseInput <$> BS.getContents

magic :: Word64
magic = 0xa2facedead -- wish not to be hacked

hash :: Word64 -> Char -> Word64
hash v ch = v * magic + fromIntegral (ord ch)

solve (t, sBegin, sEnd) = sum $ map solveLen [gap..len]
  where
    pBegin = BS.findSubstrings sBegin t
    pEnd = BS.findSubstrings sEnd t

    len = BS.length t
    lBegin = BS.length sBegin
    lEnd = BS.length sEnd

    gap = lBegin `max` lEnd

    vBegin = accumArray (||) False (0, len) [(p, True) | p <- pBegin] :: UArray Int Bool
    vEnd = accumArray (||) False (0, len) [(p + lEnd, True) | p <- pEnd] :: UArray Int Bool

    prefixHash = listArray (0, len) $ scanl hash 0 (BS.unpack t) :: UArray Int Word64

    solveLen l = length $ group $ sort hashes
      where
        magicl = magic ^ l
        hashes = [ (prefixHash ! (s + l)) - (prefixHash ! s) * magicl
                 | s <- [0..len - l]
                 , vBegin ! s && vEnd ! (s + l)
                 ]

----------------------------------------------------------------------
----------------------------------------------------------------------
----------------------------------------------------------------------

class (Monad m) => MonadState s m | m -> s where
	get :: m s
	put :: s -> m ()

modify :: (MonadState s m) => (s -> s) -> m ()
modify f = do
	s <- get
	put (f s)

gets :: (MonadState s m) => (s -> a) -> m a
gets f = do
	s <- get
	return (f s)

newtype State s a = State { runState :: s -> (a, s) }

instance Functor (State s) where
	fmap f m = State $ \s -> let
		(a, s') = runState m s
		in (f a, s')

instance Applicative (State s) where
    pure = return
    (<*>) = ap

instance Monad (State s) where
	return a = State $ \s -> (a, s)
	m >>= k  = State $ \s -> let
		(a, s') = runState m s
		in runState (k a) s'

instance MonadState s (State s) where
	get   = State $ \s -> (s, s)
	put s = State $ \_ -> ((), s)

evalState :: State s a -> s -> a
evalState m s = fst (runState m s)

execState :: State s a -> s -> s
execState m s = snd (runState m s)

mapState :: ((a, s) -> (b, s)) -> State s a -> State s b
mapState f m = State $ f . runState m

withState :: (s -> s) -> State s a -> State s a
withState f m = State $ runState m . f

state = State

import qualified Data.ByteString.Char8 as BS
import List
import Array
import Char
main=BS.getContents>>=print.s.BS.words
m v c=v*97+fromIntegral(ord c)::Int
s[t,b,e]=sum[length$group$sort$g i x y|i<-[max u v..w]]
 where
  x=BS.findSubstrings b t
  y=map(+v)$BS.findSubstrings e t
  u=BS.length b
  v=BS.length e
  w=BS.length t
  h=listArray(0,w)$scanl m 0(BS.unpack t)
  g l(x:xs)(y:ys)
   |x+l<y=g l xs(y:ys)
   |x+l>y=g l(x:xs)ys
   |1>0=(h!y-h!x*97^l):g l xs ys
  g l _ _=[]

{-# OPTIONS_GHC -O2 -XNoMonomorphismRestriction #-}
{-# LANGUAGE BangPatterns #-}
{-(c) gorlum0 [at] gmail.com-}
import qualified Data.ByteString.Char8 as BS
import qualified Data.IntSet as S
import Data.List
import Data.Array
import Data.Char
import Control.Monad
import Debug.Trace (trace)
import Data.Maybe (fromJust)
import Text.Printf (printf)

solve [t, b, e] = sum $ map S.size ss
    where
    len = BS.length
    [n, m] = map len [b, e]
    xs = BS.findSubstrings b t
    ys = map (+m) $ BS.findSubstrings e t
    [u, v] = map length [xs, ys]
    xs' = listArray (0,u-1) xs
    ys' = listArray (0,v-1) ys

    h = listArray (0,len t) $ scanl g 0 (BS.unpack t)
        where g x c = x*31 + (fI $ ord c)

    --ss = [S.fromList $ f l xs ys | l <- [max n m .. len t]]
    ss = [S.fromList $ f' l 0 0 | l <- [max n m .. len t]]

    f l (x:xs) (y:ys)
        | x + l < y  = f l xs (y:ys)
        | x + l > y  = f l (x:xs) ys
        | otherwise  = (h!y - h!x * 31^l) : f l xs ys
    f _ _ _ = []

    f' l i j
        | i == u    = []
        | j == v    = []
        | x + l < y = f' l (i+1) j
        | x + l > y = f' l i (j+1)
        | otherwise = (h!y - h!x * 31^l) : f' l (i+1) (j+1)
        where x = xs'!i
              y = ys'!j

main = do
    ws <- BS.words `fmap` BS.getContents
    forM_ (splitEvery 3 ws) $
        print . solve

readNum = fst . fromJust . BS.readInteger
fI = fromIntegral
--- debug = flip trace
traceShow = trace . show
debug = flip traceShow
infixr 1 `debug2`
debug2 x msg = flip trace x (printf "%s: %s" msg $ show x)

infixr 1 ?
True ? x = const x
False ? _ = id

splitEvery _ [] = []
splitEvery n xs = ys : splitEvery n xs'
    where (ys, xs') = splitAt (fI n) xs

{-# OPTIONS_GHC -O2 -XNoMonomorphismRestriction #-}
{-# LANGUAGE BangPatterns #-}
{-(c) gorlum0 [at] gmail.com-}
import qualified Data.ByteString.Char8 as BS
import qualified Data.IntSet as S
import Data.List
import Data.Array
import Data.Char
import Control.Monad
import Debug.Trace (trace)
import Data.Maybe (fromJust)
import Text.Printf (printf)

solve [t, b, e] = sum $ map length ss
    where
    len = BS.length
    [n, m] = map len [b, e]
    xs = BS.findSubstrings b t
    ys = map (+m) $ BS.findSubstrings e t

    h = listArray (0,len t) $ scanl g 0 (BS.unpack t)
        -- Int qualification gave ~3x speed up on codeforces
        where g x c = x*31 + (fI $ ord c) :: Int

    -- subsequences
    --ss = [S.fromList $ f l xs ys | l <- [max n m .. len t]]
    ss = [group . sort $ f l xs ys | l <- [max n m .. len t]]

    f l (x:xs) (y:ys)
        | x + l < y  = f l xs (y:ys)
        | x + l > y  = f l (x:xs) ys
        | otherwise  = (h!y - h!x * 31^l) : f l xs ys
    f _ _ _ = []

    --ss = [S.fromList $ f' l 0 0 | l <- [max n m .. len t]]

    [u, v] = map length [xs, ys]
    xs' = listArray (0,u-1) xs
    ys' = listArray (0,v-1) ys

    f' l i j
        | i == u    = []
        | j == v    = []
        | x + l < y = f' l (i+1) j
        | x + l > y = f' l i (j+1)
        | otherwise = (h!y - h!x * 31^l) : f' l (i+1) (j+1)
        where x = xs'!i
              y = ys'!j

main = do
    ws <- BS.words `fmap` BS.getContents
    forM_ (splitEvery 3 ws) $
        print . solve

readNum = fst . fromJust . BS.readInteger
fI = fromIntegral
--- debug = flip trace
traceShow = trace . show
debug = flip traceShow
infixr 1 `debug2`
debug2 x msg = flip trace x (printf "%s: %s" msg $ show x)

infixr 1 ?
True ? x = const x
False ? _ = id

splitEvery _ [] = []
splitEvery n xs = ys : splitEvery n xs'
    where (ys, xs') = splitAt (fI n) xs

import Data.List
import Data.Function
import Data.Maybe
import Data.Ord
import qualified Data.Set as Set

data Parsing a = Parsing
                 (Maybe ((a -> Bool), (Parsing a))) -- success
               (Parsing a) -- fallback

stepParser ch (Parsing (Just (b, p)) _) | b ch = p
stepParser ch (Parsing _ fallback) = stepParser ch fallback

mkParsing :: Eq a => Parsing a  -- alternative parsing
             -> [a] -- primary parsing
             -> Parsing a
mkParsing prev [] = (Parsing Nothing prev)
mkParsing prev (ch:t) = Parsing (Just ((ch==), mkParsing (stepParser ch prev) t)) prev

parser str = p where p = mkParsing (Parsing (Just (const True, p)) undefined) str

parsingSucceeded (Parsing Nothing _) = True
parsingSucceeded _ = False -- really?
{-parsingSucceeded (Parsing _ Nothing) = False
parsingSucceeded (Parsing _ (Just fallback)) = parsingSucceeded fallback -}

consumeOne ((h,t), p) = (t, stepParser h p)

ensureHeaded :: ([a], Parsing a) -> [((a, [a]), Parsing a)]
ensureHeaded (h : t, p) = [((h, t), p)]
ensureHeaded _ = []

ccNext :: Ord a => [([a], Parsing a)] -> [(a, [([a], Parsing a)])]
ccNext strs = map (\l -> (fst(fst(head l)), map consumeOne l)) $ groupBy ((==) `on` (fst . fst)) . sortBy (comparing (fst . fst)) $ (strs >>= ensureHeaded)

ccStep :: Ord a => [([a], Parsing a)] -> (Bool, [(a, [([a], Parsing a)])])
ccStep strs = (any (parsingSucceeded . snd) strs, ccNext strs)

cc :: Ord a => Int -> [([a], Parsing a)] -> Int
cc skips strs = (if i && skips<=0 then 1 else 0) + sum (map (\(a,l) -> (cc (skips-1) l)) next) where
  (i, next) = ccStep strs

cnt prefix suffix str = cc (length prefix) (map (\s -> (s, ps)) $ (filter (prefix `isPrefixOf`) (tails str)))
 where
   ps = parser suffix

s[q,a,b]=cnt a b q
main = interact$qq
qq=show.s.words

----------------- QuickTest checks --------------

parserGood' :: [Bool] -> [Bool] -> Bool
parserGood' s1 s2 = parserGood s1 (s1 ++ s2)
                    && parserGood s2 (s1 ++ s2)
                    && parserGood s1 (s2 ++ s1)
                    && parserGood s2 (s2 ++ s1)

parserGood :: [Bool] -> [Bool] -> Bool
parserGood s1 s2 = if s1 `isSuffixOf` s2 then answer else not answer
                     where answer = parsingSucceeded $ foldl (flip stepParser) (parser s1) s2

solveSlow prefix suffix str = Set.fromList $ [s'|t <- tails str, s' <- inits t, prefix `isPrefixOf` s', suffix `isSuffixOf` s']

cntSlow prefix suffix str = Set.size $ solveSlow prefix suffix str

emptyParserGood s = parsingSucceeded (foldl (flip stepParser) (parser "") s)

cntGood' :: [Bool] -> [Bool] -> Bool
cntGood' x s = cntSlow x x s == cnt x x s

cntGood :: [Bool] -> [Bool] -> [Bool] -> Bool
cntGood pre suf s = cntSlow pre suf s == cnt pre suf s

{-# OPTIONS_GHC -O2 -XNoMonomorphismRestriction #-}
{-# LANGUAGE BangPatterns #-}
{-(c) gorlum0 [at] gmail.com-}
import qualified Data.ByteString.Char8 as BS
import qualified Data.IntSet as S
import Data.List
import Data.Array
import Data.Char
import Control.Monad
import Debug.Trace (trace)
import Data.Maybe (fromJust)
import Text.Printf (printf)

solve [t, b, e] = sum $ map S.size ss
    where
    len = BS.length
    [n, m] = map len [b, e]
    xs = BS.findSubstrings b t
    ys = map (+m) $ BS.findSubstrings e t
    [u, v] = map length [xs, ys]
    xs' = listArray (0,u-1) xs
    ys' = listArray (0,v-1) ys

    h = listArray (0,len t) $ scanl g 0 (BS.unpack t)
        where g x c = x*31 + (fI $ ord c)

    ss = [S.fromList $ f l xs ys | l <- [max n m .. len t]]

    f l (x:xs) (y:ys)
        | x + l < y  = f l xs (y:ys)
        | x + l > y  = f l (x:xs) ys
        | otherwise  = (h!y - h!x * 31^l) : f l xs ys
    f _ _ _ = []

    --ss = [S.fromList $ f' l 0 0 | l <- [max n m .. len t]]

    f' l i j
        | i == u    = []
        | j == v    = []
        | x + l < y = f' l (i+1) j
        | x + l > y = f' l i (j+1)
        | otherwise = (h!y - h!x * 31^l) : f' l (i+1) (j+1)
        where x = xs'!i
              y = ys'!j

main = do
    ws <- BS.words `fmap` BS.getContents
    forM_ (splitEvery 3 ws) $
        print . solve

readNum = fst . fromJust . BS.readInteger
fI = fromIntegral
--- debug = flip trace
traceShow = trace . show
debug = flip traceShow
infixr 1 `debug2`
debug2 x msg = flip trace x (printf "%s: %s" msg $ show x)

infixr 1 ?
True ? x = const x
False ? _ = id

splitEvery _ [] = []
splitEvery n xs = ys : splitEvery n xs'
    where (ys, xs') = splitAt (fI n) xs

{-# OPTIONS_GHC -O2 -XNoMonomorphismRestriction #-}
{-# LANGUAGE BangPatterns #-}
{-(c) gorlum0 [at] gmail.com-}
import qualified Data.ByteString.Char8 as BS
import qualified Data.IntSet as S
import Data.List
import Data.Array
import Control.Monad
import Debug.Trace (trace)
import Data.Maybe (fromJust)
import Text.Printf (printf)

solve [t, b, e] = S.size . S.fromList $ ss
    where
    x = BS.findSubstrings b t
    y = BS.findSubstrings e t

    ss = [j-i | i <- x, j <- y, j >= i]

main = do
    ws <- BS.words `fmap` BS.getContents
    forM_ (splitEvery 3 ws) $
        print . solve

readNum = fst . fromJust . BS.readInteger
fI = fromIntegral
--- debug = flip trace
traceShow = trace . show
debug = flip traceShow
infixr 1 `debug2`
debug2 x msg = flip trace x (printf "%s: %s" msg $ show x)

infixr 1 ?
True ? x = const x
False ? _ = id

splitEvery _ [] = []
splitEvery n xs = ys : splitEvery n xs'
    where (ys, xs') = splitAt (fI n) xs

import Data.List
import Data.Function
import Data.Maybe
import Data.Ord
import qualified Data.Set as Set

data Parsing = Parsing (Maybe (Char, Parsing)) -- next char
               (Maybe Parsing) -- fallback

parserGood' s1 s2 = parserGood s1 (s1 ++ s2)
                    && parserGood s2 (s1 ++ s2)
                    && parserGood s1 (s2 ++ s1)
                    && parserGood s2 (s2 ++ s1)

parserGood s1 s2 = if s1 `isSuffixOf` s2 then answer else not answer
                     where answer = parsingSucceeded $ foldl (flip stepParser) (parser s1) s2

stepParser ch (Parsing (Just (c, p)) _) | c==ch = p
stepParser ch (Parsing _ (Just fallback)) = stepParser ch fallback
stepParser _ p = p

mkParsing :: Maybe Parsing  -- alternative parsing
             -> String -- primary parsing
             -> Parsing
mkParsing prev "" = (Parsing Nothing prev)
mkParsing Nothing (ch:t) = p where
  p = Parsing (Just (ch, mkParsing (Just p) t)) Nothing
mkParsing (Just prev) (ch:t) = Parsing (Just (ch, mkParsing (Just $ stepParser ch prev) t)) (Just prev)

parser str = mkParsing Nothing str

parsingSucceeded (Parsing Nothing _) = True
parsingSucceeded (Parsing _ Nothing) = False
parsingSucceeded (Parsing _ (Just fallback)) = parsingSucceeded fallback

consumeOne ((h,t), p) = (t, stepParser h p)

ensureHeaded :: ([a], Parsing) -> [((a, [a]), Parsing)]
ensureHeaded (h : t, p) = [((h, t), p)]
ensureHeaded _ = []

ccNext strs = map (map consumeOne) $ groupBy ((==) `on` (fst . fst)) . sortBy (comparing (fst . fst)) $ (strs >>= ensureHeaded)

ccStep :: [(String, Parsing)] -> (Int, [[(String, Parsing)]])
ccStep strs = (if any (parsingSucceeded . snd) strs then 1 else 0, ccNext strs)
  where

cc :: [(String, Parsing)] -> Int
cc strs = i + sum (map cc next) where
  (i, next) = ccStep strs

solveSlow prefix suffix str = Set.fromList $ [s'|t <- tails str, s' <- inits t, prefix `isPrefixOf` s', suffix `isSuffixOf` s']

cntSlow prefix suffix str = Set.size $ solveSlow prefix suffix str

emptyParserGood s = parsingSucceeded (foldl (flip stepParser) (parser "") s)

cntGood pre suf s = cntSlow pre suf s == cnt pre suf s

cnt prefix suffix str = cc (map (\s -> (s, ps)) $ (filter (prefix `isPrefixOf`) (tails str)))
 where
   ps = parser suffix

s[q,a,b]=cnt a b q
main = interact$show.s.words

import Data.List
import Data.Function
import Data.Maybe
import Data.Ord
import qualified Data.Set as Set

data Parsing a = Parsing
                 (Maybe ((a -> Bool), (Parsing a))) -- success
               (Parsing a) -- fallback

stepParser ch (Parsing (Just (b, p)) _) | b ch = p
stepParser ch (Parsing _ fallback) = stepParser ch fallback

mkParsing :: Eq a => Parsing a  -- alternative parsing
             -> [a] -- primary parsing
             -> Parsing a
mkParsing prev [] = (Parsing Nothing prev)
mkParsing prev (ch:t) = Parsing (Just ((ch==), mkParsing (stepParser ch prev) t)) prev

parser str = p where p = mkParsing (Parsing (Just (const True, p)) undefined) str

parsingSucceeded (Parsing Nothing _) = True
parsingSucceeded _ = False -- really?
{-parsingSucceeded (Parsing _ Nothing) = False
parsingSucceeded (Parsing _ (Just fallback)) = parsingSucceeded fallback -}

consumeOne ((h,t), p) = (t, stepParser h p)

ensureHeaded :: ([a], Parsing a) -> [((a, [a]), Parsing a)]
ensureHeaded (h : t, p) = [((h, t), p)]
ensureHeaded _ = []

ccNext strs = map (map consumeOne) $ groupBy ((==) `on` (fst . fst)) . sortBy (comparing (fst . fst)) $ (strs >>= ensureHeaded)

ccStep :: Ord a => [([a], Parsing a)] -> (Bool, [[([a], Parsing a)]])
ccStep strs = (any (parsingSucceeded . snd) strs, ccNext strs)

cc :: Ord a => [([a], Parsing a)] -> Int
cc strs = fromEnum i + sum (map cc next) where
  (i, next) = ccStep strs

cnt prefix suffix str = cc (map (\s -> (s, ps)) $ (filter (prefix `isPrefixOf`) (tails str)))
 where
   ps = parser suffix

s[q,a,b]=cnt a b q
main = interact$show.s.words

----------------- QuickTest checks --------------

parserGood' s1 s2 = parserGood s1 (s1 ++ s2)
                    && parserGood s2 (s1 ++ s2)
                    && parserGood s1 (s2 ++ s1)
                    && parserGood s2 (s2 ++ s1)

parserGood s1 s2 = if s1 `isSuffixOf` s2 then answer else not answer
                     where answer = parsingSucceeded $ foldl (flip stepParser) (parser s1) s2

solveSlow prefix suffix str = Set.fromList $ [s'|t <- tails str, s' <- inits t, prefix `isPrefixOf` s', suffix `isSuffixOf` s']

cntSlow prefix suffix str = Set.size $ solveSlow prefix suffix str

emptyParserGood s = parsingSucceeded (foldl (flip stepParser) (parser "") s)

cntGood' :: [Bool] -> [Bool] -> Bool
cntGood' x s = cntSlow x x s == cnt x x s

cntGood pre suf s = cntSlow pre suf s == cnt pre suf s

import Data.List
import Data.Function
import Data.Maybe

-- aaParsing0 = (p1@Just ('a', (p2@Just('a', (Nothing, p2)), p1)), Nothing)

data Parsing = Parsing (Maybe (Char, Parsing)) -- next char
               (Maybe Parsing) -- fallback

stepParser ch (Parsing (Just (c, p)) _) | c==ch = p
stepParser ch (Parsing _ (Just fallback)) = stepParser ch fallback
stepParser _ p = p

mkParsing :: Maybe Parsing  -- alternative parsing
             -> String -- primary parsing
             -> Parsing
mkParsing prev "" = (Parsing Nothing prev)
mkParsing Nothing (ch:t) = p where
  p = Parsing (Just (ch, mkParsing (Just p) t)) Nothing
mkParsing (Just prev) (ch:t) = Parsing (Just (ch, mkParsing (Just $ stepParser ch prev) t)) (Just prev)

parser str = mkParsing Nothing str

parsingSucceeded (Parsing Nothing _) = True
parsingSucceeded (Parsing _ Nothing) = False
parsingSucceeded (Parsing _ (Just fallback)) = parsingSucceeded fallback

cc :: [(String, Parsing)] -> Int
cc strs = (if any (parsingSucceeded . snd) strs then 1 else 0) + sum (map cc next)
  where
    (nulls, nonNulls) = partition (null.fst) strs
    consumeOne ((h:t), p) = (t, stepParser h p)
    next = map (map consumeOne) $ groupBy ((==) `on` (head . fst)) nonNulls

cnt prefix suffix str = cc (map (\s -> (s, ps)) $ (filter (prefix `isPrefixOf`) (tails str)))
 where
   ps = parser suffix

s[q,a,b]=cnt a b q
main = interact$show.s.words


main :: IO ()
main = do
  [n,a,b,c,t] <- fmap (fmap read . words) getLine
  l <- fmap (map read . words) getLine
  let ans = sum(map (\x -> max a $ a - (t - x) * (b - c)) l)
  print ans

main = interact $ show . (\(_:a:b:c:t:xs) -> sum $ map (\x -> max a $ a - (t - x) * (b - c)) xs) . map read . words


{-# LANGUAGE BangPatterns #-}
module Main where

import Control.Monad
import Control.Monad.ST.Safe
import Control.Monad.Trans.State
import Data.Int

import Data.Array.Unboxed ((!))

import qualified Data.ByteString.Lazy.Char8 as BS
import qualified Data.Array as A
import qualified Data.Array.ST.Safe as STA
import qualified Data.Array.Unboxed as AU
import qualified Data.List as L

readInt :: Num a => BS.ByteString -> a
readInt bs = case BS.readInt bs of
  Just (i, _) -> fromIntegral i
  Nothing -> error $ "Not an integer: " ++ show bs

readLines :: IO [BS.ByteString]
readLines = BS.lines `fmap` BS.getContents

type LineReader a = State [BS.ByteString] a

currentLine :: LineReader BS.ByteString
currentLine = do
  ls <- get
  let (x, xs) = case ls of
        [] -> error "No remain lines."
        l -> (head l, tail l)
  put xs
  return x

restLines :: LineReader [BS.ByteString]
restLines = do
  xs <- get
  put []
  return xs

readDim :: BS.ByteString -> (Int32, Int32)
readDim line =
  let [m, n] = map readInt $ BS.words line in (m, n)

readHeights :: [BS.ByteString] -> [[Int32]]
readHeights = map (map readInt . BS.words)

type XY = (Int32, Int32)
type HM = AU.UArray XY Int32

data Pair a b = P !a !b

data Pos = PS {
  lt :: !Int32,
  ge :: !Int32
}

toArray :: Int32 -> Int32 -> [[Int32]] -> HM
toArray m n hs = AU.listArray ((1, 1), (m, n)) $ mconcat hs

g :: HM -> [XY] -> [Pair XY Pos]
g arr xys = e $ mconcat $ zipWith f [0..] gs
  where
    gs = L.groupBy (\x y -> arr ! x == arr ! y) $ L.sortOn (arr!) xys
    numV = fromIntegral $ length gs
    f i = map (flip P p)
      where
        p = PS{lt = i, ge = numV - i}

    m !x y = y
    e [] = []
    e (x:xs) = m (m x (e xs)) (x:xs)

solve :: HM -> A.Array XY Int32
solve hs = STA.runSTArray $ do
  answer <- STA.newArray ((1, 1), (n ,m)) (PS 0 0)
  let ua (P x y) = updateAnswer' answer x y
  getNormalPos ua
  getTransPos ua
  STA.mapArray (\(PS x y) -> x + y) answer
  where
    (_, (n, m)) = AU.bounds hs
    getPos mkXy runDim fixedDim = g hs $ map (mkXy fixedDim) runDim

    getNormalPos ua = forM_ [1..n] $ mapM_ ua . getPos (,) [1..m]
    getTransPos ua = forM_ [1..m] $ mapM_ ua . getPos (flip (,)) [1..n]

    updateAnswer PS{lt = lt1, ge = ge1} PS{lt = lt2, ge = ge2} =
      PS{lt = max lt1 lt2, ge = max ge1 ge2}

    updateAnswer' :: STA.STArray s XY Pos -> XY -> Pos -> ST s ()
    updateAnswer' ans xy new = do
      old <- STA.readArray ans xy
      STA.writeArray ans xy (updateAnswer old new)

main :: IO ()
main = do
  ls <- readLines
  let (answer, _) = flip runState ls $ do
      (n, m) <- readDim <$> currentLine
      hs <- toArray n m . readHeights <$> restLines
      return $ solve hs
  let (_, (n ,m)) = A.bounds answer
  let out = unlines $ flip map [1..n] $ \i -> unwords $
        flip map [1..m] $ \j -> show . (answer!) $ (i, j)
  putStrLn out

{-# OPTIONS_GHC -O2 -optc-Ofast -fignore-asserts #-}
{-# LANGUAGE ViewPatterns #-}
{-# LANGUAGE DeriveGeneric #-}
{-# LANGUAGE FlexibleContexts #-}
{-# LANGUAGE ScopedTypeVariables #-}

module Main where

--import Debug.Trace

import System.IO
import GHC.Generics
import Control.Monad
import Control.Monad.ST
import Control.DeepSeq
import Data.Function
import Data.Maybe
import Data.Either
import Data.Ord
import Data.Ratio
import qualified Data.Foldable as Foldable
import Data.Char
import qualified Data.ByteString as BS
import qualified Data.ByteString.Char8 as BS8
import Data.List
import Data.Array.IArray
import Data.Array.MArray.Safe
import qualified Data.Array.Unboxed as UA
import qualified Data.Array.ST.Safe as SA
import qualified Data.Array.IO.Safe as IA
import Data.Map.Strict (Map)
import qualified Data.Map.Strict as Map
import Data.IntMap.Strict (IntMap)
import qualified Data.IntMap.Strict as IntMap
import Data.Set (Set)
import qualified Data.Set as Set
import Data.IntSet (IntSet)
import qualified Data.IntSet as IntSet

getWords  = words <$> getLine :: IO [String]
getInts = (map (fst . fromJust . BS8.readInt) . BS8.words) <$> BS.getLine :: IO [Int]
getDoubles = (map (read . BS8.unpack) . BS8.words) <$> BS.getLine :: IO [Double]
getInt    = read <$> getLine :: IO Int
getDouble  = read <$> getLine :: IO Double
printLines :: Show a => [a] -> IO ()
printLines = mapM_ print
printStrs = mapM_ putStrLn :: [String] -> IO ()
printList = putStrLn . intercalate " " . map show :: [Int] -> IO ()

---- Answer Code Section ----

type Int2D = Array Int (Array Int Int)

minifyLine line = map (\h -> Set.findIndex h set + 1) line where
    set = foldl (flip Set.insert) Set.empty line

process :: [[Int]] -> Int -> Int -> [[Int]]
process area n m = [ [ solve i j | j <- [1..m] ] | i <- [1..n] ] where
    iLines = map minifyLine area
    jLines = map minifyLine (transpose area)
    iLines' = force $ listArray (1, n) $ map (listArray (1, m)) iLines :: Int2D
    jLines' = force $ listArray (1, m) $ map (listArray (1, n))jLines :: Int2D
    iMaxs = force $ listArray (1, n) $ map maximum iLines :: Array Int Int
    jMaxs = force $ listArray (1, m) $ map maximum jLines :: Array Int Int
    solve i j = max maxI maxJ where
        iOffset = max (jLines' ! j ! i - iLines' ! i ! j) 0
        jOffset = max (iLines' ! i ! j - jLines' ! j ! i) 0
        maxI = iMaxs ! i + iOffset
        maxJ = jMaxs ! j + jOffset

main = do
    n:m:[] <- getInts
    area <- replicateM n getInts
    printArea $ process area n m

printArea = printStrs . map (intercalate " " . map show) :: [[Int]] -> IO ()


import Control.Monad
import Data.Bool

answer :: Integer -> Bool
answer n =
  let divnum = div n 2020 in
  (2020 * divnum) <= n && n <= (2021 * divnum)

main = do
  n <- read <$> getLine
  replicateM_ n $ do
    i <- read <$> getLine
    putStrLn $ bool "NO" "YES" $ answer i

-- Trying to use only ByteString I/O with a state monad this contest

import Control.Monad
import Control.Monad.Trans.State.Lazy
import qualified Data.ByteString.Lazy.Char8 as P

getSLine :: Monad m => StateT P.ByteString m P.ByteString
getSLine = do
  (out, next) <- P.break (== '\n') <$> get
  put $ P.tail next
  pure out

readInts :: Monad m => StateT P.ByteString m [Int]
readInts = do
  currLine <- getSLine
  pure [x | Just (x, _) <- P.readInt <$> P.words currLine]

-- There has to be a combinator for this. But where?
outLine :: P.ByteString -> StateT P.ByteString IO ()
outLine v = StateT $ \s -> ((), s) <$ P.putStrLn v

main :: IO ()
main = (P.getContents >>=) $ evalStateT $ do
  [t] <- readInts
  replicateM_ t $ do
    [n] <- readInts
    let  w = mod (0-n) 2021
    outLine . P.pack $ if  n >= w * 2020
      then  "YES"
      else  "NO"

import qualified Data.List as L
import qualified Data.Map as M
import qualified Data.Set as S

import qualified Data.Array as A

import qualified Control.Monad.State.Strict as State
import Control.Monad.ST

import Data.Bits(xor, (.&.), (.|.))

import Data.Array((!))
import Control.Monad(replicateM)
import Data.Maybe

solve n = mod2020 <= div2020
	where
		mod2020 = mod n 2020
		div2020 = div n 2020

plotResult True = putStrLn "YES"
plotResult False = putStrLn "NO"

main = do
	t <- getLine >>= return . read :: IO Integer
	replicateM (fromInteger t) $ do
		[n] <- getLine >>= return . (fmap read) . words :: IO [Integer]
		plotResult $ solve n

module Main where

import Control.Monad
import Data.List
import qualified Data.Set as S

getStrList :: IO [String]
getStrList = words <$> getLine

getIntList :: IO [Int]
getIntList = map read <$> getStrList

printList :: (Show a) => [a] -> IO ()
printList = putStrLn . list2Str

list2Str :: (Show a) => [a] -> String
list2Str = concat . intersperse " " . fmap show

yesOrNo :: Bool -> String
yesOrNo True = "YES"
yesOrNo False = "NO"

tCase :: IO () -> IO ()
tCase x = do
    t <- readLn
    replicateM_ t $ x

main :: IO ()
main = tCase process

--------------------------------------------------------------------------------

process :: IO ()
process = do
    x <- readLn :: IO Int
    let d = x `div` 2020
        r = x `mod` 2020
    putStrLn . yesOrNo . (d>=) $ r

main = interact $ unlines . map (solve . read) . tail . lines

solve n
    | n - x * 2020 <= x = "YES"
	| otherwise = "NO"
  where x = n `div` 2020

{- This code was written by
Russell Emerine - linguist,
mathematician, coder,
musician, and metalhead. -}
import Control.Monad
import Data.Bool

main :: IO ()
main = getLine >>= flip replicateM_ test . read

test :: IO ()
test = do
  n <- read <$> getLine :: IO Integer
  putStrLn $ bool "YES" "NO" $ n `mod` 2020 > n `div` 2020

good :: Int -> Bool
good n
    | n < 0     = False
    | otherwise = n `mod` 2020 == 0 || good (n - 2021)

process :: [String] -> String
process (_ : inp) = unlines $ map solve inp
    where solve s = if good (read s :: Int) then "YES" else "NO"

main :: IO ()
main = interact (process . lines)