#include<algorithm>
#include<cmath>
#include<cstdio>
#include<iostream>
#include<map>
#include<numeric>
#include<queue>
#include<sstream>
#include<stack>
#include<string>
#include<unordered_set>
#include<vector>

#define ll long long
#define P pair<int,int>
#define FOR(i,N) for(int i=0;i<(int)N;i++)
#define FORIN(i,a,b) for(int i=a;i<(int)b;i++)
#define ALL(x) (x).begin(),(x).end()
#define LAST(x) (x)[(x).size()-1]
#define GI(name) int (name);scanf("%d",&(name))
#define GI2(name1,name2) int (name1),(name2);scanf("%d %d",&(name1),&(name2))
#define GI3(name1,name2,name3) int (name1),(name2),(name3);scanf("%d %d %d",&(name1),&(name2),&(name3))
#define GVI(name,size) vector<int> (name)(size);FOR(i,(size))scanf("%d",&(name)[i])
#define MOD 1000000007

using namespace std;

string to_hex(int x){
    stringstream ss;
    ss<<hex<<x;
    return ss.str();
}

inline int get_int(){
    int ret;
    scanf("%d",&ret);
    return ret;
}

inline vector<int> get_ints(int n){
    vector<int> ret(n);
    FOR(i,n){
        scanf("%d",&ret[i]);
    }
    return ret;
}

inline string get_str(){
    string ret;
    cin>>ret;
    return ret;
}

bool is_prime(int n){
    int s=sqrt(n)+1;
    for(int i=2;i<=s;++i){
        if(n%i==0){
            return 0;
        }
    }
    return 1;
}

vector<P> prime_division(int n){
    vector<P> ret;
    int s=sqrt(n)+1;
    int c=0;
    for(int i=2;i<=n;++i){
        if(n%i==0){
            c=0;
            do{
                ++c;
                n/=i;
            }while(n%i==0);
            ret.push_back(P(i,c));
        }
    }
    return ret;
}

struct UnionFind{
    vector<int> data;
    UnionFind(int size){
        data=vector<int>(size,-1);
    }
    bool union_set(int x,int y){
        x=root(x);
        y=root(y);
        if(x!=y){
            if(data[y]<data[x])swap(x,y);
            data[x]+=data[y];
            data[y]=x;
        }
        return x!=y;
    }
    bool find(int x,int y){
        return root(x)==root(y);
    }
    int root(int x){
        return data[x]<0?x:data[x]=root(data[x]);
    }
    int size(int x){
        return -data[root(x)];
    }
};

string to_string(string s){
    return s;
}

template<class T>
string to_string(vector<T> v){
    string ret="{";
    FOR(i,v.size()-1){
        ret+=to_string(v[i])+",";
    }
    if(v.size()>0){
        ret+=to_string(LAST(v));
    }
    ret+="}";
    return ret;
}

void debug_print(){
    cerr<<endl;
}

template<class Head,class... Tail>
void debug_print(Head head,Tail... tail){
    cerr<<to_string(head)<<" ";
    debug_print(tail...);
}

template<class... T>
void debug(T... args){
    cerr<<"["<<__LINE__<<"]: ";
    debug_print(args...);
}

void print(){
    cout<<endl;
}

template<class Head,class... Tail>
void print(Head head,Tail... tail){
    cout<<to_string(head);
    print(tail...);
}

int main(){
    ll N,W;
    cin>>N>>W;
    vector<int> l1,l2,l3,l4;
    GI2(w1,v1);
    l1.push_back(v1);
    FOR(i,N-1){
        GI2(w,v);
        if(w==w1){
            l1.push_back(v);
        }else if(w==w1+1){
            l2.push_back(v);
        }else if(w==w1+2){
            l3.push_back(v);
        }else{
            l4.push_back(v);
        }
    }
    sort(ALL(l1),greater<int>());
    sort(ALL(l2),greater<int>());
    sort(ALL(l3),greater<int>());
    sort(ALL(l4),greater<int>());
    int a1=l1.size(),a2=l2.size(),a3=l3.size(),a4=l4.size();
    vector<int> s1(a1+1),s2(a2+1),s3(a3+1),s4(a4+1);
    FOR(i,a1)s1[i+1]=s1[i]+l1[i];
    FOR(i,a2)s2[i+1]=s2[i]+l2[i];
    FOR(i,a3)s3[i+1]=s3[i]+l3[i];
    FOR(i,a4)s4[i+1]=s4[i]+l4[i];
    int ans=0;
    for(int c1=0;c1<=a1;++c1){
        int sum_w1=w1*c1;
        int sum_v1=s1[c1];
        if(sum_w1>W)break;
        for(int c2=0;c2<=a2;++c2){
            int sum_w2=sum_w1+(w1+1)*c2;
            int sum_v2=sum_v1+s2[c2];
            if(sum_w2>W)break;
            for(int c3=0;c3<=a3;++c3){
                int sum_w3=sum_w2+(w1+2)*c3;
                int sum_v3=sum_v2+s3[c3];
                if(sum_w3>W)break;
                int c4=min(a4,(int)(W-sum_w3)/(w1+3));
                int sum_v=sum_v3+s4[c4];
                ans=max(ans,sum_v);
            }
        }
    }
    print(ans);
    return 0;
}

Measured memory_bytes: 256