/*
下面给出O(log amount)时间处理一件多重背包中物品的过程,其中amount表示物品的数量:
procedure MultiplePack(cost,weight,amount)
if cost*amount>=V
CompletePack(cost,weight)
return
integer k=1
while k<amount
ZeroOnePack(k*cost,k*weight)
amount=amount-k
k=k*2
ZeroOnePack(amount*cost,amount*weight)
*/
#include <iostream>//2585875 2010-07-10 22:43:25 Accepted 2844 234MS 624K 1067 B C++ 悔惜晟
#include <cstdio>
#include <cstring>
using namespace std;
int dp[100005];
int m;
void compelete(int cost, int weight)
{
for(int i = cost; i <= m; i++)
if(dp[i] < dp[i - cost] + weight)
dp[i] = dp[i - cost] + weight;
}
void one_zero(int cost, int weight)
{
for(int i = m; i >= cost; i--)
if(dp[i] < dp[i - cost] + weight)
dp[i] = dp[i - cost] + weight;
}
int main()
{
int a[105];
int c[105];
int n;
while(cin >> n >> m)
{
if(n == 0 && m == 0)
break;
for(int i = 1; i <= n; i++)
cin >> a[i];
for(int j = 1; j <= n; j++)
cin >> c[j];
memset(dp, 0, sizeof(dp));
for(int i = 1; i <= n; i++)
{
int tt = a[i] * c[i];
int t = c[i];
if(tt > m)
compelete(a[i], a[i]);//完全背包
else
{
int k = 1;// 0 - 1 背包
while(k < t)
{
one_zero(k * a[i], k*a[i]);
t -= k;
k *= 2;
}
one_zero(t * a[i], t * a[i]);
}
}
int count = 0;
for(int i = 1; i <= m; i++)
if(dp[i] == i)
count++;
printf("%d/n", count);
}
} /*
又是一道多重背包的变形,一开始转化为0-1背包连sample都没有过了,后来用了母函数,看看复杂程度
超时是难免的,最后还是要用多重背包,但是用了优化
将第i种物品分成若干件物品,其中每件物品有一个系数,
这件物品的费用和价值均是原来的费用和价值乘以这个系数。
使这些系数分别为 1,2,4,...,2^(k-1),n[i]-2^k+1,且k是满足n[i]-2^k+1>0的最大整数
例如,如果n[i]为13,就将这种 物品分成系数分别为1,2,4,6的四件物品。
*/
#include <iostream>//2585494 2010-07-10 20:45:20 Accepted 2844 437MS 276K 1446 B C++ 悔惜晟
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 105;
int main()
{
int n, m;
int val[N], kind[N];
while(scanf("%d %d", &n, &m) != EOF)
{
if(n == 0 && m == 0)
break;
for(int i = 1; i <= n; i++)
scanf("%d", &val[i]);
//int m1 = 0;
for(int i = 1; i <= n; i++)
{
scanf("%d", &kind[i]);
//m1 += val[i] * kind[i];
}
bool dp[100005];
/* 母函数 TLE
int c1[100005];
int c2[100005];
memset(c1, 0, sizeof(c1));
memset(c2, 0, sizeof(c2));
c1[0] = 1;
for(int i = 1; i <= n; i++)
{
for(int j = 0; j <= kind[i]; j++)
for(int k = 0; k <= m; k++)
if(k + j * val[i] <= m)
c2[k + j * val[i]] += c1[k];
else
break;
for(int j = 0; j <= m; j++)
{
c1[j] = c2[j];
c2[j] = 0;
}
}
int count = 0;
for(int i = 1; i <= m; i++)
if(c1[i] != 0)
count++;
printf("%d/n", count);
*/
memset(dp, false, sizeof(dp));
dp[0] = true;
for(int i = 1; i <= n ; i++)
{
int tt = kind[i];
for(int j = 1; j <= tt; j <<= 1)
{
for(int k = m; k >= j * val[i]; k--)
if(dp[k - j * val[i]])
dp[k] = true;
tt -= j;
}
if(tt != 0)
{
for(int k = m; k >= tt * val[i]; k--)
if(dp[k - tt * val[i]])
dp[k] = true;
}
}
int count1 = 0;
for(int i = 1; i <= m; i++)
if(dp[i])
count1++;
printf("%d/n", count1);
}
}