using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ABC88D
{
    class Program
    {
        static void Main(string[] args)
        {
            EDPC.D_Knapsack1();
        }

        class EDPC
        {
            public static void B_Frog2()
            {
                var NK = ReadIntN();
                int N = NK[0];
                int K = NK[1];
                var Hs = ReadIntN();
                int inf = 100000;

                var dp = new long[N];

                for (int i = 1; i < dp.Length; i++)
                {
                    dp[i] = (long)Math.Pow(10,10);
                }

                for (int i = 0; i < N-1; i++)
                {
                    for (int j = i+1; j <= Math.Min(i+K,N-1); j++)
                    {
                        dp[j] = Math.Min(dp[j],dp[i]+Math.Abs(Hs[j] - Hs[i]));
                    }
                }

                Console.WriteLine(dp[N-1]);
                Console.ReadLine();
            }

            public static void C_Vacation()
            {
                #region Read
                int N = ReadInt();
                var happinesses = new int[N][];
                for (int i = 0; i < N; i++)
                {
                    happinesses[i] = ReadIntN();
                }
                #endregion

                var dp = new int[N][];
                dp[0] = happinesses[0];

                for (int i = 1; i < N; i++)
                {
                    dp[i] = new int[3];

                    dp[i][0] = Math.Max(dp[i - 1][1], dp[i - 1][2]) + happinesses[i][0];
                    dp[i][1] = Math.Max(dp[i - 1][2], dp[i - 1][0]) + happinesses[i][1];
                    dp[i][2] = Math.Max(dp[i - 1][0], dp[i - 1][1]) + happinesses[i][2];
                }

                Console.WriteLine(Math.Max(Math.Max(dp[N - 1][0], dp[N - 1][1]), dp[N - 1][2]));
                Console.ReadLine();
            }

            public static void D_Knapsack1()
            {
                var NW = ReadIntN();
                int N = NW[0];
                int W = NW[1];

                var itemArray = ReadTupleInt(N);
                var dp = new long[N+1,W+1];

                long maxValue = 0;
                for (int i = 1; i <= N; i++)
                {
                    //0番からi-1番の商品について

                    for (int w = 0; w <= W; w++)
                    {
                        //w以下になるように選ぶ
       
                        if (w - itemArray[i - 1].Item1 >= 0)
                        {
                            dp[i, w] = Math.Max(dp[i - 1, w], dp[i - 1, w - itemArray[i - 1].Item1] + itemArray[i - 1].Item2);
                        }
                        else dp[i, w] = dp[i - 1, w];
                        maxValue = Math.Max(maxValue, dp[i, w]);
                    }
                }
                Console.WriteLine(maxValue);
                Console.ReadLine();
            }
        }

        class ABC015
        {
            public static void C()
            {
                var nk = ReadIntN();
                var N = nk[0];
                var K = nk[1];
                var T = ReadLongMatrix(N, K);
                Console.WriteLine(DFS(0, 0, N, K, T) ? "Found" : "Nothing");
            }
            static bool DFS(long n, long v, long N, long K, long[,] T)
            {
                if (n == N) { return v == 0; }
                for (int k = 0; k < K; ++k)
                {
                    if (DFS(n + 1, v ^ T[n, k], N, K, T)) { return true; }
                }
                return false;
            }
            public static void D()
            {
                var W = ReadInt();
                var nk = ReadIntN();
                var N = nk[0];
                var K = nk[1];
                var AB = ReadTupleInt(N);
                var inf = 60000;
                var maxb = 5100;
                var dp = Util.Gen(maxb, K + 1, inf);
                for (int k = 0; k <= K; ++k) { dp[0, k] = 0; }
                for (int n = 0; n < N; ++n)
                {
                    //写真を一つ取り出す
                    var ab = AB[n];

                    //重要度ループ
                    for (int b = maxb - 1; b >= 0; --b)
                    {

                        //枚数ループ
                        for (int k = K - 1; k >= 0; --k)
                        {
                            //写真重要度がbよりも小さいとき
                            if (ab.Item2 <= b)
                            {
                                dp[b, k + 1] = Math.Min(dp[b, k + 1], dp[b - ab.Item2, k] + ab.Item1);
                                
                            }
                        }
                    }
                
                }
                var max = 0;
                for (int b = 0; b < maxb; ++b)
                {
                    for (int k = 1; k <= K; ++k)
                    {
                        if (dp[b, k] <= W)
                        {
                            max = Math.Max(max, b);
                        }
                    }
                }
                Console.WriteLine(max);
                Console.ReadLine();
            }
        }

        class Util
        {
            /// <summary>
            /// r行、c列の配列を作り、vで初期化する
            /// </summary>
            /// <typeparam name="T"></typeparam>
            /// <param name="r"></param>
            /// <param name="c"></param>
            /// <param name="v"></param>
            /// <returns></returns>
            public static T[,] Gen<T>(int r, int c, T v)
            {
                var matrix = new T[r, c];
                for (int i = 0; i < r; ++i)
                {
                    for (int j = 0; j < c; ++j)
                    {
                        matrix[i, j] = v;
                    }
                }
                return matrix;
            }
        }

        #region Reader
        static string ReadStr()
        {
            return Console.ReadLine();
        }
        static string[] ReadStrN()
        {
            return Console.ReadLine().Split(' ');
        }
        static int ReadInt()
        {
            return Convert.ToInt32(Console.ReadLine());
        }
        static int[] ReadIntN()
        {
            return Console.ReadLine().Split(' ').Select(s => Convert.ToInt32(s)).ToArray();
        }
        static long ReadLong()
        {
            return Convert.ToInt64(Console.ReadLine());
        }
        static long[] ReadLongN()
        {
            return Console.ReadLine().Split(' ').Select(s => Convert.ToInt64(s)).ToArray();
        }
        static long[,] ReadLongMatrix(int r, int c)
        {
            var mat = new long[r, c];
            for (int i = 0; i < r; ++i)
            {
                var x = ReadLongN();
                for (int j = 0; j < c; ++j)
                {
                    mat[i, j] = x[j];
                }
            }
            return mat;
        }
        static Tuple<string, string>[] ReadTupleStr(int n)
        {
            List<Tuple<string, string>> list = new List<Tuple<string, string>>();
            for (int i = 0; i < n; ++i)
            {
                var ab = ReadStrN();
                list.Add(new Tuple<string, string>(ab[0], ab[1]));
            }
            return list.ToArray();
        }
        static Tuple<long, long>[] ReadTupleLong(int n)
        {
            List<Tuple<long, long>> list = new List<Tuple<long, long>>();
            for (int i = 0; i < n; ++i)
            {
                var ab = ReadLongN();
                list.Add(new Tuple<long, long>(ab[0], ab[1]));
            }
            return list.ToArray();
        }
        static Tuple<int, int>[] ReadTupleInt(int n)
        {
            List<Tuple<int, int>> list = new List<Tuple<int, int>>();
            for (int i = 0; i < n; ++i)
            {
                var ab = ReadIntN();
                list.Add(new Tuple<int, int>(ab[0], ab[1]));
            }
            return list.ToArray();
        }
        static Tuple<double, double>[] ReadTupleDouble(int n)
        {
            List<Tuple<double, double>> list = new List<Tuple<double, double>>();
            for (int i = 0; i < n; ++i)
            {
                var ab = ReadLongN();
                list.Add(new Tuple<double, double>(ab[0], ab[1]));
            }
            return list.ToArray();
        }
        static Dictionary<int, HashSet<int>> ReadAdjacencyList(int N, int M)
        {
            Dictionary<int, HashSet<int>> dict = new Dictionary<int, HashSet<int>>();
            for (int i = 0; i <= N; ++i)
            {
                dict.Add(i, new HashSet<int>());
            }
            for (int i = 0; i < M; ++i)
            {
                var ab = ReadIntN();
                dict[ab[0]].Add(ab[1]);
                dict[ab[1]].Add(ab[0]);
            }
            return dict;
        }
        #endregion
    }
}


Measured memory_bytes: 89056