#include <bits/stdc++.h>
using namespace std;
struct Node {
  long long val;
  int a, b;
} dp[310000];
vector<int> w1, w2, w3;
long long s[110000];
int n, m;
bool cmp(int a, int b) { return a > b; }
int main() {
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) {
    int x, y;
    scanf("%d%d", &x, &y);
    if (x == 1) w1.push_back(y);
    if (x == 2) w2.push_back(y);
    if (x == 3) w3.push_back(y);
  }
  sort(w1.begin(), w1.end(), cmp);
  sort(w2.begin(), w2.end(), cmp);
  sort(w3.begin(), w3.end(), cmp);
  for (int i = 0; i < w3.size(); i++) s[i + 1] = s[i] + w3[i];
  dp[0].val = dp[0].a = dp[0].b = 0;
  long long ans = -1e16;
  for (int i = 1; i <= m; i++) {
    dp[i] = dp[i - 1];
    int a = dp[i - 1].a;
    if (a < w1.size() && dp[i - 1].val + w1[a] > dp[i].val) {
      dp[i].val = dp[i - 1].val + w1[a];
      dp[i].a++;
    }
    if (i > 1) {
      int b = dp[i - 2].b;
      if (i > 1 && b < w2.size() && dp[i - 2].val + w2[b] > dp[i].val) {
        dp[i] = dp[i - 2];
        dp[i].b++;
        dp[i].val = dp[i - 2].val + w2[b];
      }
    }
    ans = max(ans, dp[i].val +
                       s[min((int)w3.size(), (m - dp[i].a - 2 * dp[i].b) / 3)]);
  }
  ans = max(
      ans, dp[0].val + s[min((int)w3.size(), (m - dp[0].a - 2 * dp[0].b) / 3)]);
  printf("%I64d\n", ans);
  return 0;
}
