#include <bits/stdc++.h>
using namespace std;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int N;
long long W;
if (!(cin >> N >> W)) return 0;
vector<pair<long long,long long>> a(N); // (w, v)
for (int i = 0; i < N; ++i) {
long long v, w;
cin >> v >> w;
a[i] = {w, v};
}
sort(a.begin(), a.end()); // sort by weight asc
// Gom theo trọng lượng
struct Group { long long w; vector<long long> vals; };
vector<Group> g;
for (auto [w, v] : a) {
if (g.empty() || g.back().w != w) g.push_back({w, {}});
g.back().vals.push_back(v);
}
priority_queue<long long> pq;
long long ans = 0;
long long usedSlots = 0; // số slot đã dùng theo đơn vị w_{i} của vòng lặp hiện tại
for (int i = (int)g.size() - 1; i >= 0; --i) {
// Chuyển đơn vị slot từ w_{i+1} xuống w_i: nhân với r = w_{i+1}/w_i
if (i + 1 < (int)g.size()) {
long long r = g[i + 1].w / g[i].w;
// đảm bảo không vượt quá floor(W / w_i)
long long Ti = W / g[i].w;
__int128 scaled = (__int128)usedSlots * r;
if (scaled > Ti) usedSlots = Ti;
else usedSlots = (long long)scaled;
}
// Thêm các món có đúng trọng lượng w_i
for (long long v : g[i].vals) pq.push(v);
long long Ti = W / g[i].w; // tối đa slot đơn vị w_i có thể dùng
long long add = Ti - usedSlots; // còn có thể lấp thêm bao nhiêu slot
while (add > 0 && !pq.empty()) {
ans += pq.top(); pq.pop();
++usedSlots; --add;
}
}
cout << ans << '\n';
return 0;
}