import Control.Applicative
import Control.Monad
import Data.Array

main = do
	[n,capacity] <- map read.words <$> getLine
	wvs <- replicateM n (toTuple.map read.words <$> getLine) :: IO [(Int,Int)]
	putStrLn.show.maximum.map snd $ foldl (knapsack capacity) [] wvs

toTuple [a,b] = (a,b)

-- N,capacity
-- weight, value
knapsack :: Int -> [(Int,Int)] -> (Int,Int) -> [(Int,Int)]
knapsack capacity memo wv = wv:concat (map (f wv) memo)
	where
		f (w,v) (ow,ov) = if ow+w <= capacity then [(ow+w,ov+v),(ow,ov)] else [(ow,ov)]