#include<bits/stdc++.h>
using namespace std;
#define P pair<int,int>
int n,W,suf,i,j,k,VMAX,x,y,z,t;
P obj[5002],sufpart[5002];
class I
{
private:
FILE *F;
char *buff;
int sp;
char read_ch()
{
++sp;
if (sp == 4096) {
sp = 0;
fread(buff, 1, 4096, F);
}
return buff[sp];
}
public:
I(const char* nume)
{
F = fopen(nume, "r");
buff = new char[4096]();
sp = 4095;
}
I& operator >> (int &n)
{
char c;
for(c=read_ch();!isdigit(c);c=read_ch());
for(n=0;isdigit(c);n=10*n+c-'0',c=read_ch());
return *this;
}
};
int greedsuf(int poz,int wmax)
{
int rez=0;
while(poz<n&&obj[poz].first<wmax)
rez+=obj[poz].second,wmax-=obj[poz++].first;
if(poz==n)
return rez;
return rez+obj[poz].second*wmax/obj[poz].first;
}
void B(int poz,int vtot,int rem)
{
if(poz==n)
VMAX=max(VMAX,vtot);
else {
if(rem-obj[poz].first>=0&&vtot+obj[poz].second+greedsuf(poz+1,rem-obj[poz].first)>VMAX)
B(poz+1,vtot+obj[poz].second,rem-obj[poz].first);
if(vtot+greedsuf(poz+1,rem)>VMAX)
B(poz+1,vtot,rem);
}
}
bool A(P a,P b)
{
return a.second*b.first>=b.second*a.first;
}
int main()
{
I F("rucsac.in");
ofstream G("rucsac.out");
for(F>>n>>W;i<n;F>>obj[i].first>>obj[i].second,++i);
for(sort(obj,obj+n,A),obj[n].first=1,i=n-1;i>=0;sufpart[i]=make_pair(sufpart[i+1].first+obj[i].first,sufpart[i+1].second+obj[i].second),--i);
for(i=0;i<n&&x+obj[i].first<=W;x+=obj[i].first,VMAX+=obj[i++].second);
return B(0,0,W),G<<VMAX,0;
}