//code by lynmisakura.wish to be accepted!
/****************************/
#include<iostream>
#include<iomanip>
#include<math.h>
#include<vector>
#include<string>
#include<stack>
#include<queue>
#include<map>
#include<algorithm>
#include<bitset>
#include<climits>
#include<set>
#include<bitset>
using namespace std;
/***************************/
typedef long long ll;
typedef vector<ll> vi;
typedef vector<long long> vl;
typedef pair<ll, ll> pi;
typedef vector<pair<ll, ll>> vpi;

//const long long INF = 1LL << 55;

#define itn ll
#define endl '\n'
#define pb push_back
#define mp make_pair
#define eb emplace_back
#define ss second
#define ff first
#define dup(x,y) ((x) + (y) - 1)/(y)
#define mins(x,y) x = min(x,y)
#define maxs(x,y) x = max(x,y)
#define all(x) (x).begin(),(x).end()
#define Rep(n) for(ll i = 0;i < n;i++)
#define rep(i,n) for(ll i = 0;i < n;i++)
#define flush fflush(stdout)
#define rrep(i,n) for(ll i = n - 1;i >= 0;i--)
#define UNIQUE(v) v.erase( unique(v.begin(), v.end()), v.end() )
#define ioboost cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(20)
ll gcd(ll a, ll b) { return b ? gcd(b, a%b) : a; }
ll qp(ll a, ll b) { ll ans = 1; do { if (b & 1)ans = 1ll * ans*a; a = 1ll * a*a; } while (b >>= 1); return ans; }
ll qp(ll a, ll b, ll mo) { ll ans = 1; do { if (b & 1)ans = 1ll * ans*a%mo; a = 1ll * a*a%mo; } while (b >>= 1); return ans; }

#define _GLIBCXX_DEBUG
#define debug(x) cerr << #x << " = " << (x) << " (L" << __LINE__ << ")" << " " << __FILE__ << endl
ll dp[3010][3010];
int main(void){
    int n,t;cin >> n >> t;
    vector<pair<ll,ll>> meal(n);
    ll ans = 0;
    for (int j = 0; j < n; ++j) {
        cin >> meal[j].ss >> meal[j].ff;
    }
    for (int i = 0; i < n; ++i)
    {
        ll b = meal[i].ff , a = meal[i].ss;
        for (int now_time = 0; now_time < t; ++now_time)
        {
            if(now_time + a >= t){
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][t], dp[i][now_time] + b);
            }else{
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][now_time + a], dp[i][now_time] + b);
            }
        }
    }


    for (int i = 0; i < 3010; ++i) {
        for (int j = 0; j < 3010; ++j) {
            maxs(ans,dp[i][j]);
        }
    }


    sort(all(meal));
    rep(i,3010)rep(j,3010)dp[i][j] = 0;
    for (int i = 0; i < n; ++i)
    {
        ll b = meal[i].ff , a = meal[i].ss;
        for (int now_time = 0; now_time < t; ++now_time)
        {
            if(now_time + a >= t){
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][t], dp[i][now_time] + b);
            }else{
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][now_time + a], dp[i][now_time] + b);
            }
        }
    }


    for (int i = 0; i < 3010; ++i) {
        for (int j = 0; j < 3010; ++j) {
            maxs(ans,dp[i][j]);
        }
    }

    reverse(all(meal));
    rep(i,3010)rep(j,3010)dp[i][j] = 0;
    for (int i = 0; i < n; ++i)
    {
        ll b = meal[i].ff , a = meal[i].ss;
        for (int now_time = 0; now_time < t; ++now_time)
        {
            if(now_time + a >= t){
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][t], dp[i][now_time] + b);
            }else{
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][now_time + a], dp[i][now_time] + b);
            }
        }
    }


    for (int i = 0; i < 3010; ++i) {
        for (int j = 0; j < 3010; ++j) {
            maxs(ans,dp[i][j]);
        }
    }

    for (int k = 0; k < n; ++k) {
        swap(meal[k].ff,meal[k].ss);
    }

    sort(all(meal));
    rep(i,3010)rep(j,3010)dp[i][j] = 0;
    for (int i = 0; i < n; ++i)
    {
        ll b = meal[i].ss , a = meal[i].ff;
        for (int now_time = 0; now_time < t; ++now_time)
        {
            if(now_time + a >= t){
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][t], dp[i][now_time] + b);
            }else{
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][now_time + a], dp[i][now_time] + b);
            }
        }
    }


    for (int i = 0; i < 3010; ++i) {
        for (int j = 0; j < 3010; ++j) {
            maxs(ans,dp[i][j]);
        }
    }

    reverse(all(meal));
    rep(i,3010)rep(j,3010)dp[i][j] = 0;
    for (int i = 0; i < n; ++i)
    {
        ll b = meal[i].ss , a = meal[i].ff;
        for (int now_time = 0; now_time < t; ++now_time)
        {
            if(now_time + a >= t){
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][t], dp[i][now_time] + b);
            }else{
                maxs(dp[i+1][now_time],dp[i][now_time]);
                maxs(dp[i+1][now_time + a], dp[i][now_time] + b);
            }
        }
    }


    for (int i = 0; i < 3010; ++i) {
        for (int j = 0; j < 3010; ++j) {
            maxs(ans,dp[i][j]);
        }
    }

    cout << ans << endl;
}

Measured memory_bytes: 71168