#include <bits/stdc++.h>
#define int long long int
#define endl '\n'
#define pb push_back
#define mod 1000000007
#define db(i) cout<<i<<" ";
#define db1(i) cout<<"("<<i<<")";
#define db2(i) cout<<"["<<i<<"]";
#define db3(i) cout<<"{"<<i<<"}";
#define ff first 
#define ss second
#define vv vector
#define pp pair
#define pi acos(-1);
#define printarr(a,n) cout<<"[";for(int i=0;i<n;i++){db1(a[i]);}cout<<"]";
#define inf LLONG_MAX
#define ninf LLONG_MIN
#define MAXN 100001 


using namespace std;


//..................................................................................................//

vector<int> prime;
int fprime=0;

void seiveprime(int n) 
{fprime=123; bool pr[n+1];memset(pr, true, sizeof(pr)); 
    for (int p=2; p*p<=n; p++){ 
        if (pr[p] == true) {
            for (int i=p*p; i<=n; i += p) 
                pr[i] = false; 
        } 
    } 
    for (int p=2; p<=n; p++) 
       if (pr[p]) 
          prime.pb(p); 
} 

//...................................................................................................//

vector<pp<int,int>> primefactors(int n)  
{  
    vector<pp<int,int>> v;
    int co=0;
    while (n % 2 == 0)  
    {  
        co++;
        n = n/2;  
    }  
    if(co>0)
    v.pb({2,co});
    for (int i = 3; i <= sqrt(n); i = i + 2)  
    {  
        co=0;
        while (n % i == 0)  
        {
            co++;
            n = n/i;  
        }  
        if(co>0)
        {
            v.pb({i,co});
        }
    }
    if (n > 2)  
        v.pb({n,1});  
   return v;
}

//.................................................................................................................//
  
  
  
// int spf[MAXN]; 

// void seive() 
// { 
//     spf[1] = 1; 
//     for (int i=2; i<MAXN; i++) 
//         spf[i] = i; 
//     for (int i=4; i<MAXN; i+=2) 
//         spf[i] = 2; 
  
//     for (int i=3; i*i<MAXN; i++) 
//     { 
//         if (spf[i] == i) 
//         {
//             for (int j=i*i; j<MAXN; j+=i) 
//                 if (spf[j]==j) 
//                     spf[j] = i; 
//         } 
//     } 
// } 

// //call seive
// vector<pp<int,int>> seiveprimefactors(int x) 
// { 
//     int i=0;
//     vector<pp<int,int>> ret; 
//     while (x != 1) 
//     { 
//         if(i==0)
//         {
//             ret.push_back({spf[x],1});
//             i++;
//         }
//         else
//         {
//             int si=ret.size()-1;
//             if(spf[x]==ret[si].ff)
//             {
//                   ret[si].ss++;
//             }
//             else
//             {
//                 ret.pb({spf[x],1});
//             }
//         }
//         x = x / spf[x]; 
//     } 
    
    
//     return ret; 
    
// } 


//......................................................................................//


bool isprime(int n)
{
    for(int i=2;i<=sqrt(n);i++)
        if(n%i==0)
        return false;
    return true;
}

//........................................................................................//

int maxarr(int *a,int n)
{
    int val=a[0];
    for(int i=1;i<n;i++)
    {
        if(val<a[i])
        {
            val=a[i];
        }
    }
    return val;
}

//..........................................................................................//

int minarr(int *a,int n)
{
    int val=a[0];
    for(int i=1;i<n;i++)
    {
        if(val>a[i])
        {
            val=a[i];
        }
    }
    return val;
}

//..........................................................................................//


int gcd(int a, int b) 
{ 
    if (b == 0) 
        return a; 
    return gcd(b, a % b);  
} 

//............................................................................................//

int power(int x, int y, unsigned int p=ULLONG_MAX)  
{  
    int res = 1;     
    x = x % p; 
    if (x == 0) 
      return 0; 
    while (y > 0)  
    {    
        if (y & 1)  
           res = (res*x) % p;  
        y = y>>1; 
        x = (x*x) % p;  
    }  
    return res;  
}

//................................................................................................//
bool cmp(const pair<int,int> &a,const pair<int,int> &b)
{
    if(a.ss<b.ss)
        return true;
    else if(a.ss>b.ss)
        return false;
    else
    {
        if(a.ff<b.ff)
            return true;
        else
            return false;
    }
    
}
bool cmp1(const pair<int,int> &a,const pair<int,int> &b)
{
    return (a.ss<b.ss);
}


//..................................................................................................//

//if no test cases add coments for reading




signed main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    int t=1;
    //cin>>t;
    while(t--)
    {
        int n,w;
        cin>>n>>w;
        int a[w+1][n+1];
        memset(a,0,sizeof(a));
        int b[n+1][2];
        for(int i=1;i<=n;i++)
        {
            cin>>b[i][0]>>b[i][1];
        }
        for(int i=1;i<=w;i++)
        {
            for(int j=1;j<=n;j++)
            {
               int ind=i-b[j][0];
              // db1(ind);
                if(ind<0)
                ind=0;
              
                int val=0;
                if(b[j][0]<=i)
                val=b[j][1];
                
                //   db1(val);
                //   db3(a[ind][j-1]);
                //   db2(a[i][j-1]);
                //  cout<<endl;
                a[i][j]=max(val+a[ind][j-1],a[i][j-1]);
            }
        }
       
        cout<<a[w][n];
        
        
        
        
        
    }
   
}


Measured memory_bytes: 82424