#include <bits/stdc++.h>
using namespace std;
const int MAX = 1e5 + 5;
vector<int> v[4];
int n, m;
long long roll(const vector<int> &v2, const vector<int> &v3, int capacity) {
  vector<long long> pref(v2.size());
  for (int i = int(0); i < int(v2.size()); i++) {
    pref[i] = i == 0 ? v2[i] : pref[i - 1] + v2[i];
  }
  long long best = 0;
  long long total = 0;
  for (int i = 0; i < (int)v3.size() + 1 && i * 3 <= capacity; i++) {
    int has = min((int)v2.size(), (capacity - i * 3) / 2);
    best = max(best, (has > 0 ? pref[has - 1] : 0) + total);
    if (i < (int)v3.size()) {
      total += v3[i];
    }
  }
  return best;
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = int(1); i < int(n + 1); i++) {
    int w, c;
    scanf("%d %d", &w, &c);
    v[w].push_back(c);
  }
  for (int i = int(1); i < int(4); i++) {
    sort(v[i].begin(), v[i].end(), greater<int>());
  }
  vector<int> v2 = v[2];
  for (int i = 0; i + 1 < (int)v[1].size(); i += 2) {
    v2.push_back(v[1][i] + v[1][i + 1]);
  }
  sort(v2.begin(), v2.end(), greater<int>());
  long long ans = roll(v2, v[3], m);
  if (!v[1].empty()) {
    v2 = v[2];
    long long best_one = v[1][0];
    for (int i = 1; i + 1 < (int)v[1].size(); i += 2) {
      v2.push_back(v[1][i] + v[1][i + 1]);
    }
    sort(v2.begin(), v2.end(), greater<int>());
    ans = max(ans, roll(v2, v[3], m - 1) + best_one);
  }
  printf("%lld\n", ans);
  return 0;
}
