#include <iostream>
#include <string>
#include <vector>
#include <algorithm>
#include <cstring>
#include <cmath>
#include <limits>
#include <stack>
#include <queue>
#include <map>
#include <set>
#include <functional>

using namespace std;

using ll = long long;
using ui = unsigned int;
const ll MOD = 1000000007;
const ll INF = 9223372036854775807;


//E
//2�l�̑g�ݍ��킹
struct LLPair {
	int a = 0;
	int b = 0;
	LLPair() {}
	LLPair(int a, int b) {
		this->a = a;
		this->b = b;
	}
};

int main() {
	int N;
	scanf("%d", &N);
	int T;
	scanf("%d", &T);
	vector<LLPair> F(N + 1);
	for (int i = 0; i < N; i++) {
		scanf("%d %d", &F[i].a, &F[i].b);
	}

	std::sort(F.begin(), F.end(), [](const LLPair &a, const LLPair &b) {
		return a.b > b.b;
	});

	vector<vector<vector<int>>> dp(N + 1, vector<vector<int>>(T + 1, vector<int>(2, -1)));

	dp[0][0][0] = 0;

	for (int i = 0; i < N; i++) {
		for (int t = 0; t <= T; t++) {
			if (dp[i][t][0] >= 0) {
				//skip�Ȃ�

				//eat
				if (t + F[i].a <= T)
				{
					dp[i + 1][t + F[i].a][0] = max(dp[i + 1][t + F[i].a][0], dp[i][t][0] + F[i].b);
				}

				//skip
				if (t <= T - 1) {
					dp[i + 1][t][1] = max(dp[i + 1][t][1], dp[i][t][0] + F[i].b);
				}

				//through
				if (t == T) {
					dp[i + 1][t][0] = max(dp[i + 1][t][0], dp[i][t][0]);
				}
			}

			if (dp[i][t][1] >= 0) {
				//skip����

				//eat
				if (t + F[i].a <= T - 1) //skip����ꍇ�Ȃ̂ōŌ�̎��Ԃ��c���K�v������
				{
					dp[i + 1][t + F[i].a][1] = max(dp[i + 1][t + F[i].a][1], dp[i][t][1] + F[i].b);
				}

				//cannot skip -> through
				dp[i + 1][t] = max(dp[i + 1][t], dp[i][t]);
			}
		}
	}

	int result = 0;
	for (int t = 0; t <= T; t++) {
		result = max(dp[N][t][0], result);
		result = max(dp[N][t][1], result);
	}

	printf("%d\n", result);
}

//D
/*
//mod. m �ł� a �̋t�� a^{-1} ���v�Z����
//�g�p(num1 / num2) % m : (num1 * modinv(num2, m)) % m
ll modinv(ll a, ll m) {
	ll b = m, u = 1, v = 0;
	while (b) {
		ll t = a / b;
		a -= t * b; swap(a, b);
		u -= t * v; swap(u, v);
	}
	u %= m;
	if (u < 0) u += m;
	return u;
}


//�g�ݍ��킹C��mod�������l�����߂�
ll calcCombinationMOD(ll n, ll r, ll mod) {
	ll num = 1;
	for (ll i = 1; i <= r; i++) {
		num = num * (n - i + 1);
		num = num % mod;
		num = (num * modinv(i, mod)) % mod;
	}
	return num;
}

int main() {
	ll X;
	scanf("%lld", &X);
	ll Y;
	scanf("%lld", &Y);

	if ((X + Y) % 3 != 0) {
		printf("0\n");
		return 0;
	}

	ll M = (X + Y) / 3;
	ll Mx = X - M;
	ll My = Y - M;

	if (Mx < 0 || My < 0) {
		printf("0\n");
		return 0;
	}
 
	ll result = calcCombinationMOD(Mx + My, Mx, MOD);

	printf("%lld\n", result);
}
*/

//C
/*
struct LLPoint {
	ll x = 0;
	ll y = 0;
	LLPoint() {}
	LLPoint(ll x, ll y) {
		this->x = x;
		this->y = y;
	}
};

// nPn�̏���ɑ΂��ď��������s����
void foreach_permutation(int n, std::function<void(int *)> f) {
	int *indexes = new int[n];
	for (int i = 0; i < n; i++) indexes[i] = i;
	do {
		f(indexes);
	} while (std::next_permutation(indexes, indexes + n));
	delete[] indexes;
}

ll N;
double sum = 0;
ll c = 0;
vector<LLPoint> P;

int main() {
	scanf("%lld", &N);
	P.resize(N);
	for (ll i = 0; i < N; i++) {
		scanf("%lld %lld", &P[i].x, &P[i].y);
	}

	//���s��
	foreach_permutation(N, [](int *indexes) {
		//indexes[0] ~ indexes[N - 1]
		for (ll i = 0; i < N - 1; i++) {
			//i -> i+1
			ll sx = P[indexes[i]].x - P[indexes[i + 1]].x;
			ll sy = P[indexes[i]].y - P[indexes[i + 1]].y;
			double d = sqrt((double)(sx * sx) + (double)(sy * sy));
			sum += d;
		}
		c++;
	});

	double result = sum / (double)c;

	printf("%0.10f\n", result);
}
*/

//B
/*
int main() {
	ll N;
	scanf("%lld", &N);
	char S[220];
	scanf("%s", &S);

	bool result = true;

	if (N % 2 == 0) {
		ll half = N / 2;
		for (ll i = 0; i < half; i++) {
			if (S[i] != S[i + half]) {
				result = false;
				break;
			}
		}
	}
	else {
		result = false;
	}

	if (result) {
		printf("Yes\n");
	}
	else {
		printf("No\n");
	}
}
*/

//A
/*
int main() {
	ll r;
	scanf("%lld", &r);

	ll result = r * r;

	printf("%lld\n", result);
}
*/



Measured memory_bytes: 493056