#include<bits/stdc++.h>
	using namespace std;
	#define M (int)1e9
	#define pi 3.1415926536
	#define all(a) a.begin(),a.end()
	#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
	#define flp(i,x,y) for(long long int i=x;i<y;i++)
	#define ll long long int 
	#define MOD (long long int)(1000000007)
	vector <int> SieveOfEratosthenes(int n) 
	{ 
	    vector<int> ans;
	    bool prime[n+1]; 
	    memset(prime, true, sizeof(prime)); 
	  
	    for (int p=2; p*p<=n; p++) 
	    if (prime[p] == true) 
	    for (int i=p*p; i<=n; i += p) 
	    prime[i] = false; 
	        
	  	for (int p=2; p<=n; p++) 
	    if (prime[p]) 
	    ans.push_back(p);
		return ans;
	}
	 
	vector <int> fib(int n)
	{
		vector<int> ans;
		int x=0,y=1,l=1;
		ans.push_back(x);
		ans.push_back(y);
		while(l<n)
		{
			l=x+y;
			x=y;y=l;
			ans.push_back(l);
		}
		return ans;
	}
	 
	bool isPrime(ll n) 
	{ 
		if (n <= 1) return false; 
		if (n <= 3) return true; 
	 
		if (n%2 == 0 || n%3 == 0) return false; 
	 
		for (ll i=5; i*i<=n; i=i+6) 
			if (n%i == 0 || n%(i+2) == 0) 
			return false; 
	 
		return true; 
	} 
	 
	 
	long long power(int n,int k)
	{
		if(k==0)	return 1;
		else return (n*power(n,k-1)%1000000007);
	}
	 
	long long nCr(int n,int r)
	{
		if(n==r)	return 1;
		else if (r==0)	return 1;
		else return ((nCr(n-1,r-1)+nCr(n-1,r))%998244353);
	}

	int sdigit(int x)
	{
		int ans=0;
		while(x)
		{
			ans+=x%10;
			x/=10;
		}
		return ans;
	}
	 
	long long lcm(int a,int b)
	{
		return ((long long)a*(long long)b)/__gcd(a,b);
	}
	 
	 
	 pair<int,int> subArraySum(int arr[], int n, int sum) 
	{ 
	    int curr_sum = arr[0], start = 0, i; 
	  
	    for (i = 1; i <= n; i++) 
	    { 
	        while (curr_sum > sum && start < i - 1) 
	        { 
	            curr_sum = curr_sum - arr[start]; 
	            start++; 
	        } 
	  
	        
	        if (curr_sum == sum) 
	        {  
	            //cout << "Sum found between indexes " 
	              //   << start << " and " << i - 1; 
	            return make_pair(start,i-1); 
	        } 
	  
	        if (i < n) 
	        curr_sum = curr_sum + arr[i]; 
	    } 
	  
	    return make_pair(-1,-1); 
	} 

	int bs(int a[],int b,int l,int r)
	{
		int mid=(l+r)/2;
		if(l>r)	return -1;
		if(a[mid]==b||l==r)	return mid;
		if(a[mid]>b)	return bs(a,b,l,mid-1);
		else return bs(a,b,mid+1,r);
	}

	int divideandconquerbc(int a[],int l,int r)
	{
		if(l>=r)	return 0;
		int mid=(l+r)/2,ans=0;
		ans+=divideandconquerbc(a,l,mid);
		ans+=divideandconquerbc(a,mid+1,r);
		int x=r-l+1,y=mid-l+1;
		int c[x];
		int i=0,j=0;
		for(int k=0;k<x;k++)
		{
			if((a[l+i]<=a[mid+1+j]&&i<y)||j>=x-y)	{c[k]=a[l+i];i++;}
			else {c[k]=a[mid+1+j];j++;ans+=y-i;}
			//cout<<c[k]<<" "<<ans<<endl;
			
		}
		for(int k=l;k<=r;k++)
			a[k]=c[k-l];
	    return ans;
	}

	void explore(bool a[],vector<vector <int> >adj,int u)
	{
		if(a[u-1])	return;
		else	a[u-1]=true;
		for(int i=0;i<adj[u-1].size();i++)
		{
			explore(a,adj,adj[u-1][i]+1);
		}
	}
	long long  gcd(int a,int b)
	{
	    if (b==0) return a;
	    return gcd(b,a%b);
	}
	 
	double startTime;
	double getCurrentTime() {
		return ((double)clock() - startTime) / CLOCKS_PER_SEC;
	}
	/*int dfs(int u,int f)
	{
		depth[u]=depth[f]+1;size[u]=1;
		for (int i=0;i<conj[u].size();++i)
		{
			if ((v=conj[u][i])==f)continue;
			size[u]+=dfs(v,u);
		}
		det[u]=size[u]-depth[u];return size[u];*/
void out(ll n)
{
	string a,b;
    cin >>a>>b;
    vector<int> v1,v2;
    a+='0';
    b+='0';
    flp(i,1,n+1)
    {
    	if(a[i]!=a[i-1])
    		v1.push_back(i);
    	if(b[i]!=b[i-1])
    		v2.push_back(i);

    }
    cout<<v1.size()+v2.size()<<" ";
    flp(i,0,v1.size())
    cout<<v1[i]<<" ";
    flp(i,0,v2.size())
    cout<<v2[v2.size()-i-1]<<" ";
    cout<<"\n";

}	

int point(char A, char B)   {
    if(A == B)  return 0;

    if(A == 'R')    {
        if(B == 'P')    return -1;
        else    return 1;
    }

    if(A == 'P')    {
        if(B == 'R')    return 1;
        else    return -1;
    }

    else    {
        if(B == 'R')    return -1;
        else    return 1;
    }
}
/*int mex(int r[])
{
	int n=sizeof(r)/sizeof(r[0]);
	int b[n+1]={};
	int st=0;
	flp(i,0,n)
	{
		b[a[i]]=1;
		while(b[st]==1)
			st++;
	}
	return st;

}*/
/*ll modInverse(ll n, ll p) 
{ 
    return power(n, p-2, p); 
}*/ 
int good (int n,string s,char ch)
{
	if (n==1){
		if (s[0]==ch) return 0;
		else return 1;
	}else{
		int f1=0,f2=0;
		for (int i=0;i<n/2;i++){
			if (s[i]==ch) f1++;
			if (s[n-i-1]==ch) f2++;
		}
		string s1=s.substr(n/2,n);
		int ans1= (n/2)-f1 + good(n/2,s1,ch+1);
		string s2=s.substr(0,n/2);
		int ans2= (n/2)-f2 + good(n/2,s2,ch+1);
		return  min(ans1,ans2);
		
	}
}
	int main()
	{
		//#ifndef ONLINE_JUDGE
		//freopen("input.txt","r",stdin);
		//freopen("ou.txt","w",stdout);
		//#endif
		fastio 
		long long int T,i,r,c0=0,c1=0,c2=0,ctr,m,n,a,b,c,d,t,mx=1,g,f,l1,l2,sum=0,o,m1,m2,x,x2,y1,y2,x1,y,k,p,num=1,step,l,z;
	//long	double ar;
	int k1,k2,k3,p1=-1,p2=-1,p3=-1,p5=-1,p4=-1,j,pd=0,U=-1e9;
	T=1;
		//cin>>T;
		bool res=false;
		ctr=1;
		while(T--)
		{
			//res=false;
			cin>>n>>c;
			ll w[100],v[100];
			flp(i,0,n)
			cin>>w[i]>>v[i];
			ll dp[100][100001];
			dp[0][0]=0;
			dp[0][w[0]]=v[0];
			flp(i,1,n)
			{
				dp[i][0]=0;
				flp(j,1,c+1)
				{
					dp[i][j]=dp[i-1][j];
					if(j>=w[i])
						dp[i][j]=max(dp[i][j],v[i]+dp[i-1][j-w[i]]);
				}
			}
			ll ans=-1e18;
			flp(i,0,c+1)
			ans=max(ans,dp[n-1][i]);
			cout<<ans;

			
				}
		return 0;
			}
			
			
		


Measured memory_bytes: 80936