#define _USE_MATH_DEFINES
#include <cassert>
#include <cctype>
#include <cerrno>
#include <cfloat>
#include <ciso646>
#include <climits>
#include <clocale>
#include <cmath>
#include <csetjmp>
#include <csignal>
#include <cstdarg>
#include <cstddef>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <ctime>
#include <ccomplex>
#include <cfenv>
#include <cinttypes>
#include <cstdbool>
#include <cstdint>
#include <ctgmath>
#include <cwchar>
#include <cwctype>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <exception>
#include <fstream>
#include <functional>
#include <iomanip>
#include <ios>
#include <iosfwd>
#include <iostream>
#include <iterator>
#include <limits>
#include <list>
#include <locale>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <ostream>
#include <queue>
#include <set>
#include <sstream>
#include <stack>
#include <stdexcept>
#include <streambuf>
#include <string>
#include <typeinfo>
#include <utility>
#include <valarray>
#include <vector>
#include <array>
#include <atomic>
#include <chrono>
#include <condition_variable>
#include <forward_list>
#include <future>
#include <initializer_list>
#include <mutex>
#include <random>
#include <ratio>
#include <regex>
#include <scoped_allocator>
#include <system_error>
#include <thread>
#include <tuple>
#include <typeindex>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef unsigned long ull;
typedef vector<pii> vii;
typedef vector<int> vi;
typedef pair<int, int> ii;
typedef priority_queue<int> maxPq;
typedef priority_queue<ll, vector<ll>, greater<ll> > minPq;
typedef deque<int> dq;
#define F first
#define S second
#define PB push_back
#define MP make_pair
#define forVar(type, var, init, till, increment) for (type var = init; var < till; var += increment)
#define deb(x) cout << x << endl;
#define MAX 5 * 10000 + 1
#define INF 10000000000

// Knapsack 1: Atcoder Educational DP contest
int n, peso, wi;
ll v;
vi wes;
vector<ll> utils;
ll dpUtility[102][100001];


ll knapsack()
{
    for(int i = 0; i <= n; ++i)
    {
        for (int w = 0; w <= peso; ++w)
        {
            if (i == 0 || w == 0) dpUtility[i][w] = 0;
            else if (wes[i-1] <= w) dpUtility[i][w] = max(dpUtility[i-1][w], dpUtility[i-1][w-wes[i-1]] + utils[i-1]);
            else dpUtility[i][w] = dpUtility[i-1][w];
        }
    }
    return dpUtility[n][peso];
}


ll recursiveKnapsack(int curr, int remWeight)
{
    if (remWeight < 0) return -1000000000LL;
    if (curr == n) return 0;
    if (dpUtility[curr][remWeight] != -1) return dpUtility[curr][remWeight];

    ll skipear = recursiveKnapsack(curr+1, remWeight);
    ll tomar = recursiveKnapsack(curr+1, remWeight - wes[curr]) + utils[curr];

    dpUtility[curr][remWeight] = max (skipear, tomar);

    return dpUtility[curr][remWeight];
}


int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);

    cin >> n >> peso;
    // For recursive filling only, else comment this.

    memset(dpUtility, -1, sizeof(dpUtility));
    for(int i = 0; i < n; ++i)
    {
        cin >> wi >> v;
        wes.push_back(wi);
        utils.push_back(v);
    }


    cout << recursiveKnapsack(0, peso) << endl;
    return 0;
}

Measured memory_bytes: 80000