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

#include<cstdio>

#include<algorithm>

#include<cstring>

#include<cmath>

#include<queue>

typedef long long LL;

using namespace std;

int N,W;

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

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

struct good

{

	int w,v;

};

good s[105],a[105],b[105],c[105],d[105];

bool cmp(good xx,good yy){ return xx.v>yy.v; }

inline LL max(LL aa,LL bb){ return aa>bb?aa:bb; }

int main()

{

	while(scanf("%d%d",&N,&W)!=EOF)

	{

		LL ans=0;

		int A=0,B=0,C=0,D=0;

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

		{

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

			if(s[i].w==s[1].w) a[++A]=s[i];

			if(s[i].w==s[1].w+1) b[++B]=s[i];

			if(s[i].w==s[1].w+2) c[++C]=s[i];

			if(s[i].w==s[1].w+3) d[++D]=s[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(int i=1;i<=A;i++)

		{

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

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

		}

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

		{

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

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

		}

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

		{

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

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

		}

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

		{

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

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

		}

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

			for(int j=0;j<=B;j++)

				for(int k=0;k<=C;k++)

					for(int l=0;l<=D;l++)

					{

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

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

					}

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

	}

	return 0;

}


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

#include <cstring>

#include <cmath>

#include <algorithm>

using namespace std;

typedef long long LL;

struct huowu

{

	int w,v;

}g[105];

huowu A[105], B[105], C[105], D[105];

bool cmp(huowu a,huowu b)

{

	return a.v > b.v;

}

int n,W;

int main()

{

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

	int a, b, c, d, f;

	a = b = c = d = f = 0;

	for(int 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];

		}

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

		{

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

		}

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

		{

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

		}

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

		{

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

		}

	}

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

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

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

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

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

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

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

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

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

    {  

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

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

    }  

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

    {  

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

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

     }  

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

     {  

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

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

     }  

     for(int 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(int i = 0;i <= a;i++)  

    {  

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

         {  

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

            {  

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

              {  

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

					if(sum <= (LL)W)  

					{  

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

					}  

			 }  

            }  

        }  

    }  

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

    return 0;  

}  

	

	

// Fastest known solution for this problem: