#include <bits/stdc++.h>
#pragma GCC optimize("Ofast", "unroll-loops")
using namespace std;
const int iinf = 1 << 29;
const long long inf = 1ll << 60;
const long long mod = 1e9 + 7;
void GG() {
  cout << "No\n";
  exit(0);
}
long long mpow(long long a, long long n) {
  long long re = 1;
  while (n > 0) {
    if (n & 1) re = re * a % mod;
    a = a * a % mod;
    n >>= 1;
  }
  return re;
}
long long inv(long long b) {
  if (b == 1) return b;
  return (mod - mod / b) * inv(mod % b) % mod;
}
const int maxn = 1e5 + 5;
vector<long long> a[4];
vector<long long> even, odd;
vector<long long> eps, ops;
long long poss(long long w) {
  if (w < 0) return -inf;
  long long re = 0;
  if (w & 1 && a[1].size() > 0) {
    re += a[1][0];
    re += ops[min((w - 1) / 2, (long long)ops.size() - 1)];
    return re;
  } else {
    re += eps[min(w / 2, (long long)eps.size() - 1)];
    return re;
  }
}
int main() {
  ios::sync_with_stdio(false), cin.tie(0), cout.tie(0);
  int n, m;
  cin >> n >> m;
  for (int i = 0; i < (n); i++) {
    int w;
    long long c;
    cin >> w >> c;
    a[w].push_back(c);
  }
  a[1].push_back(0);
  for (int i = 0; i < (4); i++) {
    sort(a[i].begin(), a[i].end(), greater<long long>());
  }
  even = odd = a[2];
  eps.push_back(0);
  ops.push_back(0);
  if (a[1].size()) {
    for (int i = 1; i + 1 < a[1].size(); i += 2) {
      odd.push_back(a[1][i] + a[1][i + 1]);
    }
  }
  for (int i = 0; i + 1 < a[1].size(); i += 2) {
    even.push_back(a[1][i] + a[1][i + 1]);
  }
  sort(even.begin(), even.end(), greater<long long>());
  sort(odd.begin(), odd.end(), greater<long long>());
  for (int i = 0; i < (odd.size()); i++) {
    ops.push_back(ops.back() + odd[i]);
  }
  for (int i = 0; i < (even.size()); i++) {
    eps.push_back(eps.back() + even[i]);
  }
  long long re = 0;
  long long s3 = 0;
  for (int i = 0; i < (a[3].size() + 1); i++) {
    re = max(re, (__typeof__(re))(s3 + poss(m - 3 * i)));
    if (i != a[3].size()) {
      s3 += a[3][i];
    }
  }
  cout << re << '\n';
}
