{-# LANGUAGE BangPatterns #-}
import Control.Arrow
import Control.Monad.Fix
import Data.Foldable
import qualified Data.Vector.Unboxed as VU
import qualified Data.Vector.Unboxed.Mutable as VUM
import qualified Data.ByteString.Char8 as B
import Data.ByteString.Internal (accursedUnutterablePerformIO)
import qualified Data.Set as S
import System.IO.Unsafe
import Debug.Trace

unew :: VU.Unbox a => Int -> VUM.IOVector a
unew !n = accursedUnutterablePerformIO $ VUM.unsafeNew n

uread :: VU.Unbox a => Int -> VUM.IOVector a -> a
uread !i !v = accursedUnutterablePerformIO $ VUM.unsafeRead v i

uwrite :: VU.Unbox a => Int -> a -> VUM.IOVector a -> VUM.IOVector a
uwrite !i !a !v =
  accursedUnutterablePerformIO $ VUM.unsafeWrite v i a >> return v

umodify :: VU.Unbox a => Int -> (a -> a) -> VUM.IOVector a -> VUM.IOVector a
umodify !i !f !v =
  accursedUnutterablePerformIO $ VUM.unsafeModify v f i >> return v

uthaw :: VU.Unbox a => VU.Vector a -> VUM.IOVector a
uthaw !v = accursedUnutterablePerformIO $ VU.unsafeThaw v

ufreeze :: VU.Unbox a => VUM.IOVector a -> VU.Vector a
ufreeze !v = accursedUnutterablePerformIO $ VU.unsafeFreeze v

uset :: VU.Unbox a => a -> VUM.IOVector a -> VUM.IOVector a
uset !a !v = accursedUnutterablePerformIO $ VUM.set v a >> return v

--solve :: Int -> Int -> VU.Vector (Int, Int) -> Int
solve !n !w !wvs = foldl'
  ( \(!acc) (!i) ->
    if 0 <= uread (toIndex n i) dp && uread (toIndex n i) dp <= w
      then i
      else acc
  )
  0
  [0 .. sumOfValue]
 where
  sumOfValue = VU.sum $ VU.map (\(_, v) -> v) wvs

  toIndex i k = i * (sumOfValue + 1) + k

  max' x y | x > w     = y
           | y > w     = x
           | otherwise = max x y

  dp = VU.ifoldl'
    ( \(!dp) !i (!wi, !vi) -> foldl'
      ( \(!dp) !v ->
        let z = max'
              (uread (toIndex i v) dp)
              ( if v - vi < 0
                then minBound
                else uread (toIndex i (v - vi)) dp + wi
              )
        in  uwrite (toIndex (i + 1) v) z dp
      )
      dp
      [0 .. sumOfValue]
    )
    (uwrite (toIndex 0 0) 0 $ uset minBound $ unew $ succ n * succ sumOfValue)
    wvs

main = do
  let readInt = fmap (second B.tail) . B.readInt

  (n, w) <-
    (\vec -> (vec VU.! 0, vec VU.! 1)) . VU.unfoldrN 2 readInt <$> B.getLine
  wvs <-
    VU.replicateM n
    $   (\vec -> (vec VU.! 0, vec VU.! 1))
    .   VU.unfoldrN 2 readInt
    <$> B.getLine
  print $ solve n w wvs
