// Slower C++ solution:
//01背包 

#include<bits/stdc++.h>

using namespace std;



const int N = 105;

long long f[100050];//滚动数组

long long v[N];//价值

int w[N];//重量

int n,m;

 

int main()

{

 	cin>>n;//物品种数

	cin>>m;//背包容量

	for(int i = 1;i<=n;++i){

		cin>>w[i]>>v[i];

	}

	

	memset(f,0,sizeof(f));

	for(int i = 1;i<=n;++i){//外层循环物品个数 

		for(int j = m;j>=w[i];--j){//内层循环背包体积 (从大到小循环） 

			f[j] = max(f[j],f[j-w[i]]+v[i]);

		}

	}

	cout<<f[m]<<endl;

	return 0;

} 

// Faster C++ solution for the same problem (measured speedup: 1.803507998593899x):








/******************************************************/

/******************************************************/

/**                                                  **/

/**            BISMILLAHIR RAHMANIR RAHIM            **/

/**         REAZ AHAMMED CHOWDHURY - reaziii         **/

/**  Department of Computer Science and Engineering  **/

/*         INSTITUTE OF SCIENCE AND TECHNOLOGY       **/

/**                                                  **/

/******************************************************/

/******************************************************/







#include<bits/stdc++.h>

#define sc(x)        scanf("%lld",&x)

#define pcase(x)     printf("Case %d: ",x++)

#define pn           printf("\n")

#define fri(f)       for(int i=0;i<f;i++)

#define frj(f)       for(int j=0;j<f;j++)

#define reset(x,e)   memset(x,e,sizeof(x))

#define all(x)       x.begin(),x.end()

#define input        freopen("input.txt","r",stdin);

#define output       freopen("output.txt","w",stdout)

#define infi         INT_MAX

#define m_v          3000000

#define pii          pair<int,int>

#define pch          pair<char,char>

#define pll          pair<ll,ll>

#define mgraph       map<int,vector<int> >

#define mp           make_pair

#define pb           push_back

#define clr(x)       memset(x,0,sizeof(x))

#define frx(x,y)     for(int x=0;x<y;x++)

#define ff           first

#define ss           second

using namespace std;

typedef long long int ll;

typedef unsigned long long int ull;

bool checkbitt(ll num, int pos);

ll setbitt(ll num, ll pos);

ll resetbitt(ll num, int pos);

void abcd() {

#ifndef ONLINE_JUDGE

	input;

	output;

#endif

#ifdef ONLINE_JUDGE

	ios_base::sync_with_stdio(false);

	cin.tie(0);

#endif

}



void read(int *aa, int sz) {fri(sz) scanf("%d", (aa + i));}

void read(ll *aa, int sz) {fri(sz) scanf("%lld", (aa + i));}

void read(ll *aa, int s, int e) {for (int i = s; i < s + e; i++)scanf("%lld", (aa + i));}

void read(int *aa, int s, int e) {for (int i = s; i < s + e; i++)scanf("%d", (aa + i));}

const ll mod =       1e9 + 7;

const ll N =     1e6 + 10;



//.................___Start from here___.................//

//.................._____________________................//

int n, k;

ll dp[N];

ll w[N];

ll v[N];







int solve() {

	cin >> n >> k;

	for (int i = 1; i <= n; i++) {

		cin >> w[i] >> v[i];

	}





	for (int i = 1; i <= n; i++) {

		for (int j = k; j >= 1; j--) {

			if (j >= w[i]) {

				dp[j] = max(dp[j], dp[j - w[i]] + v[i]);

			}

		}

	}



	cout << dp[k] << endl;





	return 0;

}

int main() {

	// abcd();

	int cs = 1;

	int cn = 1;

	//cin>>cs;

	while (cs--) {

		solve();



	}

}





bool checkbitt(ll num, int pos) {return (num >> pos) & 1;}

ll setbitt(ll num, ll pos) {return (1 << pos) | num;}

ll resetbitt(ll num, int pos) {if (!checkbitt(num, pos)) return num; else return (1 << pos)^num;}