#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
const int N=300010,M=300010;
int n,m,i,j,k,w,x,y,o,q[N];ll f[N],g[N],v[M];
struct P{int x,y;}a[M];//x 重量 y 价值
bool cmp(P a,P b){return a.x==b.x?a.y>b.y:a.x<b.x;}
void solve(int l,int r,int dl,int dr)
{
int m=(l+r)>>1,dm=dl;ll&d=g[m];d=0;//g[m]=d dm为初始dl d取最小值
for(int i=dl;i<=dr&&i<=m;i++)
{//从dl到dr
ll t=f[q[i]];
if(m-i<=o)t+=v[m-i];//如果有的话就把v中 也就是最大价值最小重量的几个
//东西加起来 如果v[m-i] 没有的话就是0
if(t>d)d=t,dm=i;//更新d--能达到的最大值
}
if(l<m)solve(l,m-1,dl,dm);
if(r>m)solve(m+1,r,dm,dr);
}
int main()
{
scanf("%d%d",&n,&m);
for(i=1;i<=n;i++)scanf("%d%d",&a[i].x,&a[i].y);
sort(a+1,a+n+1,cmp);//排序
for(i=1;i<=n;i=j)
{
w=a[i].x;//w取最前的价值
if(w>m)break;//剪枝
for(j=i;j<=n&&a[i].x==a[j].x;j++)v[j-i+1]=v[j-i]+a[j].y;//相同的重量且同价值的处理
o=j-i;//数组v 有多少个相同的(o)
for(k=0;k<w;k++)
{
for(x=k,y=0;x<=m;x+=w)q[++y]=x;//能取多少个(y个)w存在q里
solve(1,y,1,y);
for(x=1;x<=y;x++)f[q[x]]=g[x];//更新f[]值
}
}
printf("%I64d",f[m]);
}