#include<stdio.h>
#include<string.h>
#include<vector>
using namespace std;
const int NMAX = 105;
int n, l, last, bmax[NMAX], a[NMAX], b[NMAX], solA[NMAX], solB[NMAX];
vector <int> lastInd[NMAX], lastA[NMAX];
bool vis[NMAX];
bool check (int t) {
int i, j, B, A, pos, iA, lim;
for(i = 1; i <= l; ++ i)
bmax[i] = -1;
bmax[0] = 0;
lim = 0;
for(i = 1; i <= n; ++ i)
for(A = lim; A >= 0; -- A)
if(bmax[A] != -1)
for(iA = 1; a[i] * iA <= t && A + iA <= l; ++ iA) {
B = (t - a[i] * iA) / b[i];
if(iA == 0) {
bmax[A] += B;
lastInd[A].push_back(i);
lastA[A].push_back(iA);
// fprintf(stderr, "\nind - %d, pos - %d, added - %d", i, iA, 0);
continue;
}
pos = A + iA;
if(bmax[A] + B > bmax[pos]) {
bmax[pos] = bmax[A] + B;
lastInd[pos].clear();
lastInd[pos].push_back(i);
lastA[pos].clear();
lastA[pos].push_back(iA);
// fprintf(stderr, "\ndel - %d\nind - %d, pos - %d, added - %d", pos, i, pos, iA);
}
lim = max(lim, pos);
}
return bmax[l] >= l;
}
void buildSol (int t) {
int lastpos, pos, ind, i;
memset(vis, 0, sizeof(vis));
memset(solA, 0, sizeof(solA));
memset(solB, 0, sizeof(solB));
pos = lastpos = l;
while(pos > 0) {
for(i = 0; i < lastInd[pos].size(); ++ i) {
ind = lastInd[pos][i];
if(!vis[ind]) {
solA[ind] = lastA[pos][i];
solB[ind] = (t - solA[ind] * a[ind]) / b[ind];
vis[ind] = 1;
pos -= solA[ind];
}
}
if(pos == lastpos)
break;
lastpos = pos;
}
}
int bs (int right) {
int left, mid, last;
left = 1;
while(left <= right) {
mid = (left + right) / 2;
if(check(mid)) {
buildSol(mid);
last = mid;
//fprintf(stderr, "val = %d\n", mid);
right = mid - 1;
}
else
left = mid + 1;
}
return last;
}
int main() {
freopen("lapte.in", "r", stdin);
freopen("lapte.out", "w", stdout);
int i;
scanf("%d%d", &n, &l);
for(i = 1; i <= n; ++ i)
scanf("%d%d", &a[i], &b[i]);
printf("%d\n", bs(100));
for(i = 1; i <= n; ++ i)
printf("%d %d\n", solA[i], solB[i]);
return 0;
}