#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define INF 9e18
#define M (ll)(1e5+5)
typedef long long ll;
typedef vector <ll> vi;
typedef pair <ll,ll> pll;
typedef vector <pll> vpll;
typedef vector<vpll> vvpll;
ll mx(ll a,ll b){return a>=b ? a:b;}
ll mn(ll a,ll b){return a<=b ? a:b;}
ll dp[100005];
ll w[102],v[102];
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    ll n,x;cin>>n>>x;
    for(ll i=0;i<n;i++)
        cin>>w[i]>>v[i];
    for(ll i=0;i<n;i++)
        for(ll j=x;j>=w[i];j--)
            dp[j]=mx(dp[j],dp[j-w[i]]+v[i]);
    cout<<dp[x]<<endl;
    return 0;
}

/*
 #include <bits/stdc++.h>
 using namespace std;
 #define pb push_back
 #define mp make_pair
 //#define INF 9e18
 //#define M (ll)(1e5+5)
 typedef long long ll;
 typedef vector <ll> vi;
 typedef pair <ll,ll> pll;
 typedef vector <pll> vpll;
 typedef vector<vpll> vvpll;
 ll mx(ll a,ll b){return a>=b ? a:b;}
 ll mn(ll a,ll b){return a<=b ? a:b;}
 const int INF=1e9;
 const int N=205;
 void updMin(short &a,short b){
 a=min(a,b);
 }
 int solve(vector<int> a1,vector<int> a2){
 vector<vector<int> > a({a1,a2});
 vector<int> n({(int)a[0].size(), (int)a[1].size()});
 short dp[2][N][N][N];
 short lastDiag[2][N][N];
 short memDiag[2][N][N][N];
 auto can= [&](int dif){
 memset(lastDiag,63,sizeof(lastDiag));
 memset(memDiag,63,sizeof(memDiag));
 for(int sum=n[0]+n[1];sum>=0;sum--)
 for(int f=0;f<2;f++)
 for(int mturn=0;mturn<=sum;mturn++){
 int eturn=sum-mturn;
 if(!(mturn<=n[f] and eturn<=n[f^1])) continue;
 for (int mdead=0;mdead<=n[f];mdead++){
 if(mturn==n[f]){
 int need_edead=N-1;
 if(f==1 and dif>=0)
 need_edead=max(0,n[f^1]-eturn-abs(dif)+1+1);
 if(f==0 and dif<=0)
 need_edead=max(0,n[f^1]-eturn-abs(dif)+1);
 dp[f][eturn][mturn][mdead]=need_edead;
 }
 else{
 int mndiag=memDiag[f^1][mturn+1][eturn][mdead+1];
 int needKill=mndiag-eturn;
 int res=max(0,needKill-a[f][mturn]);
 res=min(res,N-1);
 dp[f][eturn][mturn][mdead]=res;
 }
 updMin(lastDiag[f][eturn][dp[f][eturn][mturn][mdead]],mturn+mdead);
 }
 for(int i=N-1;i>0;i--)
 updMin(lastDiag[f][eturn][i-1],lastDiag[f][eturn][i]);
 memcpy(memDiag[f][eturn][mturn],lastDiag[f][eturn],sizeof(lastDiag[f][eturn]));
 }
 return dp[0][0][0][0]==0;
 };
 int l=-N,r=N;
 while(r-l>1){
 int mid=(l+r)>>1;
 if(can(mid)) l=mid;
 else r=mid;
 }
 return L;
 }
 int main(){
 ios::sync_with_stdio(0);
 cin.tie(0);cout.tie(0);
 int n,m;
 cin>>n>>m;
 vector<int> a(n),b(m);
 for(int i=0;i<n;i++)
 cin>>a[i];
 for(int j=0;j<m;j++)
 cin>>b[j];
 auto ans=solve(a,b);
 string name= ans>0 ? "Gandalf" : "Saruman";
 int score=abs(ans)-1;
 cout<<name<<" "<<score<<endl;
 return 0;
 }

 */
/*
#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define mp make_pair
#define INF 9e18
#define M (ll)(1e5+5)
typedef long long ll;
typedef vector <int> vi;
typedef pair <ll,ll> pll;
typedef vector <pll> vpll;
typedef vector<vpll> vvpll;
ll mx(ll a,ll b){return a>=b ? a:b;}
ll mn(ll a,ll b){return a<=b ? a:b;}
const int N=500007;
string str;
struct expr{
    char type;
    int val,l,r;
    expr(){
        type='-';
        l=-1;
        r=-1;
        val=0;
    }
};
vi args;
vi ptr;
vector <expr> e;
int last=0,n;
void parse(int i){
    if(i>=n) return;
    last=i;
    if(str[i]=='(')
        parse(i+1);
    else if(str[i] == '&' or str[i] == '|' or str[i] == '^') {
        int id=e.size();
        ptr[i]=id;
        e.pb(expr());
        e[id].type=str[i];
        e[id].l=args.back();
        args.pop_back();
        parse(i+1);
        e[id].r=args.back();
        args.pop_back();
        args.pb(id);
        parse(last+1);
    }
    else if(str[i]=='1' or str[i]=='0'){
        int id=e.size();
        ptr[i]=id;
        e.pb(expr());
        e[id].val=str[i]-'0';
        args.pb(id);
        parse(i+1);
    }
}
int calc(int v){
    if(e[v].type=='-')
        return e[v].val;
    else if(e[v].type=='&')
        return calc(e[v].l) & calc(e[v].r);
    else if(e[v].type=='|')
        return calc(e[v].l) | calc(e[v].r);
    else if(e[v].type=='^')
        return calc(e[v].l) ^ calc(e[v].r);
}
int main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>str;
    cout<<"hata1\n";
    n=str.size();
    cout<<"hata3\n";
    ptr.resize(n);
    cout<<"hata\n";
    parse(0);
    cout<<"hata2"<<endl;
    int root=args.back();
    int t;
    cout<<calc(root);
    cin>>t;
    for(int i=0;i<t;i++){
        int k;char c;
        cin>>k>>c;
        k--;
        if(c=='0' or c=='1')
            e[ptr[k]].val=c-'0';
        else
            e[ptr[k]].type=c;
        cout<<calc(root);
    }
    return 0;
}
*/

/*
 #define linf 1000000000000000000LL
 #define bit(mask,i) ((mask>>i)&1)
 ll C[64][64];
 int bitcnt(ll x){
 int Res=0;
 for(;x;x-=(x&-x)) Res++;
 return Res;
 }
 ll Solve(ll x,int k){
 ll Answer=(k==bitcnt(x));
 for(int i=63;i>=0 and k>=0;i--)
 if(bit(x,i))
 Answer+=C[i][k--];
 return Answer;
 }
 int main(){
 ios::sync_with_stdio(0);
 cin.tie(0);cout.tie(0);
 C[0][0]=1;
 for(int i=1;i<=63;i++)
 for(int j=0;j<=i;j++)
 C[i][j]=C[i-1][j]+(j ? C[i-1][j-1] : 0);
 ll count;int k;
 cin>>count>>k;
 ll l=1,r=linf;
 while(l<r){
 ll mid=(r+l)>>1;
 if(Solve(mid<<1,k)-Solve(mid,k)<count) l=mid+1;
 else
 r=mid;
 }
 cout<<l<<endl;
 
 return 0;
 }

 */


Measured memory_bytes: 1024