// Original C++ solution (slower):
#include<stdio.h>

#include<memory.h>

#include<iostream>

#include<algorithm>

#define maxn 105

#define ll long long

using namespace std;

ll w[maxn],v[maxn];

ll w1[maxn],w2[maxn],w3[maxn],w4[maxn];

ll n,W;



bool compare(ll a,ll b)

{

    return a>b;

}



int main()

{

    while(~scanf("%d %d",&n,&W))

    {

        int i;

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

        {

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

        }



        memset(w1,0,sizeof(w1));

        memset(w2,0,sizeof(w2));

        memset(w3,0,sizeof(w3));

        memset(w4,0,sizeof(w4));



        int a=0,b=0,c=0,d=0;

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

        {

            switch(w[i]-w[1])

            {

                case 0: w1[a++]=v[i];break;

                case 1: w2[b++]=v[i];break;

                case 2: w3[c++]=v[i];break;

                case 3: w4[d++]=v[i];break;

            }

        }



        sort(w1,w1+a,compare);

        sort(w2,w2+b,compare);

        sort(w3,w3+c,compare);

        sort(w4,w4+d,compare);



        int j,k,l;

        ll maxx=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 ww;

                        ww=i*w[1]+j*(w[1]+1)+k*(w[1]+2)+l*(w[1]+3);

                        if(ww<=W)

                        {

                            ll vv=0;

                            int m;

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

                                vv+=w1[m];

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

                                vv+=w2[m];

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

                                vv+=w3[m];

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

                                vv+=w4[m];

                            if(vv>maxx) maxx=vv;

                        }

                    }

                }

            }

        }

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

    }

}


// 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=n*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: