Problem:
Problem B:
Compress Files
Your computer is a little old-fashioned. Its CPU is slow, its memory is not enough, and its hard drive is
near to running out of space. It is natural for you to hunger for a new computer, but sadly you are not so
rich. You have to live with the aged computer for a while.
At present, you have a trouble that requires a temporary measure immediately. You downloaded a new
software from the Internet, but failed to install due to the lack of space. For this reason, you have decided
to compress all the existing files into archives and remove all the original uncompressed files, so more
space becomes available in your hard drive.
It is a little complicated task to do this within the limited space of your hard drive. You are planning to
make free space by repeating the following three-step procedure:
Choose a set of files that have not been compressed yet.
Compress the chosen files into one new archive and save it in your hard drive. Note that this step
        needs space enough to store both of the original files and the archive in your hard drive.
Remove all the files that have been compressed.
For simplicity, you don’t take into account extraction of any archives, but you would like to reduce the
number of archives as much as possible under this condition. Your task is to write a program to find the
minimum number of archives for each given set of uncompressed files.
Input
The input consists of multiple data sets.
Each data set starts with a line containing two integers
n
(1 ≤
n
≤ 14) and
m
(1 ≤
m
≤ 1000), where
n
indicates the number of files and
m
indicates the available space of your hard drive before the task of
compression. This line is followed by
n
lines, each of which contains two integers
b
i
and
a
i
.
b
i
indicates
the size of the
i
-th file without compression, and
a
i
indicates the size when compressed. The size of each
archive is the sum of the compressed sizes of its contents. It is guaranteed that
b
i
≥
a
i
holds for any
1 ≤
i
≤
n
.
A line containing two zeros indicates the end of input.
Output
For each test case, print the minimum number of compressed files in a line. If you cannot compress all
the files in any way, print “Impossible” instead.
Sample Input
6 1
2 1
2 1
2 1
2 1
2 1
5 1
1 1
4 2
0 0
Output for the Sample Input
2
Impossible

Submitted solutions:

code_snippet: #include <bits/stdc++.h>
using namespace std;
int main() {
    while (1) {
        int n, m;
        cin >> n >> m;
        if (n == 0 && m == 0) {
            return 0;
        }
        vector <int > a(n), b(n);
        for (int i = 0; i < n; i++) {
            cin >> a[i] >> b[i];
        }

        vector <int > space(1<<n), need(1<<n);
        for (int s = 0; s < (1<<n); ++s) {
            space[s] = m;
            need[s] = 0;
            for(int i = 0; i < n; ++i) {
                if((s >> i) & 1) {
                    space[s] += a[i] - b[i];
                    need[s] += b[i];
                }
            }
        }
        
        vector <int > dp(1 << n, 1e9 + 7);
        dp[0] = 0;
        for (int mask = 0; mask < (1 << n); mask++) {
            int rev_mask = mask ^ ((1 << n) - 1);
            int sub_mask = rev_mask;
            do {
                sub_mask = (sub_mask - 1) & rev_mask;
                if (space[mask] >= need[sub_mask]) {
                    dp[mask | sub_mask] = min(dp[mask | sub_mask], dp[mask] + 1);
                }
                
            } while (sub_mask != rev_mask);
        }
        if (dp[(1 << n) - 1] == 1e9 + 7) {
            cout << "Impossible" << endl;
        } else {
            cout << dp[(1 << n) - 1] << endl;
        }
    }
}
accuracy: 1
time_ms: 330
memory_kb: 3220
final_rank: 10

code_snippet: #pragma GCC optimize("Ofast")
#include <bits/stdc++.h>
using namespace std;
typedef long long int ll;
typedef unsigned long long int ull;

mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
ll myRand(ll B) { return (ull)rng() % B; }

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n,m;
    while (cin >> n >> m, n) {
        vector<int> a(n), b(n);
        for (int i = 0; i < n; ++i) {
            cin >> a[i] >> b[i];
        }
        vector<int> dp(1<<n, 1e9);
        vector<int> sum(1<<n);
        for (int i = 0; i < (1<<n); ++i) {
            for (int j = 0; j < n; ++j) {
                if ((1<<j) & i) sum[i] += b[j];
            }
        }
        dp[0] = 0;
        for (int i = 0; i < (1<<n); ++i) {
            int S = (1<<n) - 1 - i;
            int fr = m;
            for (int j = 0; j < n; ++j) {
                if ((1<<j) & i) fr += a[j] - b[j];
            }
            for (int T = S; T; T = (T-1) & S) {
                if (sum[T] <= fr) {
                    dp[i + T] = min(dp[i + T], dp[i] + 1);
                }
            }
        }
        if (dp.back() == 1e9) cout << "Impossible\n";
        else cout << dp.back() << "\n";
    }
}
accuracy: 1
time_ms: 310
memory_kb: 3484
final_rank: 12

code_snippet: #include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
using namespace std;
#define MAX 14
#define SMAX (1 << 14)
#define QMAX 17000
class State {
public:
  int used, n, size, cost, remain;
  State(int n = 0, int size = 0) : n(n), size(size) {
    used = 0;
    cost = 0;
    remain = n;
  }
  State(int n, int size, int cost, int remain)
      : n(n), size(size), cost(cost), remain(remain) {}
  bool operator<(const State &s) const { return used < s.used; }
};
int n, m;
pair<int, int> F[MAX];
int head, tail;
void rec(State &u, State &v, int pos, int fsize, State Q[QMAX],
         set<State> &visited) {
  if (pos == n) {
    v.size += fsize;
    if (visited.insert(v).second) {
      v.cost = u.cost + 1;
      Q[tail++] = v;
    }
    return;
  }
  if (!(v.used & (1 << pos)) && v.size >= F[pos].second) {
    State vv = v;
    vv.used |= (1 << pos);
    vv.remain--;
    vv.size -= F[pos].second;
    rec(u, vv, pos + 1, fsize + F[pos].first, Q, visited);
  }
  rec(u, v, pos + 1, fsize, Q, visited);
}
int bfs() {
  State s = State(n, m);
  static State Q[QMAX];
  head = tail = 0;
  set<State> visited;
  Q[tail++] = s;
  visited.insert(s);
  State u, v;
  while (head < tail) {
    u = Q[head++];
    if (u.remain == 0)
      return u.cost;
    rec(u, u, 0, 0, Q, visited);
  }
  return -1;
}
void compute() {
  int cost = bfs();
  if (cost < 0)
    cout << "Impossible" << endl;
  else
    cout << cost << endl;
}
main() {
  while (cin >> n >> m && n) {
    for (int i = 0; i < n; i++)
      cin >> F[i].first >> F[i].second;
    compute();
  }
}
accuracy: 1
time_ms: 4610
memory_kb: 4356
final_rank: 18

code_snippet: #include <algorithm>
#include <iostream>
#include <map>
#include <queue>
#include <set>
using namespace std;
#define MAX 14
#define SMAX (1 << 14)
#define QMAX 17000
class State {
public:
  int used, n, size, cost, remain;
  State(int n = 0, int size = 0) : n(n), size(size) {
    used = cost = 0;
    remain = n;
  }
};
int n, m;
pair<int, int> F[MAX];
void rec(State &u, State &v, int pos, int fsize, queue<State> &Q,
         bool visited[SMAX]) {
  if (pos == n) {
    v.size += fsize;
    if (!visited[v.used]) {
      visited[v.used] = true;
      v.cost = u.cost + 1;
      Q.push(v);
    }
    return;
  }
  if (!(v.used & (1 << pos)) && v.size >= F[pos].second) {
    State vv = v;
    vv.used |= (1 << pos);
    vv.remain--;
    vv.size -= F[pos].second;
    rec(u, vv, pos + 1, fsize + F[pos].first, Q, visited);
  }
  rec(u, v, pos + 1, fsize, Q, visited);
}
int bfs() {
  State s = State(n, m);
  queue<State> Q;
  bool visited[SMAX];
  Q.push(s);
  for (int i = 0; i < (1 << n); i++)
    visited[i] = false;
  visited[s.used] = true;
  State u, v;
  while (!Q.empty()) {
    u = Q.front();
    Q.pop();
    if (u.remain == 0)
      return u.cost;
    rec(u, u, 0, 0, Q, visited);
  }
  return -1;
}
void compute() {
  int cost = bfs();
  if (cost < 0)
    cout << "Impossible" << endl;
  else
    cout << cost << endl;
}
main() {
  while (cin >> n >> m && n) {
    for (int i = 0; i < n; i++)
      cin >> F[i].first >> F[i].second;
    compute();
  }
}
accuracy: 1
time_ms: 690
memory_kb: 3260
final_rank: 11

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	int normal,compress;
};


int N,M;
int POW[15];
int min_num[16384];
Info info[14];


void func(){

	for(int i = 0; i < N; i++){
		scanf("%d %d",&info[i].normal,&info[i].compress);
	}

	min_num[0] = 0;
	for(int i = 1; i < POW[N]; i++)min_num[i] = BIG_NUM;

	int ROOM,count,index_table[N];
	int add,compress_size;

	for(int state = 0; state < POW[N]-1; state++){
		if(min_num[state] == BIG_NUM)continue;

		ROOM = M;
		count = 0;

		for(int loop = 0; loop < N; loop++){
			if(state & (1 << loop)){
				ROOM += (info[loop].normal-info[loop].compress);
			}else{
				index_table[count] = loop;
				count++;
			}
		}

		for(int i = 0; i < POW[count]; i++){
			compress_size = 0;
			add = 0;
			for(int loop = 0; loop < count; loop++){
				if(i & (1 << loop)){
					compress_size += info[index_table[loop]].compress;
					if(compress_size > ROOM)continue;
					add += POW[index_table[loop]];
				}

				min_num[state+add] = min(min_num[state+add],min_num[state]+1);
			}
		}
	}

	if(min_num[POW[N]-1] == BIG_NUM){
		printf("Impossible\n");
	}else{
		printf("%d\n",min_num[POW[N]-1]);
	}
}


int main(){

	for(int i = 0; i < 15; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 6450
memory_kb: 3420
final_rank: 17

code_snippet: #include <stdio.h>
#include <cmath>
#include <algorithm>
#include <cfloat>
#include <stack>
#include <queue>
#include <vector>
#include <string>
#include <iostream>
#include <set>
#include <map>
#include <time.h>
typedef long long int ll;
typedef unsigned long long int ull;
#define BIG_NUM 2000000000
#define MOD 1000000007
#define EPS 0.000000001
using namespace std;


struct Info{
	int normal,compress;
};


int N,M;
int POW[15];
int min_num[16384];
Info info[14];


void func(){

	for(int i = 0; i < N; i++){
		scanf("%d %d",&info[i].normal,&info[i].compress);
	}

	min_num[0] = 0;
	for(int i = 1; i < POW[N]; i++)min_num[i] = BIG_NUM;

	int ROOM,count,index_table[N];
	int add,compress_size;

	for(int state = 0; state < POW[N]-1; state++){
		if(min_num[state] == BIG_NUM)continue;

		ROOM = M;
		count = 0;

		for(int loop = 0; loop < N; loop++){
			if(state & (1 << loop)){
				ROOM += (info[loop].normal-info[loop].compress);
			}else{
				index_table[count] = loop;
				count++;
			}
		}

		for(int i = 0; i < POW[count]; i++){
			compress_size = 0;
			add = 0;
			for(int loop = 0; loop < count; loop++){
				if(i & (1 << loop)){
					compress_size += info[index_table[loop]].compress;
					add += POW[index_table[loop]];
				}
				if(compress_size > ROOM)continue;
				min_num[state+add] = min(min_num[state+add],min_num[state]+1);
			}
		}
	}

	if(min_num[POW[N]-1] == BIG_NUM){
		printf("Impossible\n");
	}else{
		printf("%d\n",min_num[POW[N]-1]);
	}
}


int main(){

	for(int i = 0; i < 15; i++)POW[i] = pow(2,i);

	while(true){
		scanf("%d %d",&N,&M);
		if(N == 0 && M == 0)break;

		func();
	}

	return 0;
}
accuracy: 1
time_ms: 6720
memory_kb: 3408
final_rank: 19

code_snippet: #include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<iostream>
#include<string>
#include<vector>
#include<map>
#include<set>
#include<list>
#include<queue>
#include<deque>
#include<algorithm>
#include<numeric>
#include<utility>
#include<complex>
#include<functional>
 
using namespace std;

/* constant */

const int MAX_N = 14;

const int MAX_BITS = 1 << MAX_N;
const int INF = 1 << 30;

/* typedef */

/* global variables */

int n, m;
int bs[MAX_N], as[MAX_N];
int asums[MAX_BITS], dsums[MAX_BITS], dp[MAX_BITS];

/* subroutines */

/* main */

int main() {
  for (;;) {
    cin >> n >> m;
    if (n == 0) break;

    for (int i = 0; i < n; i++)
      cin >> bs[i] >> as[i];
    
    int maxbits = 1 << n;
    int allbits = maxbits - 1;
    
    memset(asums, 0, sizeof(asums));
    memset(dsums, 0, sizeof(dsums));

    for (int bits = 0; bits < maxbits; bits++) {
      asums[bits] = dsums[bits] = 0;
      for (int i = 0, b = 1; i < n; i++, b <<= 1)
	if (bits & b)
	  asums[bits] += as[i], dsums[bits] += bs[i] - as[i];
      dp[bits] = INF;
    }

    dp[0] = 0;
    
    for (int bits = 0; bits < maxbits; bits++) {
      int asize = m + dsums[bits];
      int cmask = allbits ^ bits;
      int cbits = 0;
      
      for (;;) {
	cbits = ((cbits | bits) + 1) & cmask;
	if (cbits == 0) break;

	if (asums[cbits] <= asize) {
	  int bits0 = bits | cbits;
	  dp[bits0] = min(dp[bits0], dp[bits] + 1);
	}
      }
    }

    if (dp[allbits] >= INF)
      cout << "Impossible" << endl;
    else
      cout << dp[allbits] << endl;
  }

  return 0;
}
accuracy: 1
time_ms: 460
memory_kb: 1360
final_rank: 6

code_snippet: #include<stdio.h>
#include<algorithm>
using namespace std;
int p[20];
int q[20];
int dp[1<<14];
int sum[1<<14];
int main(){
	int a,b;
	while(scanf("%d%d",&a,&b),a){
		for(int i=0;i<a;i++)scanf("%d%d",p+i,q+i);
		for(int i=0;i<(1<<a);i++){
			sum[i]=0;
			for(int j=0;j<a;j++)if(i&(1<<j))sum[i]+=q[j];
		}
		for(int i=0;i<(1<<a);i++)dp[i]=99999999;
		dp[0]=0;
		for(int i=0;i<(1<<a);i++){
			int now=(1<<a)-1-i;
			int fr=b;
			for(int j=0;j<a;j++)if(i&(1<<j))fr+=p[j]-q[j];
			while(now){
				int tmp=sum[now];
				if(fr>=tmp){
					dp[i+now]=min(dp[i+now],dp[i]+1);
				}
				now=(now-1)&((1<<a)-1-i);
			}
		}
		if(dp[(1<<a)-1]>99999)printf("Impossible\n");
		else printf("%d\n",dp[(1<<a)-1]);
	}
}
accuracy: 1
time_ms: 460
memory_kb: 1168
final_rank: 3

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

class State {
public:
  int _used;
  int _archives;
  State(int used,int archives) :
    _used(used), _archives(archives) {}
  bool operator <(const State& s) const {
    return _archives < s._archives;
  }
  bool operator >(const State& s) const {
    return _archives > s._archives;
  }
};

int open_space[1<<14];
int required_space[1<<14];
int dp[1<<14];

int main(){
  int total_files;
  int init_disk_space;
  while(~scanf("%d %d",&total_files,&init_disk_space)){
    if(total_files == 0 && init_disk_space == 0) break;

    vector<int> diff;
    vector<int> req;
    for(int file_i = 0; file_i < total_files; file_i++){
      int uncompressed,compressed;
      scanf("%d %d",&uncompressed,&compressed);
      diff.push_back(uncompressed - compressed);
      req.push_back(compressed);
    }
    
    memset(open_space,0,sizeof(open_space));
    memset(required_space,0,sizeof(required_space));
    memset(dp,0x3f,sizeof(dp));

    for(int S = 0; S <= (1<<total_files) - 1; S++){
      int open_sum = 0;
      int req_sum = 0;
      for(int file_i = 0; file_i < total_files; file_i++){
        if(S & (1 << file_i)){
          open_sum += diff[file_i];
          req_sum += req[file_i];
        }
      }
      open_space[S] = open_sum;
      required_space[S] = req_sum;
    }

    priority_queue<State,vector<State>,greater<State> > que;
    que.push(State(0,0));
    dp[0] = 0;
    while(!que.empty()){
      State s = que.top();
      que.pop();

      int rev = ((1<<total_files) - 1) & ~(s._used);
      for(int S = 0; S <= rev; S++){
        if(s._used & S) continue;
        if(dp[s._used | S] <= s._archives + 1) continue;
        if(required_space[S] > open_space[s._used] + init_disk_space) continue;
        dp[s._used | S] = s._archives + 1;
        que.push(State(s._used | S,s._archives + 1));
      }
    }

    if(dp[(1<<total_files) - 1] >= INF){
      printf("Impossible\n");
    }
    else{
      printf("%d\n",dp[(1<<total_files) - 1]);
    }
  }
}
accuracy: 1
time_ms: 3690
memory_kb: 1544
final_rank: 9

code_snippet: #define _USE_MATH_DEFINES
#define INF 0x3f3f3f3f
#include <cstdio>
#include <iostream>
#include <sstream>
#include <cmath>
#include <cstdlib>
#include <algorithm>
#include <queue>
#include <stack>
#include <limits>
#include <map>
#include <string>
#include <cstring>
#include <set>
#include <deque>
#include <bitset>
#include <list>
#include <cctype>
#include <utility>
 
using namespace std;
 
typedef long long ll;
typedef pair <int,int> P;
typedef pair <int,P > PP;
 
int tx[] = {0,1,0,-1};
int ty[] = {-1,0,1,0};
 
static const double EPS = 1e-8;

class State {
public:
  int _used;
  int _archives;
  State(int used,int archives) :
    _used(used), _archives(archives) {}
  bool operator <(const State& s) const {
    return _archives < s._archives;
  }
  bool operator >(const State& s) const {
    return _archives > s._archives;
  }
};

int open_space[1<<14];
int required_space[1<<14];
int dp[1<<14];

int main(){
  int total_files;
  int init_disk_space;
  while(~scanf("%d %d",&total_files,&init_disk_space)){
    if(total_files == 0 && init_disk_space == 0) break;

    vector<int> diff;
    vector<int> req;
    for(int file_i = 0; file_i < total_files; file_i++){
      int uncompressed,compressed;
      scanf("%d %d",&uncompressed,&compressed);
      diff.push_back(uncompressed - compressed);
      req.push_back(compressed);
    }
    
    memset(open_space,0,sizeof(open_space));
    memset(required_space,0,sizeof(required_space));
    memset(dp,0x3f,sizeof(dp));

    for(int S = 0; S <= (1<<total_files) - 1; S++){
      int open_sum = 0;
      int req_sum = 0;
      for(int file_i = 0; file_i < total_files; file_i++){
        if(S & (1 << file_i)){
          open_sum += diff[file_i];
          req_sum += req[file_i];
        }
      }
      open_space[S] = open_sum;
      required_space[S] = req_sum;
    }

    priority_queue<State,vector<State>,greater<State> > que;
    que.push(State(0,0));
    dp[0] = 0;
    while(!que.empty()){
      State s = que.top();
      que.pop();
      
      for(int S = 0; S <= (1<<total_files) - 1; S++){
        if(s._used & S) continue;
        if(dp[s._used | S] <= s._archives + 1) continue;
        if(required_space[S] > open_space[s._used] + init_disk_space) continue;
        dp[s._used | S] = s._archives + 1;
        que.push(State(s._used | S,s._archives + 1));
      }
    }

    if(dp[(1<<total_files) - 1] >= INF){
      printf("Impossible\n");
    }
    else{
      printf("%d\n",dp[(1<<total_files) - 1]);
    }
  }
}
accuracy: 1
time_ms: 7720
memory_kb: 1544
final_rank: 15

code_snippet: #include<bits/stdc++.h>

#define REP(i,s,n) for(int i=s;i<n;i++)
#define rep(i,n) REP(i,0,n)

using namespace std;

const int IINF = INT_MAX;
int n,m,dp[1<<15],cost[1<<15],memory[1<<15],b[15],a[15];

int main(){
  while( cin >> n >> m, n|m ){
    rep(i,n) cin >> b[i] >> a[i];
    rep(i,(1<<n)) dp[i] = IINF;
    rep(i,(1<<n)) {
      memory[i] = m,cost[i] = 0;
      rep(j,n)if( (i>>j) & 1){
	memory[i] += b[j];
	cost[i]   += a[j];
      }
      memory[i] -= cost[i];
      assert( memory[i] >= 0 );
    }

    dp[0] = 0;
    rep(used,(1<<n))if(dp[used]!=IINF){
      rep(chose,(1<<n))if( !(used&chose) && ( cost[chose] <= memory[used] ) ){
	dp[used|chose] = min(dp[used|chose],dp[used]+1);
      }
    }
    if( dp[(1<<n)-1] == IINF ) puts("Impossible");
    else cout << dp[(1<<n)-1] << endl;
  }
  return 0;
}
accuracy: 1
time_ms: 7090
memory_kb: 1364
final_rank: 14

code_snippet: #include<cstdio>
#include<cstring>
#include<algorithm>

#define rep(i,n) for(int i=0;i<(n);i++)

using namespace std;

const int INF=1<<29;

int n,sz1[14],sz2[14];
int sum1[1<<14],sum2[1<<14];

int dp[1<<14];
int dfs(int S,int rem){
	if(S==0) return 0;

	if(dp[S]!=-1) return dp[S];

	int res=INF;
	for(int T=S;T;T=(T-1)&S) if(sum2[T]<=rem) {
		res=min(res,dfs(S-T,rem-sum2[T]+sum1[T])+1);
	}
	return dp[S]=res;
}

int main(){
	for(int m;scanf("%d%d",&n,&m),n;){
		rep(i,n) scanf("%d%d",sz1+i,sz2+i);

		rep(S,1<<n){
			sum1[S]=sum2[S]=0;
			rep(i,n) if(S>>i&1) {
				sum1[S]+=sz1[i];
				sum2[S]+=sz2[i];
			}
		}

		memset(dp,-1,sizeof dp);
		int ans=dfs((1<<n)-1,m);
		if(ans<INF) printf("%d\n",ans); else puts("Impossible");
	}

	return 0;
}
accuracy: 1
time_ms: 440
memory_kb: 1240
final_rank: 4

code_snippet: #include <cstdio>
#include <iostream>
#include <sstream>
#include <iomanip>
#include <algorithm>
#include <cmath>
#include <string>
#include <vector>
#include <list>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <bitset>
#include <numeric>
#include <climits>
#include <cfloat>
using namespace std;

const int INF = INT_MAX / 2;

template <size_t T>
bool prevSubset(bitset<T>& bs, const bitset<T>& mask)
{
    if(bs.none())
        return false;
    bs = bs.to_ulong() - 1ull;
    bs &= mask;
    return true;
}

int main()
{
    for(;;){
        int n, m;
        cin >> n >> m;
        if(n == 0)
            return 0;

        vector<int> a(n), b(n);
        for(int i=0; i<n; ++i)
            cin >> a[i] >> b[i];

        vector<int> use(1<<n, 0);
        for(int i=0; i<(1<<n); ++i){
            bitset<14> bs(i);
            for(int j=0; j<n; ++j){
                if(bs[j])
                    use[i] += b[j];
            }
        }

        vector<int> dp(1<<n, INF);
        dp[(1<<n)-1] = 0;
        for(int i=(1<<n)-1; i>=0; --i){
            bitset<14> mask(i);
            int space = m;
            for(int j=0; j<n; ++j){
                if(!mask[j])
                    space += a[j] - b[j];
            }

            bitset<14> bs(i);
            do{
                if(use[bs.to_ulong()] <= space){
                    bitset<14> bs2 = mask & ~bs;
                    dp[bs2.to_ulong()] = min(dp[bs2.to_ulong()], dp[i] + 1);
                }
            }while(prevSubset(bs, mask));
        }

        if(dp[0] == INF)
            cout << "Impossible" << endl;
        else
            cout << dp[0] << endl;
    }
}
accuracy: 1
time_ms: 440
memory_kb: 1328
final_rank: 5

code_snippet: #include <iostream>
#include <cstring>
#include <climits>
using namespace std;

typedef pair<int,int> P;

int n, m;
int a[14], b[14];
P dp[1 << 14];

void dfs(int idx, int bit, int rem, int sum, int now){
  if(idx == n){
    rem += sum;
    if(dp[now].first + 1 < dp[bit].first ||
       dp[now].first + 1 == dp[bit].first && dp[bit].second < rem){
      dp[bit] = P(dp[now].first + 1, rem);
    }
    return;
  }

  dfs(idx + 1, bit, rem, sum, now);

  if(!(bit & (1 << idx)) && b[idx] <= rem){
    dfs(idx + 1, bit | (1 << idx), rem - b[idx], sum + a[idx], now);
  }
}

void solve(){
  int to = 1 << n;

  for(int i = 0; i < to; i++){
    dp[i] = P(INT_MAX, INT_MAX);
  }

  dp[0] = P(0, m);

  for(int i = 0; i < to; i++){
    if(dp[i] == P(INT_MAX, INT_MAX)) continue;
    dfs(0, i, dp[i].second, 0, i);
  }

  int ans = dp[to - 1].first;

  if(ans == INT_MAX){
    cout << "Impossible\n";
  }
  else{
    cout << ans << endl;
  }
}

int main(){
  while(cin >> n >> m, n || m){
    for(int i = 0; i < n; i++){
      cin >> a[i] >> b[i];
    }
    solve();
  }
}
accuracy: 1
time_ms: 2000
memory_kb: 996
final_rank: 7

code_snippet: #include <iostream>
#include <algorithm>
using namespace std;

const int MAX_N = 15;
const int INF = 1<<28;

int main() {
  int n, m;
  int b[MAX_N], a[MAX_N];
  int dp[1<<MAX_N], space[1<<MAX_N], need[1<<MAX_N];
  while(cin >> n >> m && (n|m)) {
    for(int i = 0; i < n; ++i) {
      cin >> b[i] >> a[i];
    }

    for(int s = 0; s < (1<<n); ++s) {
      space[s] = m;
      need[s] = 0;
      for(int i = 0; i < n; ++i) {
        if(s & (1<<i)) {
          space[s] += b[i] - a[i];
          need[s] += a[i];
        }
      }
    }

    fill(dp,dp+(1<<n),INF);
    dp[0] = 0;
    for(int s = 0; s < (1<<n); ++s) {
      int rs = s ^ ((1<<n)-1);
      int sub = rs;
      do {
        sub = (sub-1) & rs;
        if(space[s] >= need[sub]) {
          dp[s|sub] = min(dp[s|sub], dp[s] + 1);
        }
      } while(sub != rs);
    }

    if(dp[(1<<n)-1] == INF)
      cout << "Impossible" << endl;
    else
      cout << dp[(1<<n)-1] << endl;

  }
  return 0;
}
accuracy: 1
time_ms: 610
memory_kb: 1068
final_rank: 2

code_snippet: #include <iostream>
#include <algorithm>
#include <vector>
#include <cstring>
#include <cstdio>

using namespace std;

int n,m;
int bs[20];
int as[20];
int dp[1<<14];
int combSum[1<<14];
const int INF=1000000000;

int main(){
  int tmp[20]; 
  while(scanf("%d %d",&n,&m)&&(n|m)){
    memset(combSum,0,sizeof(combSum));
    for(int i=0;i<n;i++)
      scanf("%d %d",bs+i,as+i);
    for(int mask=1;mask<(1<<n);mask++)
      for(int i=0;i<n;i++)
	if((mask>>i)&1)combSum[mask]+=as[i];
    for(int mask=(1<<n)-1;mask>=0;mask--){
      int res=INF;
      if(mask==(1<<n)-1)res=0;
      else{
    	int cemp=m;
    	int sz=0;
    	for(int i=0;i<n;i++){
    	  if((mask>>i)&1)cemp+=bs[i]-as[i];
    	  else tmp[sz++]=i;
    	}
	int revMask=(~mask)&((1<<n)-1);
	int sub=revMask;
	do{
	  int nmask=mask|(sub);
	  int sum=combSum[sub];
	  if(nmask!=mask&&sum<=cemp)
	    res=min(res,dp[nmask]+1);
	  sub=(sub-1)&revMask;
	}while(sub!=revMask);
      }
      dp[mask]=res;
    }
    if(dp[0]==INF)printf("Impossible\n");
    else printf("%d\n",dp[0]);
  }

  return 0;
}
accuracy: 1
time_ms: 720
memory_kb: 1012
final_rank: 1

code_snippet: #include<iostream>
#include<algorithm>
using namespace std;
#define REP(i,b,n) for(int i=b;i<n;i++)
#define rep(i,n)   REP(i,0,n)

const int N = 14;
const int inf = (1 << 20);

int asum[1<<N],bsum[1<<N];
int dp[1<<N];

int cut;

int search(int n,int state,int r,int cost){
  if (dp[state] != -1){
    cut=min(cut,cost+dp[state]);
    return dp[state];
  }
  if (state == (1<<n)-1){
    cut=min(cut,cost);
    return 0;
  }

  if (cost >= cut)return inf-1;
  
  int ret = inf;
  int cnt=0;
  int cpy[n];
  /*  
  rep(i,n)if ( (state&(1<<i)) == 0)cpy[cnt++]=i;

  REP(i,1,1<<cnt){
    int next=0;
    rep(k,cnt)if ( (i&(1<<k)) != 0)next|=(1<<cpy[k])
;    if (r+asum[state]-bsum[state] >= bsum[next]){
      ret=min(ret,search(n,state|next,r)+1);
    }
  }
  */
  REP(i,1,1<<n){
    if (i&state)continue;
    int next=i;
    if (r+asum[state]-bsum[state] >= bsum[next]){
      ret=min(ret,search(n,state|next,r,cost+1)+1);
    }    
  }

  return dp[state] = ret;
}

main(){
  int n,r;
  while(cin>>n>>r){
    if (n == 0 && r == 0)break;
    int be[n],af[n];
    rep(i,n)cin>>be[i]>>af[i];


    rep(i,(1<<n)){
      dp[i]=-1;
      asum[i]=0;
      bsum[i]=0;
      rep(j,n)if ((i&(1<<j)) != 0)asum[i]+=be[j],bsum[i]+=af[j];
    }
  
    //    int ans = solve(n,r,be,af);
    cut = inf;
    int ans = search(n,0,r,0);
    if (ans == inf)cout << "Impossible"<<endl;
    else cout << ans << endl;
  }
}


/*
int solve(int n,int r,int *be,int *af){
  static int asum[1<<N],bsum[1<<N];
  static int dp[1<<N];
  static int cpy[N];

  rep(i,(1<<n)){
    dp[i]=inf;
    asum[i]=0;
    bsum[i]=0;
    rep(j,n)if ((i&(1<<j)) != 0)asum[i]+=be[j],bsum[i]+=af[j];
  }
  
  dp[0]=0;

  rep(i,1<<n){
    if (dp[i] == inf)continue;
    int cnt =0;
    rep(j,n)if ((i&(1<<j)) == 0 )cpy[cnt++]=j;
    rep(j,(1<<cnt)){
      int next=0;
      rep(k,cnt)if ( (j&(1<<k)) == 0)next|=(1<<cpy[k]);
      if (r+asum[i]-bsum[i] >= bsum[next]){
	dp[i|next]=min(dp[i|next],dp[i]+1);
      }
    }
  }
  return dp[(1<<n)-1];
}
*/
accuracy: 1
time_ms: 7280
memory_kb: 1056
final_rank: 13

code_snippet: #include<iostream>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define MAX 14
#define SMAX (1<<14)
#define QMAX 17000

class State{
    public:
    int used, n, size, cost, remain;
    State( int n=0, int size=0):n(n), size(size){
	used = cost = 0;
	remain = n;
    }
};

int n, m;
pair<int, int> F[MAX];

void rec(State &u, State &v, int pos, int fsize, queue<State> &Q, bool visited[SMAX]){
    if ( pos == n ){
	v.size += fsize;
	if ( !visited[v.used] ){
	    visited[v.used] = true;
	    v.cost = u.cost + 1;
	    Q.push(v);
	}
	return;
    }

    if ( !(v.used & (1<<pos)) && v.size >= F[pos].second) {
	State vv = v;
	vv.used |= (1<<pos);
	vv.remain--;
	vv.size -= F[pos].second;
	rec(u, vv, pos+1, fsize + F[pos].first, Q, visited );
    }

    rec(u, v, pos+1, fsize, Q, visited);
}

int bfs(){
    State s = State(n, m);
    queue<State> Q;
    bool visited[SMAX];
    Q.push(s);

    for ( int i = 0; i < (1<<n); i++ ) visited[i] = false;
    visited[s.used] = true;

    State u, v;
        while( !Q.empty() ){
	u = Q.front(); Q.pop();
	if ( u.remain == 0 ) return u.cost;
	rec(u, u, 0, 0, Q, visited);
	
    }

    return -1;
}

void compute(){
    int cost = bfs();
    if ( cost < 0 ) cout << "Impossible" << endl;
    else cout << cost << endl;
}

main(){
    while( cin >> n >> m && n ){
	for ( int i = 0; i < n; i++ ) cin >> F[i].first >> F[i].second;
	compute();
    }
}
accuracy: 1
time_ms: 2070
memory_kb: 1224
final_rank: 8

code_snippet: #include<iostream>
#include<queue>
#include<map>
#include<set>
#include<algorithm>
using namespace std;
#define MAX 14
#define SMAX (1<<14)
#define QMAX 17000

class State{
    public:
    int used, n, size, cost, remain;
    State( int n=0, int size=0):n(n), size(size){
	used = 0;
	cost = 0;
	remain = n;
    }
    State( int n, int size, int cost, int remain): n(n), size(size), cost(cost), remain(remain){}

    bool operator < ( const State &s) const{
	return used < s.used;
    }
};

int n, m;
pair<int, int> F[MAX];
int head, tail;

void rec(State &u, State &v, int pos, int fsize, State Q[QMAX], set<State> &visited){
    if ( pos == n ){
	v.size += fsize;

	if ( visited.insert(v).second ){
	    //	if ( !visited[v] ){
	    //	    visited[v] = true;
	    v.cost = u.cost + 1;
	    //Q.push(v);
	    Q[tail++] = v;
	}
	return;
    }

    if ( !(v.used & (1<<pos)) && v.size >= F[pos].second) {
	State vv = v;
	vv.used |= (1<<pos);
	vv.remain--;
	vv.size -= F[pos].second;
	rec(u, vv, pos+1, fsize + F[pos].first, Q, visited );
    }

    rec(u, v, pos+1, fsize, Q, visited);
}

int bfs(){
    State s = State(n, m);
    //queue<State> Q;
    static State Q[QMAX];
    head = tail = 0;
    //    map<State, bool> visited;
    set<State> visited;

    //Q.push(s);
    Q[tail++] = s;
    //visited[s] = true;
    visited.insert(s);

    State u, v;
    //    while( !Q.empty() ){
    while( head < tail ){
	//u = Q.front(); Q.pop();
	u = Q[head++];
	if ( u.remain == 0 ) return u.cost;
	rec(u, u, 0, 0, Q, visited);
	
    }

    return -1;
}

void compute(){
    int cost = bfs();
    if ( cost < 0 ) cout << "Impossible" << endl;
    else cout << cost << endl;
}

main(){
    while( cin >> n >> m && n ){
	for ( int i = 0; i < n; i++ ) cin >> F[i].first >> F[i].second;
	compute();
    }
}
accuracy: 1
time_ms: 7050
memory_kb: 1884
final_rank: 16