/*
* Problem :: 4781 / 사탕 가게
*
* Kind :: Dynamic programming
*
* Insight
* - 전형적인 냅색(Knapsack) 문제중 하나
* + Unbounded Knapsack Problem
* 물건의 개수가 무한하고 쪼갤 수 없음
* # dp[i][j] = 1~i 번째 사탕을 사용해서 j 만큼의 돈을 구매했을 때 최대 칼로리 양
*
* - 사실 이 문제의 어려운점은 DP 가 아니다...
* + 돈의 양(배낭의 무게)이 소수점 2자리의 실수다!!!
* # 100을 곱하면 되지 않나?
* -> 그렇게 간단할 리가 없지...
*
* - 부동소수점의 무시무시함을 다시 느끼고 가자
* + 알아낸 바는 다음과 같다
* # 0.35 == 0.01 * 35 => false
* 99.99 == 0.01 * 9999 => false
* # 0.35 == stod("0.35") => true
* 99.99 == stod("99.99") => true
* # (int)(0.29 * 100) => 28
* (int)(81.85 * 100) => 8184
* # cout << fixed;
* cout.precision(20)
* 로 설정하면
* -> cout << 0.29 => 0.28999999999999998002
* cout << 0.35 * 100 => 28.99999999999999644729
* -> cout << 81.85 => 81.84999999999999431566
* cout << 81.85 * 100 => 8184.99999999999909050530
*
* Point
* - 그러니...
* round(반올림) 해주자
*
* - double 이 너무 무서워져서 <= 0.0 은 0 과 같은가? <= true
* string 으로 받고 stod 했다...
*/
//
// BOJ
// ver.C++
//
// Created by GGlifer
//
// Open Source
#include <iostream>
#include <cmath>
#include <cstring>
using namespace std;
#define endl '\n'
// Set up : Global Variables
/* None */
// Set up : Functions Declaration
/* None */
int main()
{
// Set up : I/O
ios::sync_with_stdio(false);
cin.tie(nullptr);
// Set up : Input
int N; string m;
while (true) {
cin >> N >> m;
if (N == 0 && m == "0.00") break;
int M = (int)(round(stod(m)*100));
int C[N+1], P[N+1];
for (int i=1; i<=N; i++) {
int c; string p;
cin >> c >> p;
C[i] = c;
P[i] = (int)(round(stod(p)*100));
}
// Process
int dp[N+1][M+1];
memset(dp, 0, sizeof(dp));
for (int i=1; i<=N; i++) {
for (int j=1; j<=M; j++) {
/* 1~(i-1) 번째 사탕을 사용해서 j 만큼의 돈을 구매했을 때 최대 칼로리 양 */
dp[i][j] = dp[i-1][j];
/* 1~i 번째 사탕을 사용해서 j 만큼의 돈을 구매했을 때 최대 칼로리 양과 비교 */
if (j-P[i] >= 0) {
dp[i][j] = max(dp[i][j], dp[i][j-P[i]]+C[i]);
}
/* 위의 코드와 아래 코드의 로직은 같음
* 위의 코드의 경우는 Unbounded 일때 적용 <= 개수가 무한임
* 아래 코드의 경우는 Bounded 일때 적용 <= 개수가 한정됨
* 여기서는 k 로 돈이 허락하는 한 사탕을 최대한 많이 구매하게끔하여
* UnBounded 를 흉내냄 */
// for (int k=1; k<=j/P[i]; k++) {
// dp[i][j] = max(dp[i][j], dp[i-1][j-k*P[i]]+k*C[i]);
// }
}
}
// Control : Output
cout << dp[N][M] << endl;
}
}
// Helper Functions
/* None */