#include<bits/stdc++.h>
using namespace std;


/*###   FAST-IO  ###*/


#define IOS ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);


/*###   DEBUGGGGGGG   ###*/


#define trace1(x)                cerr<<#x<<": "<<x<<endl
#define trace2(x, y)             cerr<<#x<<": "<<x<<" | "<<#y<<": "<<y<<endl
#define trace3(x, y, z)          cerr<<#x<<":" <<x<<" | "<<#y<<": "<<y<<" | "<<#z<<": "<<z<<endl
#define trace4(a, b, c, d)       cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<endl
#define trace5(a, b, c, d, e)    cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<endl
#define trace6(a, b, c, d, e, f) cerr<<#a<<": "<<a<<" | "<<#b<<": "<<b<<" | "<<#c<<": "<<c<<" | "<<#d<<": "<<d<<" | "<<#e<< ": "<<e<<" | "<<#f<<": "<<f<<endl
#define testcases int testcases;cin>>testcases; while(testcases--)
#define queries int queries;cin>>queries; while(queries--)

/*###   TO PRINT   ###*/

#define pp1(a) cout << a << endl;
#define pp2(a, b) cout << a << " " << b << endl;
#define pp3(a, b, c) cout << a << " " << b << " " << c << endl;
#define pp4(a, b, c, d) cout << a << " " << b << " " << c << " " << d << endl;
#define pp5(a, b, c, d, e) cout << a << " " << b << " " << c << " " << d << " " << e << endl;

/*###   SSSSSSS   ###*/

#define INF INT_MAX

#define endl "\n"
#define ll long long
#define int long long

ll mod = 1e9+7;

#define pb push_back
#define mp make_pair

#define pii pair<int,int>
#define msi map<string,int>
#define vi vector<int>
#define vpii vector<pair<int,int>>


#define ff first
#define ss second
#define sz size()

#define REP(i,a,b) for(int i=a;i<=b;i++)
#define REP1(i,a,b) for(int i=a;i<b;i++)
#define f0(n) for(ll i=0;i<n;i++)
#define f(n) for(ll i=1;i<=n;i++)
#define fn(a,n) for(ll a=0; a<n; a++)
#define flr(a,l,r) for(ll a=l; a<=r;a++)

#define sorta(a) sort(a.begin(), a.end());
#define sortd(a) sort(a.begin(), a.end(), greater<ll>());
#define sortdp(a) sort(a.begin(), a.end(), greater<pair<ll, ll>>());

#define blb(a, b) lower_bound(all(a), b) - a.begin();
#define bub(a, b) upper_bound(all(a), b) - a.begin();


#define stop return 0


/*###   COMPARATOR   ###*/


bool rev(int x,int y)
{
    return x>y;
}


/*###   PAIR_SORT_IN_DESCENDING_ORDER  ###*/


bool sortinrev(const pair<int,int> &a,  
               const pair<int,int> &b) 
{ 
       return (a.first > b.first); 
}


/*###   MODULO   ###*/


int modulo(int x,int N){
    return (x % N + N) %N;
}


/*###   MAX & MIN   ###*/


int max(int a,int b)
{
    if(a>=b)
        return a;
    else     
        return b;
}

int min(int a,int b)
{
    if(a<=b)
        return a;
    else     
        return b;
}


/*###   MOD-DIFFERENCE   ###*/


ll diff(ll a,ll b)
{
    if(a>=b)
        return a-b;
    else
        return b-a;
}


/*###   PAIR-SORTING   ###*/


void pairsort(int a[], int b[], ll n)
{
    pair<int, int> pairt[n];
    for (int i = 0; i < n; i++) 
    {
        pairt[i].first = a[i];
        pairt[i].second = b[i];
    }

    sort(pairt, pairt + n);

    for (int i = 0; i < n; i++) 
    {
        a[i] = pairt[i].first;
        b[i] = pairt[i].second;
    }
}


/*###   GCD && LCM   ###*/


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

ll lcm (ll a, ll b) {
    return a / gcd(a, b) * b;
}


/*###   PRIME OR NOT   ###*/


int isPrime(int n)
{
    if(n < 2)
        return 0;
    if(n < 4)
        return 1;
    if(n % 2 == 0 or n % 3 == 0)
        return 0;
    for(int i = 5; i*i <= n; i += 6)
        if(n % i == 0 or n % (i+2) == 0)
            return 0;
    return 1;
}


/*###   nCr   ###*/


long long C(int n, int r) {
    if(r > n - r) r = n - r;
    long long ans = 1;
    int i;
    for(i = 1; i <= r; i++) {
        ans *= n - r + i;
        ans /= i;
    }

    return ans;
}


/*###   MODULAR-EXPONENTIATION   ###*/


ll modexpo(ll x,ll p)
{
    ll res = 1;
    x = x%mod;
    while(p)
    {
        if(p%2)
            res = res * x;
        p >>= 1;
        x = x*x % mod;
        res %= mod;
    }
    return res;
}

uint64_t mul_mod(uint64_t a, uint64_t b, uint64_t m)
{
  long double x;
  uint64_t c;
  int64_t r;
  if (a >= m) a %= m;
  if (b >= m) b %= m;
  x = a;
  c = x * b / m;
  r = (int64_t)(a * b - c * m) % (int64_t)m;
  return r < 0 ? r + m : r;
}



/*###   STRING TO INT   ###*/

int sti(string s) {
 
    int ans = 0;
    int p = 1;
 
    for (int i = s.size() - 1; i >= 0; i--) {
        ans = (ans + ((ll)(s[i] - '0') * p) % mod) % mod;
        p = (p * 10) % mod;
    }
    return ans;
 
}

/*###   TIMER   ###*/


void time() {
    #ifndef ONLINE_JUDGE
    cout << "\nTime: " << 1.0 * clock() / CLOCKS_PER_SEC << "s\n";
    #endif
}

                                    /*************************** END OF TEMPLATE ****************************/


const int N=110000;

// int w[110],v[110];
// int dp[N];
//int dp[N][N];


void maxself(int& a,int b){
	a=max(a,b);
}


int32_t main()
{
  	IOS
    int n,W;
    cin>>n>>W;

    vi dp(W+1);
    //dp[i]-the max total value of items  with total weight exatly i

    for(int i=0; i<n ; ++i){
    	int weight,value;
    	cin>>weight>>value;
    	for(int j=W-weight;j>=0;--j){
    	//for(int j=0; j<=W-weight ; j++){
    		maxself( dp[j+weight] , dp[j]+value );
    	}
    }

    int ans=0;
    flr(i,0,W){
    	maxself(ans,dp[i]);
    }
    cout<<ans<<endl;





    
    //time();
    stop;
}

Measured memory_bytes: 1024