/*
trebuie sa gasim ai, bi astfel incat:
max(ta * ai + tb * bi) sa fie minim
sum(ai) >= l && sum(bi) >= l
facand cbin, trebuie sa vedem daca exista un sir de numere ai, bi a.i.
max(ta * ai + tb * bi) <= t && sum(ai) >= l && sum(bi) >= l
fixand pentru fiecare om in parte ai, putem considera cateva perecchi valide.
Odata fixat t, atunci putem alege, pentru fiecare om in parte, un numar de
perechi (ai, bi). facem dinamica d[i][j] = cantitatea de lapte de tip b
buna, daca luam primele i persoane, cu j lapte a.
*/
#include <bits/stdc++.h>
using namespace std;
struct int_it : iterator<random_access_iterator_tag, int>{
int x;
int_it(): x(0){}
int_it(const int xx): x(xx){}
int_it operator++(){ ++x; return *this; }
int_it operator+=(const int d){ x += d; return *this; }
int operator-(const int_it& rhs){ return x - rhs.x; }
int operator*(){ return x; } };
bool verif_posibil(const int n, const int t, const int l,
const vector<int>& ta, const vector<int>& tb){
vector<int> d_cur(l+1, -1000 * 1000 * 1000), d_prev(l+1, 0);
d_cur[0] = 0;
for(int i = 0; i < n; ++i){
copy(begin(d_cur), end(d_cur), begin(d_prev));
for(int a = 0; a <= l && a * ta[i] <= t; ++a){
const int b = (t - a * ta[i]) / tb[i];
for(int j = l-a, k = l; j >= 0; --j, --k){
d_cur[k] = max(d_cur[k], d_prev[j] + b); } } }
return d_cur[l] >= l; }
vector<pair<int, int>> build_sol(const int n, const int t, const int l,
const vector<int>& ta, const vector<int>& tb){
vector<vector<int>> d(n+1, vector<int>(l+1, -1000 * 1000 * 1000));
vector<vector<pair<int, int>>> prev(n+1, vector<pair<int,int>>(l+1, make_pair(-1, -1)));
d[0][0] = 0;
for(int i = 0; i < n; ++i){
for(int a = 0; a <= l && a * ta[i] <= t; ++a){
const int b = (t - a * ta[i]) / tb[i];
for(int j = l-a, k = l; j >= 0; --j, --k){
if(d[i+1][k] < d[i][j]+b){
d[i+1][k] = d[i][j]+b;
prev[i+1][k] = make_pair(a, b); } } } }
vector<pair<int, int>> rez(n);
for(int i = n, j = l; i > 0; --i){
rez[i-1] = prev[i][j];
j -= rez[i-1].first; }
return rez; }
int main(){
ifstream f("lapte.in");
ofstream g("lapte.out");
int n, l;
f >> n >> l;
vector<int> ta(n), tb(n);
for(int i = 0; i < n; ++i){
f >> ta[i] >> tb[i]; }
const int rez = *partition_point(int_it(1), int_it(101), [&](const int t){
return !verif_posibil(n, t, l, ta, tb); });
const auto plan = build_sol(n, rez, l, ta, tb);
g << rez << '\n';
for(const auto p : plan){
g << p.first << ' ' << p.second << '\n'; }
return 0; }