#include <stdio.h>
#include <algorithm>
using namespace std;
int N, T, c[32], v[32], bst;
int config, opt[1<<20], st[32], SOL[32];
int prev[1<<20], w[1<<20];
int bit(int X, int nr_bit)
{ return (X & (1<<nr_bit)) != 0; }
int gcd(int a, int b)
{ return (b == 0 ? a : gcd(b, a%b)); }
void gcd_extins(int a, int b, int &X, int &Y)
{
int xp, yp;
if (b == 0)
X = 1, Y = 0;
else
{
gcd_extins(b, a%b, xp, yp);
X = yp; Y = xp - (a/b) * yp;
}
}
int A, B, X, Y, D;
void back(int nivel, int new_conf, int cmmmc, int TIMP)
{
if (TIMP > T)
return ;
if (nivel == N)
{
if (1 + opt[config-new_conf] < opt[config])
opt[config] = 1 + opt[config-new_conf],
prev[config] = config-new_conf,
w[config] = TIMP;
return ;
}
st[nivel] = 0; back(nivel+1, new_conf, cmmmc, TIMP);
if (bit(config, nivel))
{
st[nivel] = 1;
if (!cmmmc)
back(nivel+1, new_conf + (1<<nivel), v[nivel], c[nivel]);
else
{
A = cmmmc % v[nivel]; B = c[nivel] - TIMP % v[nivel];
if (B < 0) B += v[nivel];
D = gcd(A, v[nivel]);
if (B % D) return ;
gcd_extins(A, v[nivel], X, Y);
X = (X * (B/D)) % v[nivel];
if (X < 0) X += v[nivel];
// X este o solutie. Solutiile sunt de forma X + i * (v[nivel]/D)
X %= (v[nivel]/D); // aceasta este solutia minima
back(nivel+1, new_conf + (1<<nivel), cmmmc*(v[nivel]/gcd(cmmmc, v[nivel])), TIMP + X * cmmmc);
}
}
}
int main(void)
{
int i;
freopen("vanatoare.in", "r", stdin);
freopen("vanatoare.out", "w", stdout);
scanf("%d %d", &N, &T);
for (i = 0; i < N; ++i)
scanf("%d %d", &c[i], &v[i]);
for (config = 1; config < (1<<N); ++config)
{
opt[config] = 9999;
back(0, 0, 0, 0);
}
printf("%d\n", opt[(1<<N)-1]);
for (i = (1<<N)-1; i; i = prev[i])
SOL[++bst] = w[i];
sort(SOL+1, SOL+bst+1);
for (i = 1; i < bst; ++i)
printf("%d ", SOL[i]);
printf("%d\n", SOL[bst]);
return 0;
}