// Original C++ solution (slower):
#include<cstdio>  

#include<cstring>  

#include<cstdlib>

#include<cmath>

#include<iostream>

#include<string>

#include<algorithm>  

#include<map>

#include<iomanip>

using namespace std;  

typedef long long LL;



struct good  

{  

    int w, v;  

}g[110];  

  

bool cmp(good a, good b)  

{  

    return a.v > b.v;  

}  

good A[110], B[110], C[110], D[110];  

  

LL swa[110], swb[110], swc[110], swd[110];

LL sva[110], svb[110], svc[110], svd[110];

  

int main()  

{  

    int n, w, i, j, k, l;  

    int a, b, c, d;  

    scanf("%d%d", &n, &w);

    {  

        a = b = c = d = 0;  

        for(i = 1; i <= n; i++)  

        {  

            scanf("%d%d", &g[i].w, &g[i].v);  

            if(g[i].w == g[1].w)  

                A[++a] = g[i];  

            if(g[i].w == g[1].w + 1)  

                B[++b] = g[i];  

            if(g[i].w == g[1].w + 2)  

                C[++c] = g[i];  

            if(g[i].w == g[1].w + 3)  

                D[++d] = g[i];  

        }  

        sort(A+1,A+a+1,cmp);  

        sort(B+1,B+b+1,cmp);  

        sort(C+1,C+c+1,cmp);  

        sort(D+1,D+d+1,cmp);  

        swa[0] = swb[0] = swc[0] = swd[0] = 0;  

        sva[0] = svb[0] = svc[0] = svd[0] = 0;  

        for(i = 1; i <= a; i++)  

        {  

            swa[i] = swa[i-1] + A[i].w;  

            sva[i] = sva[i-1] + A[i].v;  

        }  

        for(i = 1; i <= b; i++)  

        {  

            swb[i] = swb[i-1] + B[i].w;  

            svb[i] = svb[i-1] + B[i].v;  

        }  

        for(i = 1; i <= c; i++)  

        {  

            swc[i] = swc[i-1] + C[i].w;  

            svc[i] = svc[i-1] + C[i].v;  

        }  

        for(i = 1; i <= d; i++)  

        {  

            swd[i] = swd[i-1] + D[i].w;  

            svd[i] = svd[i-1] + D[i].v;  

        }  

        int sumv = 0;  

        int ans = 0;  

        for(i = 0; i <= a; i++)  

        {  

            for(j = 0; j <= b; j++)  

            {  

                for(k = 0; k <= c; k++)  

                {  

                    for(l =0 ; l <= d; l++)  

                    {  

                        LL sum = swa[i] + swb[j] + swc[k] + swd[l];  

                        if(sum <= (LL)w)  

                        {  

                            ans = max((LL)ans, sva[i] + svb[j] + svc[k] + svd[l]);  

                        }  

                    }  

                }  

            }  

        }  

        cout << ans << endl;  

    }  

  

    return 0;  

}

// Optimized solution to the same problem (faster):
#include       <set>

#include       <map>

#include     <queue>

#include     <cmath>

#include    <cstdio>

#include    <cctype>

#include    <vector>

#include   <cstring>

#include <algorithm>

using namespace std;



typedef long long ll;

const ll mod = 1e9+7;

const double eps = 1e-7;

const int maxn = 105;



ll fast_pow(ll a,ll b,ll mod){

    ll ans = 1;

    while(b){

        if(b&1)

            ans = ans*a%mod;

        a = a*a%mod;

        b>>=1;

    }

    return ans;

}



int w[maxn], v[maxn];

int dp[maxn*4][maxn];



int main(){

    int n, W, c;

    scanf("%d%d",&n,&W);

    for(int i=0;i<n;i++)

        scanf("%d%d",&w[i],&v[i]);

    for(int i=1;i<n;i++)

        w[i] -= w[0]-1;

    c = w[0]-1;

    w[0] = 1;

    for(int i=0;i<n;i++)

        for(int j=(i+1)*4;j>=w[i];j--)

            for(int k=1;k<=i+1;k++){

                dp[j][k] = max(dp[j][k],dp[j-w[i]][k-1]+v[i]);

    }

    int ans = 0;

    for(int j=n*4;j>=0;j--)

        for(int k=1;k<=n;k++){

            if(1ll*k*c+j<=W){

                ans = max(ans,dp[j][k]);

            }

    }

    printf("%d\n",ans);

    return 0;

}




// Fastest known solution for this problem: