#include <bits/stdc++.h>
using namespace std;
long long n, m;
struct nod {
  long long val, pt1, pt2;
} dp[300005];
ifstream in("selling.in");
vector<long long> unu, doi, trei;
nod Max(nod a, nod b) { return a.val < b.val ? b : a; }
int main() {
  long long i, j, w, v, last1, last2, var1, var2;
  cin >> n >> m;
  for (i = 1; i <= n; i++) {
    cin >> w >> v;
    if (w == 1) unu.push_back(v);
    if (w == 2) doi.push_back(v);
    if (w == 3) trei.push_back(v);
  }
  sort(unu.begin(), unu.end());
  sort(doi.begin(), doi.end());
  sort(trei.begin(), trei.end());
  for (i = 1; i <= m; i++) {
    if (int(unu.size()) - dp[i - 1].pt1 - 1 >= 0)
      var1 = dp[i - 1].val + unu[int(unu.size()) - 1 - dp[i - 1].pt1];
    else
      var1 = 0;
    if (i >= 2 && int(doi.size()) - dp[i - 2].pt2 - 1 >= 0)
      var2 = dp[i - 2].val + doi[int(doi.size()) - 1 - dp[i - 2].pt2];
    else
      var2 = 0;
    if (var1 > var2) {
      if (var1 > dp[i].val) {
        dp[i].val = var1;
        dp[i].pt1 = dp[i - 1].pt1 + 1;
        dp[i].pt2 = dp[i - 1].pt2;
      }
    } else {
      if (var2 > dp[i].val) {
        dp[i].val = var2;
        dp[i].pt1 = dp[i - 2].pt1;
        dp[i].pt2 = dp[i - 2].pt2 + 1;
      }
    }
  }
  for (i = 1; i <= m; i++) dp[i] = Max(dp[i - 1], dp[i]);
  long long sol = 0, sum = 0, l = trei.size();
  for (i = 0; 3 * i <= m; i++) {
    sol = max(sol, dp[m - 3 * i].val + sum);
    if (trei.empty()) break;
    sum += trei.back(), trei.pop_back();
  }
  cout << sol << "\n";
}
