// 自上而下
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+4;
int x[N],y[N],dp[N][N];
int cnt,v;
int solve( int i,int j )
{
if( dp[i][j] ) return dp[i][j];
if( i==0 ) return 0;
// ( i-1,0 )
if( j<x[i] ) return dp[i][j]=solve( i-1,j );
else return dp[i][j]=max( solve( i-1,j ),solve( i-1,j-x[i] )+y[i] );
return dp[i][j];
}
int main()
{
while( cin>>cnt>>v )
{
for( int i=1;i<=cnt;i++ ) cin>>x[i]>>y[i];
memset( dp,0,sizeof( dp ) );
solve( cnt,v );
cout<<dp[cnt][v]<<endl;
}
return 0;
}
// 自下而上
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+4;
int x[N],y[N],dp[N][N];
int cnt,v;
void solve()
{
memset( dp,0,sizeof( dp ) );
for( int i=1;i<=cnt;i++ )
for( int j=0;j<=v;j++ )
{
if( j<x[i] ) dp[i][j]=dp[i-1][j];
else dp[i][j]=max( dp[i-1][j],dp[i-1][j-x[i]]+y[i] );
}
}
int main()
{
while( cin>>cnt>>v )
{
for( int i=1;i<=cnt;i++ ) cin>>x[i]>>y[i];
solve();
cout<<dp[cnt][v]<<endl;
}
return 0;
}
// 轮换滚动
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+4;
int x[N],y[N],dp[2][N];
int cnt,v;
int solve()
{
memset( dp,0,sizeof( dp ) );
int k1=0,k2=1; // turn
for( int i=1;i<=cnt;i++ )
{
swap( k1,k2 );
for( int j=0;j<=v;j++ )
{
if( j<x[i] ) dp[k1][j]=dp[k2][j];
else dp[k1][j]=max( dp[k2][j],dp[k2][j-x[i]]+y[i] );
}
}
return dp[k1][v];
}
int main()
{
while( cin>>cnt>>v )
{
for( int i=1;i<=cnt;i++ ) cin>>x[i]>>y[i];
cout<<solve()<<endl;
}
return 0;
}
// 自我反序滚动
#include<bits/stdc++.h>
using namespace std;
const int N=1e3+4;
int x[N],y[N],dp[N];
int cnt,v;
int solve()
{
memset( dp,0,sizeof( dp ) );
for( i=1;i<=cnt;i++ ) // 反序循环 至 x[i] 截止
for( j=v;j>=x[i];j-- )
dp[j]=max( dp[j],dp[j-x[i]]+y[i] );
return dp[v];
}
int main()
{
while( cin>>cnt>>v )
{
for( int i=1;i<=cnt;i++ ) cin>>x[i]>>y[i];
cout<<solve()<<endl;
}
return 0;
}