#include <bits/stdc++.h>
using namespace std;
template <typename T>
inline T abs(T t) {
  return t < 0 ? -t : t;
}
const long long modn = 1000000007;
inline long long mod(long long x) { return x % modn; }
const int MAXN = 312345;
int n, m;
vector<long long> s[4];
struct pd {
  long long x;
  int i[3];
  pd(long long xx, int ii, int iii) {
    x = xx;
    i[1] = ii;
    i[2] = iii;
  }
  pd() {}
  bool operator<(const struct pd &o) const {
    return (x < o.x || (x == o.x && i[1] < o.i[1]));
  }
} dp[MAXN];
bool cmp(int a, int b) { return a > b; }
int main() {
  scanf("%d %d", &n, &m);
  long long res = 0;
  for (int a = 0; a < n; a++) {
    long long w, val;
    scanf("%lld %lld", &w, &val);
    s[w].push_back(val);
    if (w == 3) res += val;
  }
  for (int i = 1; i <= 3; i++) sort(s[i].begin(), s[i].end(), cmp);
  dp[0] = (pd){0, 0, 0};
  for (int i = 0; i < m; i++) {
    dp[i + 1] = max(dp[i], dp[i + 1]);
    if (dp[i].i[1] != s[1].size())
      dp[i + 1] = max(dp[i + 1], pd(dp[i].x + s[1][dp[i].i[1]], dp[i].i[1] + 1,
                                    dp[i].i[2]));
    if (dp[i].i[2] != s[2].size())
      dp[i + 2] = max(dp[i + 2], pd(dp[i].x + s[2][dp[i].i[2]], dp[i].i[1],
                                    dp[i].i[2] + 1));
    ;
  }
  int i = 0, j = 0;
  long long ans = 0;
  for (int k = s[3].size(); k >= 0; k--) {
    if (m < 3 * k) {
      if (k > 0) {
        res -= s[3][k - 1];
      }
      continue;
    }
    int sob = m - 3 * k;
    ans = max(ans, res + dp[sob].x);
    if (k > 0) res -= s[3][k - 1];
  }
  printf("%lld\n", ans);
}
