#include <bits/stdc++.h>
using namespace std;
struct node {
  long long c;
  int n1, n2, n3;
  node(long long c = 0, int n1 = 0, int n2 = 0, int n3 = 0)
      : c(c), n1(n1), n2(n2), n3(n3) {}
} dp[300005];
int N, M;
int v[4][300005];
int cnt[4];
void update(node &a, node b) {
  if (a.c < b.c) a = b;
}
int main() {
  cin >> N >> M;
  int w, x;
  for (int i = 1; i <= N; i++) {
    cin >> w >> x;
    v[w][++cnt[w]] = x;
  }
  for (int w = 1; w <= 3; w++) {
    sort(v[w] + 1, v[w] + cnt[w] + 1, greater<int>());
  }
  dp[0] = node(0, 0, 0, 0);
  long long ans = 0;
  for (int j = 0; j <= M; j++) {
    long long c = dp[j].c;
    int n1 = dp[j].n1, n2 = dp[j].n2, n3 = dp[j].n3;
    if (j + 1 <= M && n1 < cnt[1])
      update(dp[j + 1], node(c + v[1][n1 + 1], n1 + 1, n2, n3));
    if (j + 2 <= M && n2 < cnt[2])
      update(dp[j + 2], node(c + v[2][n2 + 1], n1, n2 + 1, n3));
    if (j + 3 <= M && n3 < cnt[3])
      update(dp[j + 3], node(c + v[3][n3 + 1], n1, n2, n3 + 1));
    if (j + 2 <= M && n1 && n3 < cnt[3])
      update(dp[j + 2], node(c - v[1][n1] + v[3][n3 + 1], n1 - 1, n2, n3 + 1));
    ans = max(ans, c);
  }
  cout << ans << endl;
  return 0;
}
