Problem:
D - Medical Inspection
Problem Statement
The government has declared a state of emergency due to the MOFU syndrome epidemic in your country. Persons in the country suffer from MOFU syndrome and cannot get out of bed in the morning. You are a programmer working for the Department of Health.  You have to take prompt measures.
The country consists of
n
islands numbered from 1 to
n
and there are ocean liners between some pair of islands.
The Department of Health decided to establish the quarantine stations in some islands and restrict an infected person's moves to prevent the expansion of the epidemic.
To carry out this plan, there must not be any liner  such that there is no quarantine station in both the source and the destination of the liner.
The problem is  the department can build at most
K
quarantine stations due to the lack of budget.
Your task is to calculate whether this objective is possible or not.
And if it is possible, you must calculate the minimum required number of quarantine stations.
Input
The test case starts with a line containing three integers
N (2 \leq N \leq 3{,}000)
,
M (1 \leq M \leq 30{,}000)
and
K (1 \leq K \leq 32)
.
Each  line in the next
M
lines contains two integers
a_i (1 \leq a_i \leq N)
and
b_i (1 \leq b_i \leq N)
. This represents
i
-th ocean liner connects island
a_i
and
b_i
.
You may assume
a_i \neq b_i
for all
i
, and there are at most one ocean liner between all the pairs of islands.
Output
If there is no way to build quarantine stations that satisfies the objective, print "Impossible" (without quotes). Otherwise, print the minimum required number of quarantine stations.
Sample Input 1
3 3 2
1 2
2 3
3 1
Output for the Sample Input 1
2
Sample Input 2
3 3 1
1 2
2 3
3 1
Output for the Sample Input 2
Impossible
Sample Input 3
7 6 5
1 3
2 4
3 5
4 6
5 7
6 2
Output for the Sample Input 3
4
Sample Input 4
10 10 10
1 2
1 3
1 4
1 5
2 3
2 4
2 5
3 4
3 5
4 5
Output for the Sample Input 4
4

Submitted solutions:

code_snippet: #include <map>
#include <set>
#include <cmath>
#include <stack>
#include <queue>
#include <string>
#include <vector>
#include <bitset>
#include <fstream>
#include <sstream>
#include <stdio.h>
#include <ctype.h>
#include <string.h>
#include <iostream>
#include <algorithm>

using namespace std;
#define li        long long int
#define rep(i,to) for(li i=0;i<((li)(to));++i)
#define pb        push_back
#define sz(v)     ((li)(v).size())
#define bit(n)    (1ll<<(li)(n))
#define all(vec)  (vec).begin(),(vec).end()
#define each(i,c) for(__typeof((c).begin()) i=(c).begin();i!=(c).end();i++)
#define MP        make_pair
#define F         first
#define S         second
 
 
#define MAX 3050
li n, m, k;
 
li used[MAX];
vector<li> E[MAX];
 
vector<li> checked[MAX];
 
li recur(li cnt, li best);
 
li run(li cnt, li best)
{
	checked[cnt].clear();
	li res = recur(cnt, best);
	rep(i, sz(checked[cnt])) used[checked[cnt][i]] = false;
	return res;
}
 
li recur(li cnt, li best)
{
	if(best <= cnt) return best;
	
	rep(i, n)if(!used[i]){
		li t = 0;
		rep(j, sz(E[i]))if(!used[E[i][j]]) t++;
		if(t == 0){
			checked[cnt].pb(i);
			used[i] = true;
		}
	}
	
	rep(i, n)if(!used[i]){
		li t = 0;
		rep(j, sz(E[i]))if(!used[E[i][j]]) t++;
		if(t != 1) continue;
		rep(j, sz(E[i]))if(!used[E[i][j]]){
			li use = E[i][j];
			checked[cnt].pb(use);
			used[use] = true;
			return run(cnt + 1, best);
		}
	}
	
	rep(i, n)if(!used[i]){
		li t = 0;
		rep(j, sz(E[i]))if(!used[E[i][j]]) t++;
		if(t <= 1) continue;
		
		li res = best;
		{
			used[i] = true;
			res = min(res, run(cnt + 1, best));
			used[i] = false;
		}
		{
			li use = 0;
			rep(j, sz(E[i]))if(!used[E[i][j]]){
				use++;
				checked[cnt].pb(E[i][j]);
				used[E[i][j]] = true;
			}
			res = min(res, run(cnt + use, best));
		}
		return res;
	}
	
	return min(cnt, best);
}
 
 
int main(){
	li k;
	cin >> n >> m >> k;
	rep(i, m){
		li a, b;
		cin >> a >> b; a--; b--;
		E[a].pb(b);
		E[b].pb(a);
	}
	
	li ans = run(0, k + 1);
	if(ans == k + 1) cout << "Impossible" << endl;
	else cout << ans << endl;
	return 0;
}
accuracy: 1
time_ms: 20
memory_kb: 4436
final_rank: 3

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back
#define pf push_front
#define pb2 pop_back
#define pf2 pop_front
#define pq priority_queue
#define haha printf("hahaha\n")

const int INF = 1e9+7;
const ll INFLL = 1e17;
const double EPS = 1e-5;

using namespace std;

vector<int> adj[3005],adj2[3005];
pii edge[30005];
int flag[3005],deg[3005];
int n,m,d,rem;


int brute(int i,int sisa){
	
	int ret = -INF;
	if(sisa<0)return -INF;
	rep(k,i,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		if(deg[a]<deg[b])swap(a,b);
		vector<int>reset;
		//use a
		flag[a] = 1;
		rep(l,0,adj[a].size()){
			int next = adj[a][l];
			if(!flag[next]){
				deg[next]--;
				reset.pb(next);
			}
		}
		ret = max(ret,brute(i+1,sisa-1));
		
		//not use a
		flag[a] = 0;
		while(reset.size())deg[reset.back()]++,reset.pb2();
		
		rep(l,0,adj[a].size()){
			int next  = adj[a][l];
			if(flag[next]==0){
				sisa--;
				flag[next] = 1;
				reset.pb(next);
				rep(j,0,adj[next].size())deg[adj[next][j]]--;
			}
		}	
		ret = max(ret,brute(i+1,sisa));
		while(reset.size()){
			int now = reset.back();
			flag[now] = 0;
			rep(j,0,adj[now].size())deg[adj[now][j]]++;
			reset.pb2();
		}
		
		return ret;
	}
	
	return sisa;
}
int main(){
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		
		adj[a].pb(b);
		adj[b].pb(a);
		edge[k] = mp(a,b);
		deg[a]++;deg[b]++;
	}
	
	int bisa = 1;
	rem = d;
	while(bisa){
		bisa = 0;
		rep(k,0,n)if(!flag[k] && deg[k]>rem){
			flag[k] = 1;
			rem--;
			rep(i,0,adj[k].size())deg[adj[k][i]]--;
			bisa = 1;
		}
		if(rem<0)break;
	}
	if(rem<0){
		printf("Impossible\n");
		return 0;
	}
	rep(k,0,n){
		vector<int> tmp;
		rep(i,0,adj[k].size()){
			int next = adj[k][i];
			if(flag[next])continue;
			tmp.pb(next);
		}
		adj[k] = tmp;
	}
	int M = 0;
	rep(k,0,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		edge[M++] = edge[k];
	//	printf("%d %d\n",edge[M-1].fi,edge[M-1].se);
	}
	m = M;
	if(m>d*d){
		printf("Impossible\n");
		return 0;
	}
	
	int tmp = brute(0,rem);
	if(tmp<0)printf("Impossible\n");
	else printf("%d\n",d-tmp);
	return 0;
}
accuracy: 1
time_ms: 6020
memory_kb: 4412
final_rank: 14

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back
#define pf push_front
#define pb2 pop_back
#define pf2 pop_front
#define pq priority_queue
#define haha printf("hahaha\n")

const int INF = 1e9+7;
const ll INFLL = 1e17;
const double EPS = 1e-5;

using namespace std;

vector<int> adj[3005],adj2[3005];
pii edge[30005];
int flag[3005],deg[3005];
int n,m,d,rem;


int brute(int i,int sisa){
	
	int ret = -INF;
	if(sisa<0)return -INF;
	rep(k,i,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		if(deg[a]<deg[b])swap(a,b);
		vector<int>reset;
		//use a
		flag[a] = 1;
		rep(l,0,adj[a].size()){
			int next = adj[a][l];
			if(!flag[next]){
				deg[next]--;
				reset.pb(next);
			}
		}
		ret = max(ret,brute(i+1,sisa-1));
		
		//not use a
		flag[a] = 0;
		while(reset.size())deg[reset.back()]++,reset.pb2();
		
		rep(l,0,adj[a].size()){
			int next  = adj[a][l];
			if(flag[next]==0){
				sisa--;
				flag[next] = 1;
				reset.pb(next);
				rep(j,0,adj[next].size())deg[adj[next][j]]--;
			}
		}	
		ret = max(ret,brute(i+1,sisa));
		while(reset.size()){
			int now = reset.back();
			flag[now] = 0;
			rep(j,0,adj[now].size())deg[adj[now][j]]++;
			reset.pb2();
		}
		
		return ret;
	}
	
	return sisa;
}
int main(){
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		
		adj[a].pb(b);
		adj[b].pb(a);
		edge[k] = mp(a,b);
		deg[a]++;deg[b]++;
	}
	
	int bisa = 1;
	rem = d;
	while(bisa){
		bisa = 0;
		rep(k,0,n)if(!flag[k] && deg[k]>rem){
			flag[k] = 1;
			rem--;
			rep(i,0,adj[k].size())deg[adj[k][i]]--;
			bisa = 1;
		}
		if(rem<0)break;
	}
	if(rem<0){
		printf("Impossible\n");
		return 0;
	}
	rep(k,0,n){
		vector<int> tmp;
		rep(i,0,adj[k].size()){
			int next = adj[k][i];
			if(flag[next])continue;
			tmp.pb(next);
		}
		adj[k] = tmp;
		deg[k] = adj[k].size();
	}
	int M = 0;
	rep(k,0,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		edge[M++] = edge[k];
	//	printf("%d %d\n",edge[M-1].fi,edge[M-1].se);
	}
	m = M;
	if(m>d*d){
		printf("Impossible\n");
		return 0;
	}
	
	int tmp = brute(0,rem);
	if(tmp<0)printf("Impossible\n");
	else printf("%d\n",d-tmp);
	return 0;
}
accuracy: 1
time_ms: 5290
memory_kb: 4372
final_rank: 9

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back
#define pf push_front
#define pb2 pop_back
#define pf2 pop_front
#define pq priority_queue
#define haha printf("hahaha\n")

const int INF = 1e9+7;
const ll INFLL = 1e17;
const double EPS = 1e-5;

using namespace std;

vector<int> adj[3005],adj2[3005];
pii edge[30005];
int flag[3005],deg[3005];
int n,m,d,rem;


int brute(int i,int sisa){
	
	int ret = -INF;
	if(sisa<0)return -INF;
	rep(k,i,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		if(deg[a]<deg[b])swap(a,b);
		vector<int>reset;
		//use a
		flag[a] = 1;
		rep(l,0,adj[a].size()){
			int next = adj[a][l];
			if(!flag[next]){
				deg[next]--;
				reset.pb(next);
			}
		}
		ret = max(ret,brute(i+1,sisa-1));
		
		//not use a
		flag[a] = 0;
		while(reset.size())deg[reset.back()]++,reset.pb2();
		
		rep(l,0,adj[a].size()){
			int next  = adj[a][l];
			if(flag[next]==0){
				sisa--;
				flag[next] = 1;
				reset.pb(next);
				rep(j,0,adj[next].size())deg[adj[next][j]]--;
			}
		}	
		ret = max(ret,brute(i+1,sisa));
		while(reset.size()){
			int now = reset.back();
			flag[now] = 0;
			rep(j,0,adj[now].size())deg[adj[now][j]]++;
			reset.pb2();
		}
		
		return ret;
	}
	
	return sisa;
}
int main(){
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		
		adj[a].pb(b);
		adj[b].pb(a);
		edge[k] = mp(a,b);
		deg[a]++;deg[b]++;
	}
	
	int bisa = 1;
	rem = d;
	while(bisa){
		bisa = 0;
		rep(k,0,n)if(!flag[k] && deg[k]>rem){
			flag[k] = 1;
			rem--;
			deg[k] = 0;
			rep(i,0,adj[k].size())deg[adj[k][i]]--;
			bisa = 1;
		}
		if(rem<0)break;
	}
	if(rem<0){
		printf("Impossible\n");
		return 0;
	}
	rep(k,0,n){
		vector<int> tmp;
		rep(i,0,adj[k].size()){
			int next = adj[k][i];
			if(flag[next])continue;
			tmp.pb(next);
		}
		adj[k] = tmp;
		deg[k] = adj[k].size();
	}
	int M = 0;
	rep(k,0,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		edge[M++] = edge[k];
	//	printf("%d %d\n",edge[M-1].fi,edge[M-1].se);
	}
	m = M;
	if(m>d*d){
		printf("Impossible\n");
		return 0;
	}
	
	int tmp = brute(0,rem);
	if(tmp<0)printf("Impossible\n");
	else printf("%d\n",d-tmp);
	return 0;
}
accuracy: 1
time_ms: 5660
memory_kb: 4340
final_rank: 13

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back
#define pf push_front
#define pb2 pop_back
#define pf2 pop_front
#define pq priority_queue
#define haha printf("hahaha\n")

const int INF = 1e9+7;
const ll INFLL = 1e17;
const double EPS = 1e-5;

using namespace std;

vector<int> adj[3005],adj2[3005];
pii edge[30005];
int flag[3005],deg[3005];
int n,m,d,rem;

int bts = -1;
int brute(int i,int sisa){
	int ret = -1;
	if(sisa<bts)return -1;
	rep(k,i,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		if(deg[a]<deg[b])swap(a,b);
		vector<int>reset;
		//use a
		flag[a] = 1;
		rep(l,0,adj[a].size()){
			int next = adj[a][l];
			if(!flag[next]){
				deg[next]--;
				reset.pb(next);
			}
		}
		ret = max(ret,brute(i+1,sisa-1));
		
		//not use a
		flag[a] = 0;
		while(reset.size())deg[reset.back()]++,reset.pb2();
		
		rep(l,0,adj[a].size()){
			int next  = adj[a][l];
			if(flag[next]==0){
				sisa--;
				flag[next] = 1;
				reset.pb(next);
				rep(j,0,adj[next].size())deg[adj[next][j]]--;
			}
		}	
		ret = max(ret,brute(i+1,sisa));
		while(reset.size()){
			int now = reset.back();
			flag[now] = 0;
			rep(j,0,adj[now].size())deg[adj[now][j]]++;
			reset.pb2();
		}
		bts = max(bts,ret);
		return ret;
	}
	bts = max(bts,sisa);
	return sisa;
}
int main(){
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		
		adj[a].pb(b);
		adj[b].pb(a);
		edge[k] = mp(a,b);
		deg[a]++;deg[b]++;
	}
	
	int bisa = 1;
	rem = d;
	while(bisa){
		bisa = 0;
		rep(k,0,n)if(!flag[k] && deg[k]>rem){
			flag[k] = 1;
			rem--;
			deg[k] = 0;
			rep(i,0,adj[k].size())deg[adj[k][i]]--;
			bisa = 1;
		}
		if(rem<0)break;
	}
	if(rem<0){
		printf("Impossible\n");
		return 0;
	}
	rep(k,0,n){
		vector<int> tmp;
		rep(i,0,adj[k].size()){
			int next = adj[k][i];
			if(flag[next])continue;
			tmp.pb(next);
		}
		adj[k] = tmp;
		deg[k] = adj[k].size();
	}
	int M = 0;
	rep(k,0,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		edge[M++] = edge[k];
	//	printf("%d %d\n",edge[M-1].fi,edge[M-1].se);
	}
	m = M;
	if(m>d*d){
		printf("Impossible\n");
		return 0;
	}
	
	int tmp = brute(0,rem);
	if(tmp<0)printf("Impossible\n");
	else printf("%d\n",d-tmp);
	return 0;
}
accuracy: 1
time_ms: 5600
memory_kb: 4296
final_rank: 12

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back
#define pf push_front
#define pb2 pop_back
#define pf2 pop_front
#define pq priority_queue
#define haha printf("hahaha\n")

const int INF = 1e9+7;
const ll INFLL = 1e17;
const double EPS = 1e-5;

using namespace std;

vector<int> adj[3005],adj2[3005];
pii edge[30005];
int flag[3005],deg[3005];
int n,m,d,rem;

int bts = 0;
int brute(int i,int sisa){
	int ret = -1;
	if(sisa<bts)return -1;
	rep(k,i,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		if(deg[a]<deg[b])swap(a,b);
		vector<int>reset;
		//use a
		flag[a] = 1;
		rep(l,0,adj[a].size()){
			int next = adj[a][l];
			if(!flag[next]){
				deg[next]--;
				reset.pb(next);
			}
		}
		if(!(deg[a]<=1 && deg[b]>1))ret = max(ret,brute(i+1,sisa-1));
		
		//not use a
		flag[a] = 0;
		rep(k,0,reset.size())deg[reset[k]]++;
		reset.clear();
		
		rep(l,0,adj[a].size()){
			int next  = adj[a][l];
			if(flag[next]==0){
				sisa--;
				flag[next] = 1;
				reset.pb(next);
				rep(j,0,adj[next].size())deg[adj[next][j]]--;
			}
		}	
		if(sisa>=0 && !(deg[a]>1&&deg[b]<=1))ret = max(ret,brute(i+1,sisa));
		rep(k,0,reset.size()){
			int now = reset[k];
			flag[now] = 0;
			rep(j,0,adj[now].size())deg[adj[now][j]]++;
		}
		
		bts = max(bts,ret);
		return ret;
	}
	bts = max(bts,sisa);
	return sisa;
}
int main(){
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		
		adj[a].pb(b);
		adj[b].pb(a);
		edge[k] = mp(a,b);
		deg[a]++;deg[b]++;
	}
	
	int bisa = 1;
	rem = d;
	while(bisa){
		bisa = 0;
		rep(k,0,n)if(!flag[k] && deg[k]>rem){
			flag[k] = 1;
			rem--;
			deg[k] = 0;
			rep(i,0,adj[k].size())deg[adj[k][i]]--;
			bisa = 1;
		}
		if(rem<0)break;
	}
	if(rem<0){
		printf("Impossible\n");
		return 0;
	}
	rep(k,0,n){
		vector<int> tmp;
		rep(i,0,adj[k].size()){
			int next = adj[k][i];
			if(flag[next] || flag[k])continue;
			tmp.pb(next);
		}
		adj[k] = tmp;
		deg[k] = adj[k].size();
	}
	int M = 0;
	rep(k,0,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		edge[M++] = edge[k];
	//	printf("%d %d\n",edge[M-1].fi,edge[M-1].se);
	}
	m = M;
	if(m>d*d){
		printf("Impossible\n");
		return 0;
	}
	//haha;
	int tmp = brute(0,rem);
	if(tmp<0)printf("Impossible\n");
	else printf("%d\n",d-tmp);
	return 0;
}
accuracy: 1
time_ms: 5520
memory_kb: 4388
final_rank: 11

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back
#define pf push_front
#define haha printf("hahaha\n")


using namespace std;

vector<int> adj[3005],adj2[3005];
pii edge[30005];
int flag[3005],deg[3005];
int n,m,d,rem;

int bts = 0;
int brute(int i,int sisa){
	int ret = -1;
	if(sisa<bts)return -1;
	rep(k,i,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		if(deg[a]<deg[b])swap(a,b);
		vector<int>reset;
		//use a
		flag[a] = 1;
		rep(l,0,adj[a].size()){
			int next = adj[a][l];
			if(!flag[next]){
				deg[next]--;
				reset.pb(next);
			}
		}
		if(!(deg[a]<=1 && deg[b]>1))ret = max(ret,brute(i+1,sisa-1));
		
		//not use a
		flag[a] = 0;
		rep(k,0,reset.size())deg[reset[k]]++;
		reset.clear();
		
		rep(l,0,adj[a].size()){
			int next  = adj[a][l];
			if(flag[next]==0){
				sisa--;
				flag[next] = 1;
				reset.pb(next);
				rep(j,0,adj[next].size())deg[adj[next][j]]--;
			}
		}	
		if(sisa>=0 && !(deg[a]>1&&deg[b]<=1))ret = max(ret,brute(i+1,sisa));
		rep(k,0,reset.size()){
			int now = reset[k];
			flag[now] = 0;
			rep(j,0,adj[now].size())deg[adj[now][j]]++;
		}
		
		bts = max(bts,ret);
		return ret;
	}
	bts = max(bts,sisa);
	return sisa;
}
int main(){
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);a--;b--;
		
		adj[a].pb(b);
		adj[b].pb(a);
		edge[k] = mp(a,b);
		deg[a]++;deg[b]++;
	}
	
	int bisa = 1;
	rem = d;
	while(bisa){
		bisa = 0;
		rep(k,0,n)if(!flag[k] && deg[k]>rem){
			flag[k] = 1;
			rem--;
			deg[k] = 0;
			rep(i,0,adj[k].size())deg[adj[k][i]]--;
			bisa = 1;
		}
		if(rem<0)break;
	}
	if(rem<0){
		printf("Impossible\n");
		return 0;
	}
	rep(k,0,n){
		vector<int> tmp;
		rep(i,0,adj[k].size()){
			int next = adj[k][i];
			if(flag[next] || flag[k])continue;
			tmp.pb(next);
		}
		adj[k] = tmp;
		deg[k] = adj[k].size();
	}
	int M = 0;
	rep(k,0,m){
		int a = edge[k].fi;
		int b = edge[k].se;
		if(flag[a] || flag[b])continue;
		edge[M++] = edge[k];
	//	printf("%d %d\n",edge[M-1].fi,edge[M-1].se);
	}
	m = M;
	if(m>d*d){
		printf("Impossible\n");
		return 0;
	}
	//haha;
	int tmp = brute(0,rem);
	if(tmp<0)printf("Impossible\n");
	else printf("%d\n",d-tmp);
	return 0;
}
accuracy: 1
time_ms: 5330
memory_kb: 3712
final_rank: 10

code_snippet: #include <bits/stdc++.h>
#define cincout
#define min(a,b) ((a) < (b) ? (a) : (b))
#define max(a,b) ((a) > (b) ? (a) : (b))
#define abs(x) ((x) < 0 ? -(x) : (x))
using namespace std;
typedef pair <int, int> pii;
int n,m,k,ans,tmppos,fixuse,sz;
bool cov[3005],found;
int a,b,tmp,edgs;
int deg[3005];
pair<int, int> edg[30005];
vector <int> adjlist[3005];
vector <pii> edglist;
priority_queue <pii, vector <pii>, greater <pii> > pq;

int get_deg(int u) {
	int ret=0;
	for (int i=0;i<adjlist[u].size();++i)
		if (!cov[adjlist[u][i]]) ++ret;
	return ret;
}

void rek(int tmp_ans) {
	//cout << tmp_ans << '\n';
	if (tmp_ans > k) return;
	if (tmp_ans > ans) return;
	bool ok=true;
	vector <int> dat;
	for (int i=1;i<=n;++i) {
		if (cov[i] || ((deg[i] = get_deg(i)) == 0)) continue;
		else {
			ok=false;
			if (deg[i] == 1) {
				//cout << "take " << i << " deg 1\n";
				int neg;
				for (int j=0;j<adjlist[i].size();++j) {
					if (!cov[adjlist[i][j]]) {
						neg=adjlist[i][j];
						break;
					}
				}
				cov[neg]=true;
				rek(tmp_ans+1);
				cov[neg]=false;
				return;
			}
		}
	}
	for (int i=1;i<=n;++i) {
		if (cov[i] || ((deg[i]=get_deg(i)) == 0)) continue;
		else {
			//cout << "take " << i << '\n';
			ok=false;
			cov[i]=true;
			rek(tmp_ans+1);
			cov[i]=false;
			for (int j=0;j<adjlist[i].size();++j) {
				if (!cov[adjlist[i][j]]) dat.push_back(adjlist[i][j]);
			}
			for (int j=0;j<dat.size();++j) cov[j]=true;
			rek(tmp_ans+dat.size());
			//for (int j=0;j<dat.size();++j) cov[j]=false;
			return;
		}
	}
	if (ok) {
		//found=true;
		ans=min(ans,tmp_ans);
		return;
	}
}

int main() {
	#ifdef cincout
		cin.sync_with_stdio(0);
		cin.tie(0);
	#endif
	cin >> n >> m >> k;
	fixuse=0;
	found=false;
	ans=1000000;
	edgs=m;
	for (int i=0;i<m;++i) {
		cin >> a >> b;
		edglist.push_back(make_pair(a,b));
		edglist.push_back(make_pair(b,a));
		adjlist[a].push_back(b);
		adjlist[b].push_back(a);
		++deg[a]; ++deg[b];
	}
	sz=edglist.size();
	//cout << "ok\n";
	rek(0);
	//cout << "FIX " << fixuse << '\n';
	if (ans>k) cout << "Impossible\n";
	else cout << ans << '\n';
	return 0;
}
accuracy: 0.9251336898395722
time_ms: 30
memory_kb: 3916
final_rank: 18

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

#define pii pair<int,int>
#define fi first
#define se second
#define mp make_pair
#define ll long long
#define line printf("\n")
#define rep(a,b,c) for(int a= (int)b;a<(int)c;a++)
#define repd(a,b,c) for(int a=(int)b;a>=c;a--)
#define pb push_back()
#define pf push_front()
#define pb2 pop_back()
#define pf2 pop_front()

const int INF = 1e9+7;
const ll INFLL = 1e17;
const double EPS = 1e-5;

using namespace std;

set<int> adj[3005];
int main(){
	int n,m,d;
	scanf("%d%d%d",&n,&m,&d);
	
	rep(k,0,m){
		int a,b;
		scanf("%d%d",&a,&b);
		adj[a].insert(b);
		adj[b].insert(a);
	}
	
	int bisa,ret = 0;
	while(1){
		pii tmp = mp(-INF,0);
		bisa = 0;
		rep(k,1,n+1){
			if(adj[k].size()){
				bisa = 1;
				tmp = max(tmp,mp((int)adj[k].size(),k));
			}
		}
		if(!bisa)break;
		set<int>::iterator it;
		for(it = adj[tmp.se].begin();it!=adj[tmp.se].end();++it){
			int next = *it;
			adj[next].erase(tmp.se);
		}
		adj[tmp.se].clear();
		ret++;
	}
	
	
	if(ret<=d)printf("%d\n",ret);
	else printf("Impossible\n");
	
	return 0;
}
accuracy: 0.9144385026737968
time_ms: 10
memory_kb: 4324
final_rank: 19

code_snippet: #include <stdio.h>
#include <string.h>
#include <iostream>
#include <algorithm>
#define maxn 3009
using namespace std;
int map[maxn][maxn];
int num[maxn];
struct asdf
{
    int num;
    int siz;
}nn[maxn];
int cmp(struct asdf a,struct asdf b)
{
    return a.num<b.num;
}
int main()
{
    int i,j,n,m,k,ans=0;
    scanf("%d%d%d",&n,&m,&k);
    for(i=1;i<=m;i++)
    {
        int a,b;
        scanf("%d%d",&a,&b);
        map[a][b]=map[b][a]=1;
        nn[b].num++;nn[a].num++;
        nn[b].siz=b;nn[a].siz=a;
    }
    int flag=1;
    while(k>0)
    {
        sort(nn+1,nn+1+n,cmp);
        if(nn[n].num==0) break;
        flag=0;
        for(i=1;i<=n;i++)
        {
            if(map[i][nn[n].siz])
            {
                map[i][nn[n].siz]=0;
                map[nn[n].siz][i]=0;
                nn[n].num--;
                for(j=1;j<=n;j++)
                {
                    if(nn[j].siz==i)
                    {
                        nn[j].num--;
                        break;
                    }
                }
            }
        }
        ans++;
    }
    if(k-ans>=0)
        printf("%d\n",ans);
    else printf("Impossible\n");
    return 0;
}
accuracy: 0.8128342245989305
time_ms: 160
memory_kb: 37476
final_rank: 20

code_snippet: // AOJ #2558 Medical Inspection
// 2025.3.18

#include <bits/stdc++.h>
using namespace std;

const int MAXV = 4096;

vector<int> graph[MAXV];
int deg[MAXV];
int ans;
int dfsCallCount;
set<pair<int, int>> degreeSet;

void updateDegree(int vertex, int newDegree) {
    auto it = degreeSet.find({deg[vertex], vertex});
    if (it != degreeSet.end()) degreeSet.erase(it);
    deg[vertex] = newDegree;
    if (newDegree > 0) degreeSet.insert({newDegree, vertex});
}

int getLeaf() {
    if (degreeSet.empty()) return -1;
    auto smallestPair = *degreeSet.begin();
    if (smallestPair.first == 1) return smallestPair.second;
    return -1;
}

int getMaxDegreeVertex() {
    if (degreeSet.empty()) return -1;
    auto largestPair = *prev(degreeSet.end());
    return largestPair.second;
}

void dfs(int currentSteps);

void tryPaint(vector<int>& vertices, int currentSteps) {
    if (currentSteps >= ans) return;
    if (vertices.empty()) {
        dfs(currentSteps);
        return;
    }

    vector<int> adjacent;
    int vertex = vertices.back();
    int originalDegree = deg[vertex];
    for (int neighbor : graph[vertex]) {
        if (deg[neighbor] > 0) adjacent.push_back(neighbor);
    }
    updateDegree(vertex, 0);
    for (int neighbor : adjacent) updateDegree(neighbor, deg[neighbor] - 1);
    vertices.pop_back();

    tryPaint(vertices, currentSteps + 1);

    updateDegree(vertex, originalDegree);
    for (int neighbor : adjacent) updateDegree(neighbor, deg[neighbor] + 1);
    vertices.push_back(vertex);
}

void dfs(int currentSteps) {
    dfsCallCount++;
    if (dfsCallCount > 300) return;
    if (degreeSet.empty()) {
        ans = min(ans, currentSteps);
        return;
    }
    if (currentSteps + 1 >= ans) return;

    int leafVertex = getLeaf();
    vector<int> verticesToTry;
    if (leafVertex >= 0) {
        int neighborCandidate = 0;
        for (int neighbor : graph[leafVertex]) {
            if (deg[neighbor] > 0) neighborCandidate = neighbor;
        }
        verticesToTry.push_back(neighborCandidate);
        tryPaint(verticesToTry, currentSteps);
    }
    else {
        int maxVertex = getMaxDegreeVertex();
        verticesToTry.push_back(maxVertex);
        tryPaint(verticesToTry, currentSteps);
        verticesToTry.pop_back();
        for (int neighbor : graph[maxVertex]) {
            if (deg[neighbor] > 0) verticesToTry.push_back(neighbor);
        }
        tryPaint(verticesToTry, currentSteps);
    }
}

int main() {
    ios::sync_with_stdio(0);
    cin.tie(0);

    int N, M, K;
    cin >> N >> M >> K;

    ans = K + 1;

    for (int i = 0; i < M; i++) {
        int src, dest;
        cin >> src >> dest;
        src--; dest--;
        graph[src].push_back(dest);
        graph[dest].push_back(src);
        deg[src]++;
        deg[dest]++;
    }

    for (int i = 0; i < N; i++) {
        if (deg[i] > 0) degreeSet.insert({deg[i], i});
    }

    dfsCallCount = 0;
    dfs(0);

    if (ans == K + 1) cout << "Impossible" << endl;
    else cout << ans << endl;
    return 0;
}
accuracy: 1
time_ms: 10
memory_kb: 4160
final_rank: 2

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> N >> M >> K;
    vector<int> A(M), B(M);
    rep(i,0,M) cin >> A[i] >> B[i], A[i]--, B[i]--;
    vector<int> Deg(N,0);
    rep(i,0,M) Deg[A[i]]++, Deg[B[i]]++;
    int Cur = 0;
    vector<bool> flag(N,false);
    rep(i,0,N) {
        if (Deg[i] > K) {
            flag[i] = true;
            Cur++;
        }
    }
    if (Cur > K) {
        cout << "Impossible" << endl;
        return 0;
    }
    K -= Cur;
    vector<vector<int>> G(N);
    int EC = 0;
    rep(i,0,N) Deg[i] = 0;
    rep(i,0,M) {
        if (flag[A[i]] || flag[B[i]]) continue;
        EC++;
        Deg[A[i]]++;
        Deg[B[i]]++;
        G[A[i]].push_back(B[i]);
        G[B[i]].push_back(A[i]);
    }
    vector<int> ord;
    rep(i,0,N) if (!flag[i]) ord.push_back(i);
    int VC = ord.size();
    sort(ALL(ord),[&](int i, int j){return Deg[i] > Deg[j];});
    int ANS = inf;
    auto DFS = [&](auto self, int id, int cnt) -> void {
        if (cnt > K) return;
        if (id == VC) {
            chmin(ANS, cnt);
            return;
        }
        int pos = ord[id];
        if (flag[pos]) {
            self(self,id+1,cnt);
            return;
        }
        vector<int> NVS;
        for (int NV : G[pos]) {
            if (flag[NV]) continue;
            NVS.push_back(NV);
        }
        if (NVS.size() == 0) {
            self(self,id+1,cnt);
            return;
        }
        if (NVS.size() == 1) {
            flag[NVS[0]] = true;
            self(self,id+1,cnt+1);
            flag[NVS[0]] = false;
            return;
        }
        {
            flag[pos] = true;
            self(self,id+1,cnt+1);
            flag[pos] = false;
        }
        {
            for (int NV : NVS) {
                flag[NV] = true;
            }
            self(self,id+1,cnt+NVS.size());
            for (int NV : NVS) {
                flag[NV] = false;
            }
        }
    };
    DFS(DFS,0,0);
    if (ANS == inf) {
        cout << "Impossible" << endl;
    }
    else {
        cout << Cur + ANS << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 4228
final_rank: 5

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> N >> M >> K;
    vector<int> A(M), B(M);
    rep(i,0,M) cin >> A[i] >> B[i], A[i]--, B[i]--;
    vector<int> Deg(N,0);
    rep(i,0,M) Deg[A[i]]++, Deg[B[i]]++;
    int Cur = 0;
    vector<bool> flag(N,false);
    rep(i,0,N) {
        if (Deg[i] > K) {
            flag[i] = true;
            Cur++;
        }
    }
    if (Cur > K) {
        cout << "Impossible" << endl;
        return 0;
    }
    K -= Cur;
    vector<vector<int>> G(N);
    int EC = 0;
    rep(i,0,N) Deg[i] = 0;
    rep(i,0,M) {
        if (flag[A[i]] || flag[B[i]]) continue;
        EC++;
        Deg[A[i]]++;
        Deg[B[i]]++;
        G[A[i]].push_back(B[i]);
        G[B[i]].push_back(A[i]);
    }
    if (EC > K*K) {
        cout << "Impossible" << endl;
        return 0;
    }
    vector<int> ord;
    rep(i,0,N) if (!flag[i]) ord.push_back(i);
    int VC = ord.size();
    sort(ALL(ord),[&](int i, int j){return Deg[i] > Deg[j];});
    int ANS = inf;
    auto DFS = [&](auto self, int id, int cnt) -> void {
        if (cnt > K) return;
        if (id == VC) {
            chmin(ANS, cnt);
            return;
        }
        int pos = ord[id];
        if (flag[pos]) {
            self(self,id+1,cnt);
            return;
        }
        vector<int> NVS;
        for (int NV : G[pos]) {
            if (flag[NV]) continue;
            NVS.push_back(NV);
        }
        if (NVS.size() == 0) {
            self(self,id+1,cnt);
            return;
        }
        if (NVS.size() == 1) {
            flag[NVS[0]] = true;
            self(self,id+1,cnt+1);
            flag[NVS[0]] = false;
            return;
        }
        {
            flag[pos] = true;
            self(self,id+1,cnt+1);
            flag[pos] = false;
        }
        {
            for (int NV : NVS) {
                flag[NV] = true;
            }
            self(self,id+1,cnt+NVS.size());
            for (int NV : NVS) {
                flag[NV] = false;
            }
        }
    };
    DFS(DFS,0,0);
    if (ANS == inf) {
        cout << "Impossible" << endl;
    }
    else {
        cout << Cur + ANS << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 4288
final_rank: 6

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> N >> M >> K;
    vector<int> A(M), B(M);
    rep(i,0,M) cin >> A[i] >> B[i], A[i]--, B[i]--;
    vector<int> Deg(N,0);
    rep(i,0,M) Deg[A[i]]++, Deg[B[i]]++;
    int Cur = 0;
    vector<bool> flag(N,false);
    rep(i,0,N) {
        if (Deg[i] > K) {
            flag[i] = true;
            Cur++;
        }
    }
    if (Cur > K) {
        cout << "Impossible" << endl;
        return 0;
    }
    K -= Cur;
    vector<vector<int>> G(N);
    int EC = 0;
    rep(i,0,N) Deg[i] = 0;
    rep(i,0,M) {
        if (flag[A[i]] || flag[B[i]]) continue;
        EC++;
        Deg[A[i]]++;
        Deg[B[i]]++;
        G[A[i]].push_back(B[i]);
        G[B[i]].push_back(A[i]);
    }
    if (EC > K*K) {
        cout << "Impossible" << endl;
        return 0;
    }
    vector<int> ord;
    rep(i,0,N) if (!flag[i]) ord.push_back(i);
    int VC = ord.size();
    sort(ALL(ord),[&](int i, int j){return Deg[i] > Deg[j];});
    int ANS = inf;
    auto DFS = [&](auto self, int id, int cnt) -> void {
        if (cnt + Cur > K) return;
        if (id == VC) {
            chmin(ANS, cnt);
            return;
        }
        int pos = ord[id];
        if (flag[pos]) {
            self(self,id+1,cnt);
            return;
        }
        vector<int> NVS;
        for (int NV : G[pos]) {
            if (flag[NV]) continue;
            NVS.push_back(NV);
        }
        if (NVS.size() == 0) {
            self(self,id+1,cnt);
            return;
        }
        if (NVS.size() == 1) {
            flag[NVS[0]] = true;
            self(self,id+1,cnt+1);
            flag[NVS[0]] = false;
            return;
        }
        {
            flag[pos] = true;
            self(self,id+1,cnt+1);
            flag[pos] = false;
        }
        {
            for (int NV : NVS) {
                flag[NV] = true;
            }
            self(self,id+1,cnt+NVS.size());
            for (int NV : NVS) {
                flag[NV] = false;
            }
        }
    };
    DFS(DFS,0,0);
    if (ANS == inf) {
        cout << "Impossible" << endl;
    }
    else {
        cout << Cur + ANS << endl;
    }
}
accuracy: 0.9251336898395722
time_ms: 30
memory_kb: 3704
final_rank: 16

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

using namespace std;

#define rep(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define rrep(i, a, b) for (int i = (int)(b)-1; i >= (int)(a); i--)
#define ALL(v) (v).begin(), (v).end()
#define UNIQUE(v) sort(ALL(v)), (v).erase(unique(ALL(v)), (v).end())
#define SZ(v) (int)v.size()
#define MIN(v) *min_element(ALL(v))
#define MAX(v) *max_element(ALL(v))
#define LB(v, x) int(lower_bound(ALL(v), (x)) - (v).begin())
#define UB(v, x) int(upper_bound(ALL(v), (x)) - (v).begin())

using uint = unsigned int;
using ll = long long int;
using ull = unsigned long long;
using i128 = __int128_t;
using u128 = __uint128_t;
const int inf = 0x3fffffff;
const ll INF = 0x1fffffffffffffff;

template <typename T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return 1;
    }
    return 0;
}
template <typename T, typename U> T ceil(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? (x + y - 1) / y : x / y);
}
template <typename T, typename U> T floor(T x, U y) {
    assert(y != 0);
    if (y < 0)
        x = -x, y = -y;
    return (x > 0 ? x / y : (x - y + 1) / y);
}
template <typename T> int popcnt(T x) {
    return __builtin_popcountll(x);
}
template <typename T> int topbit(T x) {
    return (x == 0 ? -1 : 63 - __builtin_clzll(x));
}
template <typename T> int lowbit(T x) {
    return (x == 0 ? -1 : __builtin_ctzll(x));
}

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
    os << "P(" << p.first << ", " << p.second << ")";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const vector<T> &vec) {
    os << "{";
    for (int i = 0; i < vec.size(); i++) {
        os << vec[i] << (i + 1 == vec.size() ? "" : ", ");
    }
    os << "}";
    return os;
}
template <typename T, typename U>
ostream &operator<<(ostream &os, const map<T, U> &map_var) {
    os << "{";
    for (auto itr = map_var.begin(); itr != map_var.end(); itr++) {
        os << "(" << itr->first << ", " << itr->second << ")";
        itr++;
        if (itr != map_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
template <typename T> ostream &operator<<(ostream &os, const set<T> &set_var) {
    os << "{";
    for (auto itr = set_var.begin(); itr != set_var.end(); itr++) {
        os << *itr;
        ++itr;
        if (itr != set_var.end())
            os << ", ";
        itr--;
    }
    os << "}";
    return os;
}
#ifdef LOCAL
#define show(...) _show(0, #__VA_ARGS__, __VA_ARGS__)
#else
#define show(...) true
#endif
template <typename T> void _show(int i, T name) {
    cerr << '\n';
}
template <typename T1, typename T2, typename... T3>
void _show(int i, const T1 &a, const T2 &b, const T3 &...c) {
    for (; a[i] != ',' && a[i] != '\0'; i++)
        cerr << a[i];
    cerr << ":" << b << " ";
    _show(i + 1, a, c...);
}

/**
 * @brief template
 */

int main() {
    int N, M, K;
    cin >> N >> M >> K;
    vector<int> A(M), B(M);
    rep(i,0,M) cin >> A[i] >> B[i], A[i]--, B[i]--;
    vector<int> Deg(N,0);
    rep(i,0,M) Deg[A[i]]++, Deg[B[i]]++;
    int Cur = 0;
    vector<bool> flag(N,false);
    rep(i,0,N) {
        if (Deg[i] > K) {
            flag[i] = true;
            Cur++;
        }
    }
    if (Cur > K) {
        cout << "Impossible" << endl;
        return 0;
    }
    K -= Cur;
    vector<vector<int>> G(N);
    int EC = 0;
    rep(i,0,N) Deg[i] = 0;
    rep(i,0,M) {
        if (flag[A[i]] || flag[B[i]]) continue;
        EC++;
        Deg[A[i]]++;
        Deg[B[i]]++;
        G[A[i]].push_back(B[i]);
        G[B[i]].push_back(A[i]);
    }
    vector<int> ord;
    rep(i,0,N) if (!flag[i]) ord.push_back(i);
    int VC = ord.size();
    sort(ALL(ord),[&](int i, int j){return Deg[i] > Deg[j];});
    int ANS = inf;
    auto DFS = [&](auto self, int id, int cnt) -> void {
        if (cnt + Cur > K) return;
        if (id == VC) {
            chmin(ANS, cnt);
            return;
        }
        int pos = ord[id];
        if (flag[pos]) {
            self(self,id+1,cnt);
            return;
        }
        vector<int> NVS;
        for (int NV : G[pos]) {
            if (flag[NV]) continue;
            NVS.push_back(NV);
        }
        if (NVS.size() == 0) {
            self(self,id+1,cnt);
            return;
        }
        if (NVS.size() == 1) {
            flag[NVS[0]] = true;
            self(self,id+1,cnt+1);
            flag[NVS[0]] = false;
            return;
        }
        {
            flag[pos] = true;
            self(self,id+1,cnt+1);
            flag[pos] = false;
        }
        {
            for (int NV : NVS) {
                flag[NV] = true;
            }
            self(self,id+1,cnt+NVS.size());
            for (int NV : NVS) {
                flag[NV] = false;
            }
        }
    };
    DFS(DFS,0,0);
    if (ANS == inf) {
        cout << "Impossible" << endl;
    }
    else {
        cout << Cur + ANS << endl;
    }
}
accuracy: 0.9251336898395722
time_ms: 30
memory_kb: 3760
final_rank: 17

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; }

// 最小頂点被覆
// サイズk以下の解を求める　無い場合は-1を返す
int minimum_vertex_cover(int n, int k, vector<vector<int>> g) {
    // 次数K+1以上の頂点は必ず使う
    int pre = 0;
    while (k >= 0) {
        bool ok = true;
        for (int i = 0; i < n; i++) {
            if (g[i].size() > k) {
                ok = false;
                pre++, k--;
                for (int j : g[i]) {
                    for (int k = 0; k < g[j].size(); k++) {
                        if (g[j][k] == i) {
                            swap(g[j][k], g[j].back());
                            g[j].pop_back();
                            break;
                        }
                    }
                }
                g[i].clear();
            }
        }
        if (ok) break;
    }
    if (k < 0) {
        return -1;
    }

    // グラフの再構築
    {
        vector<int> v;
        int mm = 0;
        for (int i = 0; i < n; i++) {
            if (g[i].size()) {
                v.push_back(i);
                mm += g[i].size();
            }
        }
        // 辺が多すぎる
        if (mm / 2 > k * k) {
            return -1;
        }
        n = v.size();
        vector<vector<int>> ng(n);
        for (int k = 0; k < n; k++) {
            int i = v[k];
            for (int j : g[i]) {
                ng[k].push_back(lower_bound(v.begin(), v.end(), j) - v.begin());
            }
        }
        swap(g, ng);
    }

    vector<int> used(n, false);
    int res = k + 1;
    vector<int> idx(n);
    iota(idx.begin(), idx.end(), 0);
    // 次数多い頂点から見る
    sort(idx.begin(), idx.end(),
         [&](auto i, auto j) { return g[i].size() > g[j].size(); });

    auto dfs = [&](auto dfs, int i, int cnt) -> void {
        if (cnt >= res) return;
        if (i == n) {
            res = min(res, cnt);
            return;
        }

        int s = idx[i];
        if (used[s]) {
            dfs(dfs, i + 1, cnt);
            return;
        }

        int deg = 0;
        vector<int> v;
        for (int t : g[s]) {
            if (!used[t]) {
                deg++;
                v.push_back(t);
            }
        }
        if (deg == 0) {
            dfs(dfs, i + 1, cnt);
            return;
        }
        // 枝刈り 次数1を使う場合は考えなくて良い
        if (deg == 1) {
            used[v[0]] = true;
            dfs(dfs, i + 1, cnt + 1);
            used[v[0]] = false;
            return;
        }

        // sを使う
        {
            used[s] = true;
            dfs(dfs, i + 1, cnt + 1);
            used[s] = false;
        }
        // sを使わない
        if (deg + cnt < res) {
            for (int j : v) {
                used[j] = true;
            }
            dfs(dfs, i + 1, cnt + deg);
            for (int j : v) {
                used[j] = false;
            }
        }
    };
    dfs(dfs, 0, 0);

    if (res == k + 1) return -1;
    else return res + pre;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n, m, k;
    cin >> n >> m >> k;
    vector<vector<int>> g(n);
    for (int i = 0; i < m; i++) {
        int x, y;
        cin >> x >> y;
        x--;
        y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }

    int res = minimum_vertex_cover(n, k, g);
    if (res == -1) {
        cout << "Impossible" << endl;
    } else {
        cout << res << endl;
    }
}
accuracy: 1
time_ms: 30
memory_kb: 4092
final_rank: 4

code_snippet: // time complexity: O(MK log K + 1.466^K * K^2 log K)

#include <bits/stdc++.h>
using namespace std;

const int INF = 1012345678;

struct edge {
	int a, b;
};

// function to solve for graphs with degree <= 2
int solve_deg2(int K, const vector<edge>& es) {
	map<int, vector<int> > G;
	for (edge e : es) {
		G[e.a].push_back(e.b);
		G[e.b].push_back(e.a);
	}
	vector<int> keys;
	for (pair<int, vector<int> > i : G) {
		keys.push_back(i.first);
	}
	int req = 0;
	map<int, bool> vis;
	for (int i : keys) {
		if (!vis[i] && G[i].size() == 1) {
			int pre = i, pos = G[i][0], len = 1;
			vis[pre] = true;
			vis[pos] = true;
			while (G[pos].size() == 2) {
				int nxt = G[pos][0] ^ G[pos][1] ^ pre;
				pre = pos;
				pos = nxt;
				len += 1;
				vis[pos] = true;
			}
			req += (len + 1) / 2;
		}
	}
	for (int i : keys) {
		if (!vis[i] && G[i].size() == 2) {
			int pre = i, pos = G[i][0], len = 1;
			vis[pre] = true;
			vis[pos] = true;
			while (pos != i) {
				int nxt = G[pos][0] ^ G[pos][1] ^ pre;
				pre = pos;
				pos = nxt;
				len += 1;
				vis[pos] = true;
			}
			req += (len + 1) / 2;
		}
	}
	return (req <= K ? req : INF);
}

// function to solve problem
int solve(int K, const vector<edge>& es) {
	// step #1. compute degrees / basic cases
	if (es.empty()) {
		return 0;
	}
	if (K == 0) {
		return INF;
	}
	map<int, int> deg;
	for (edge e : es) {
		deg[e.a] += 1;
		deg[e.b] += 1;
	}
	int pos = -1, maxdeg = -1;
	for (pair<int, int> i : deg) {
		if (maxdeg < i.second) {
			maxdeg = i.second;
			pos = i.first;
		}
	}
	if (maxdeg * K < int(es.size())) {
		return INF; // impossible
	}
	if (maxdeg <= 2) {
		return solve_deg2(K, es);
	}

	// step #2. case if "used"
	vector<edge> nes1(es.size() - deg[pos]);
	vector<int> adj(deg[pos]);
	int cur1 = 0, cur2 = 0;
	for (edge e : es) {
		if (e.a != pos && e.b != pos) {
			nes1[cur1++] = e;
		}
		else {
			adj[cur2++] = e.a ^ e.b ^ pos;
		}
	}
	int res1 = solve(K - 1, nes1);
	if (res1 != INF) {
		res1 += 1;
	}

	// step #3. case if "not used"
	int res2 = INF;
	if (maxdeg <= K) {
		sort(adj.begin(), adj.end());
		vector<edge> nes2;
		for (edge e : es) {
			if (!binary_search(adj.begin(), adj.end(), e.a) && !binary_search(adj.begin(), adj.end(), e.b)) {
				nes2.push_back(e);
			}
		}
		res2 = solve(K - maxdeg, nes2);
		if (res2 != INF) {
			res2 += maxdeg;
		}
	}

	return min(res1, res2);
}

int main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	int N, M, K;
	cin >> N >> M >> K;
	vector<edge> es(M);
	for (int i = 0; i < M; i++) {
		cin >> es[i].a >> es[i].b;
		es[i].a -= 1;
		es[i].b -= 1;
	}
	int ans = solve(K, es);
	if (ans != INF) {
		cout << ans << endl;
	}
	else {
		cout << "Impossible" << endl;
	}
	return 0;
}
accuracy: 1
time_ms: 40
memory_kb: 10820
final_rank: 7

code_snippet: #include <bits/stdc++.h>
using namespace std;
#define foa(s, v) for(auto &s : v)
#define all(v) v.begin(), v.end()
#define REPname(a,b,c,d,...) d
#define rep(...) REPname(__VA_ARGS__, REP2, REP1, REP0)(__VA_ARGS__)
#define REP2(i,l,r) for(int i = l; i < r; i++)
#define REP1(i, x) REP2(i,0,x)
#define REP0(x) REP1(SPJ, x)
#define sz(x) int(x.size())

template <class T>
using V=vector<T>;

template <class T>
using VV=vector<V<T>>;

template<class T>
using pqmin = priority_queue<T, V<T>, greater<T>>;
using ll = long long ;
using vi = vector<int>;
using vvi = vector<vi>;
using vvvi = vector<vvi>;
using vll = vector<ll>;
using vvll = V<vll>;
constexpr ll INF = 1e18;
constexpr int inf = 1e9;
template<class T>
inline bool chmax(T &a, T b){
	return a < b ? a=b, 1 : 0;
}
template <class T>
inline bool chmin(T &a, T b) {
	return a > b ? a = b, 1 : 0;
}

template <class T>
void view(T x) {
	cerr << x;
}

template <class T>
void view(V<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ", ";}
	cerr << "}";
	cerr << endl;
}


template <class T>
void view(VV<T> v) {
	cerr << "{ ";
	foa(t, v) {view(t) ; cerr << ",\n";}
	cerr << "}";
	cerr << endl;
}


// template <c0lass T>
void view(int x) {
	cerr << x;
}

#ifdef LOCAL
void debug_out() {}
template <class T>
void debug_out(T x) {
	view(x);
}
template <class H, class... T>
void debug_out(H h, T... t) {
	view(h);
	cerr << ", ";
	debug_out(t...);
}
#define debug(...)                                           \
	do {                                                     \
		cerr << __LINE__ << " [" << #__VA_ARGS__ << "] : ["; \
		debug_out(__VA_ARGS__);                              \
		cerr << "]\n";                                       \
	} while(0)
#else
#define debug(...) (void(0))
#endif
using vvi = V<vi>;

struct UF{
	vector<int> dat;
	int components;
	UF(int n) : dat(n, -1), components(n) {}
	int root(int x) 
	{
		int& p = dat[x];
		if(p < 0) return x;
		return p = root(p);
	}
	bool merge(int x, int y) {
		x = root(x);
		y = root(y);
		if(x == y) return false;
		if(-dat[x] < -dat[y]) swap(x, y);
		dat[x] += dat[y];
		dat[y]  = x;
		components--;
		return true;
	}
};

ll modpow(ll x, ll n, ll md){
	ll ret = 1 % md;
	while(n > 0){
		if(n & 1) {ret *= x; ret %= md;}
		n >>= 1;
		x *= x;
		x %= md;
	}
	if(ret < 0) ret += abs(md);
	return ret;
}

using S = ll;
using F = ll; // +
constexpr ll e = INF;
constexpr ll id = 0LL;
constexpr ll replace_e = e;
ll op(ll a, ll b) {return min(a,b);}
ll mapping(F f, S s) {return S(f+s);}
ll composition(F f, F g) {return f+g;}
struct node {
	node *l = nullptr;
	node *r = nullptr;
	int lo, hi;
	ll mset = e;
	ll madd = id;
	ll val = e;
	node(int lo, int hi) : lo(lo), hi(hi) {}
	node (vll& v, int lo, int hi) : lo(lo), hi(hi) {
		if(lo + 1 < hi) {
			int mid  = lo + (hi - lo) / 2;
			l  = new node (v, lo, mid);
			r = new node(v, mid, hi);
			val = op(l->val, r->val);
		}
		else {
			val  = v[lo];
		}
	}

	S query(int L, int R) {
		if(R <= lo || hi <= L) return e;
		if(L <=lo && hi  <= R) return val;
		push();
		return op(l->query(L, R), r->query(L,R));
	}

	void set(int L, int R, ll x) {
		if(R <= lo || hi <= L) return;
		if(L <= lo && hi <= R) mset = val = x, madd = id;
		else {
			push(), l->set (L, R, x) , r->set(L,R,x);
			val = op(l->val, r->val);
		}
	}

	void add(int L, int R, ll x) {
		if(R <= lo || hi <= L) return;
		if(L <= lo && hi <= R) {
			if(mset != replace_e) mset = mapping(x, mset);
			else madd = composition(x, madd);
			val = mapping(x, val);
		} else {
			push(), l->add(L, R, x), r->add(L, R, x);
			val = op(l->val, r->val);
		}
	}

	void push() {
		if(!l) {
			int mid = lo + (hi - lo) / 2;
			l = new node(lo, mid);
			r = new node(mid, hi);
		}
		if(mset != replace_e)
			l->set(lo, hi, mset), r->set(lo, hi, mset), mset = replace_e;
		else if(madd)
			l->add(lo, hi, madd), r->add(lo, hi, madd), madd = id;
	}
};

ll mst(int n, vector<tuple<ll, int, int>>& edges, int start_id) {
	UF uf(n);
	ll ans = -INF;
	rep(i, start_id, int(edges.size())){
		ll w;
		int a, b;
		tie(w, a, b) = edges.at(i);
		if(uf.merge(a, b)) {
			chmax(ans, w);
		}
	}
	if(uf.components > 1) return INF;
	return ans;
}

int f(vector<vector<int>> g, int ret) {
	int n = int(g.size());
	int used = 0;

	int edcount = 0;
	rep(i, n) rep(j, i+1, n) edcount += g[i].at(j);

	if(edcount > (ret - 1) * (ret - 1)) return ret;

	vector<int> deg(n);
	rep(i, n) deg[i] = accumulate(all(g.at(i)), 0);

	auto erase_v = [&](int v) {
		vector<int> ids;
		rep(i, n) {
			if(g[i][v]) {
				g[i][v] = g[v][i] = 0;
				edcount--;
				ids.push_back(i);
				deg.at(i)--;
				deg.at(v)--;
			}
		}
		used++;
		return ids;
	};

	auto recover = [&](int now, const vi &ids) {
		foa(i, ids) {
			g[now][i] = g[i][now] = 1;
			edcount++;
			deg.at(now)++;
			deg.at(i)++;
		}
		used--;
	};

	auto dfs = [&](auto self) -> void {
		if(used >= ret) return;
		if(edcount == 0) {
			chmin(ret, used);
			return;
		}

		// find one 
		int now = -1;
		rep(i, n) {
			if(deg[i] == 1) now = i;
		}

		if(now < 0) {
			now = max_element(all(deg)) - deg.begin();
		}
		
		bool is_leaf = deg[now] == 1;

		vi adj = erase_v(now);
		if(!is_leaf) self(self);
		recover(now, adj);

		vector<vector<int>> adjs;
		foa(nxt, adj) {
			adjs.push_back(erase_v(nxt));
		}
		self(self);
		rep(i, int(adj.size())) {
			recover(adj[i], adjs[i]);
		}

		return;
	};

	dfs(dfs);

	return ret;
}

int solve(int n){ // first : 1, second : -1, draw : 0
	int m; cin >> m; int k; cin >> k;
	int ret = k + 1;
	int used = 0;
	vector<vi> g(n, vi(n));
	vector<int> deg(n);
	rep(m) {
		int a, b;
		cin >> a >> b;
		a--;
		b--;
		deg[a]++;
		deg.at(b) ++;
		g[a][b]++;
		g[b][a]++;
	}

	auto erase_v = [&](int v) -> void {
		rep(i, n) {
			if(g[i][v]) {
				g[i][v] = g[v][i] = 0;
				deg[i]--;
				deg[v]--;
			}
		}
		used++;
	};

	while(1) {
		auto it = max_element(all(deg));
		if(*it + used >= ret) {
			erase_v(it - deg.begin());
		} else {
			break;
		}
		if(used >= ret) return -1;
	}

	if(used >= ret) return -1;

	vector<int> rest;
	rep(i, n) if(deg[i]) rest.push_back(i);
	int rs = rest.size();
	vvi ng(rs, vi(rs));
	rep(i, rs) rep(j, rs) {
		if(g[rest[i]][rest[j]]) {
			ng[i].at(j)++;
		}
	}

	used += f(ng, ret - used);
	if(used >= ret) return -1;
	return used;
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	cout << fixed << setprecision(15);
	srand((unsigned)time(NULL));
	int n;
	while(cin >> n && n) {
		int res = solve(n);
		if(res < 0) cout << "Impossible\n";
		else cout << res << '\n';
	}
}
accuracy: 1
time_ms: 30
memory_kb: 108948
final_rank: 8

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

int main(){
    cin.tie(nullptr);
    ios::sync_with_stdio(false);
    int n,m,k; cin >> n >> m >> k;
    vector<vector<int>> g(n);
    for(int i=0;i<m;i++){
        int x,y; cin >> x >> y;
        x--; y--;
        g[x].push_back(y);
        g[y].push_back(x);
    }
    // 次数K+1以上の頂点は必ず使う
    int rm = 0;
    while(true){
        if(k < 0) break;
        bool ok = true;
        for(int i=0;i<n;i++){
            if(g[i].size() > k){
                ok = false;
                rm++; k--;
                for(int j:g[i]){
                    for(int k=0;k<g[j].size();k++){
                        if(g[j][k] == i){
                            swap(g[j][k], g[j].back());
                            g[j].pop_back(); break;
                        }
                    }
                }
                g[i].clear();
            }
        }
        if(ok) break;
    }
    if(k < 0){
        cout << "Impossible" << "\n";
        return 0;
    }
    { // グラフの再構築
        vector<int> v;
        int mm = 0;
        for(int i=0;i<n;i++){
            if(g[i].size()){
                v.push_back(i);
                mm += g[i].size();
            }
        }
        // 辺が多すぎる
        if(mm/2 > k*k){
            cout << "Impossible" << "\n";
            return 0;
        }
        n = v.size();
        vector<vector<int>> ng(n);
        for(int _=0;_<n;_++){
            int i = v[_];
            for(int j:g[i]){
                ng[_].push_back(lower_bound(v.begin(), v.end(), j) - v.begin());
            }
        }
        swap(g,ng);
    }
    vector<int> used(n,false);
    int res = k+1;
    vector<int> v(n);
    for(int i=0;i<n;i++){
        v[i] = i;
    }
    // 次数多い頂点から見る
    sort(v.begin(), v.end(), [&](auto i,auto j){
        return g[i].size() > g[j].size();
    });
    auto dfs=[&](auto dfs,int i,int cnt)->void{
        if(cnt >= res) return;
        if(i == n){
            res = min(res, cnt); return;
        }
        int s = v[i];
        if(used[s]){
            dfs(dfs,i+1,cnt); return;
        }
        int deg = 0;
        int ss = -1;
        for(int t:g[s]){
            if(!used[t]) deg++,ss=t;
        }
        if(deg == 0){
            dfs(dfs,i+1,cnt); return;
        }
        // 枝刈り 次数1を使う場合は考えなくて良い
        if(deg == 1){
            used[ss] = true;
            dfs(dfs,i+1,cnt+1);
            used[ss] = false;
            return;
        }

        // sを使う
        {
            used[s] = true;
            dfs(dfs,i+1,cnt+1);
            used[s] = false;
        }
        // sを使わない
        if(deg+cnt < res){
            vector<int> v;
            for(int t:g[s]){
                if(!used[t]){
                    v.push_back(t);
                    used[t] = true;
                }
            }
            dfs(dfs,i+1,cnt+deg);
            for(int j:v){
                used[j] = false;
            }
        }
    };
    dfs(dfs,0,0);

    if(res == k+1){
        cout << "Impossible" << "\n";
    }
    else{
        cout << res+rm << "\n";
    }
}
accuracy: 1
time_ms: 10
memory_kb: 3824
final_rank: 1

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

using namespace std;

#define eps 1e-9
#define INF 2000000000              // 2e9
#define LLINF 2000000000000000000ll // 2e18 (llmax:9e18)
#define all(x) (x).begin(), (x).end()
#define sq(x) ((x) * (x))

#define rep(i, x) for (int i = 0; i < (int)(x); i++)
#define drep(i, x) for (int i = ((int)(x)-1); i >= 0; i--)

#define popcount __builtin_popcount
#define next __next
#define prev __prev

#ifndef LOCAL
#define dmp(...) ;
#else
#define dmp(...)                                                               \
  cerr << "[ " << #__VA_ARGS__ << " ] : " << dump_str(__VA_ARGS__) << endl
#endif

// ---------------- Utility ------------------

template <class T>
bool chmin(T &a, const T &b) {
  if (a <= b) return false;
  a = b;
  return true;
}

template <class T>
bool chmax(T &a, const T &b) {
  if (a >= b) return false;
  a = b;
  return true;
}

template <class T>
using MaxHeap = priority_queue<T>;

template <class T>
using MinHeap = priority_queue<T, vector<T>, greater<T>>;

template <class T>
vector<T> vect(int len, T elem) {
  return vector<T>(len, elem);
}

// ----------------- Input -------------------

template <class T, class U>
istream &operator>>(istream &is, pair<T, U> &p) {
  return is >> p.first >> p.second;
}

template <class T>
istream &operator>>(istream &is, vector<T> &vec) {
  for (int i = 0; i < vec.size(); i++) is >> vec[i];
  return is;
}

// ----------------- Output ------------------

template <class T, class U>
ostream &operator<<(ostream &os, const pair<T, U> &p) {
  return os << p.first << ',' << p.second;
}

template <class T>
ostream &operator<<(ostream &os, const vector<T> &v) {
  for (const T &e : v) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const deque<T> &d) {
  for (const T &e : d) os << e << " ";
  return os;
}

template <class T>
ostream &operator<<(ostream &os, const set<T> &s) {
  os << "{ ";
  for (const T &e : s) os << e << " ";
  return os << "}";
}

template <class T, class U>
ostream &operator<<(ostream &os, const map<T, U> &m) {
  os << "{ ";
  for (const auto &[key, val] : m) os << "( " << key << " -> " << val << " ) ";
  return os << "}";
}

template <class TupleTy, size_t... I>
void dump_tuple(ostream &os, const TupleTy t, std::index_sequence<I...>) {
  (..., (os << (I == 0 ? "" : ",") << std::get<I>(t)));
}

template <class... Args>
ostream &operator<<(ostream &os, const tuple<Args...> &t) {
  os << "(";
  dump_tuple(os, t, std::make_index_sequence<sizeof...(Args)>());
  return os << ")";
}

void dump_str_rec(ostringstream &) {}

template <class Head, class... Tail>
void dump_str_rec(ostringstream &oss, Head &&head, Tail &&... tail) {
  oss << ", " << head;
  dump_str_rec(oss, forward<Tail>(tail)...);
}

template <class T, class... U>
string dump_str(T &&arg, U &&... args) {
  ostringstream oss;
  oss << arg;
  dump_str_rec(oss, forward<U>(args)...);
  return oss.str();
}

// --------------- Fast I/O ------------------

void fastio() {
  cin.tie(0);
  ios::sync_with_stdio(0);
  cout << fixed << setprecision(20);
}

// ------------------ ACL --------------------

// #include <atcoder/modint>
// constexpr int MOD = 998244353;
// constexpr int MOD = 1000000007;
// using mint = atcoder::static_modint<MOD>;
// ostream &operator<<(ostream &os, const mint &v) {
//   return os << v.val();
// }

// ------------ End of template --------------

#define endl "\n"
using ll = long long;
using pii = pair<int, int>;

const bool multitest = false;

void solve() {
  int N, M, K;
  cin >> N >> M >> K;
  vector<vector<int>> g(N);
  for (int i = 0; i < M; i++) {
    int a, b;
    cin >> a >> b;
    a--, b--;
    g[a].push_back(b);
    g[b].push_back(a);
  }

  int ans = INF;

  // state: 0 -> not yet
  //        1 -> used
  //        2 -> not used

  function<void(vector<int>, int)> dfs = [&](vector<int> state, int num_used) {
    if (num_used > K) return;

    vector<vector<int>> adj(N);
    int cnt = 0;
    for (int i = 0; i < N; i++) {
      if (state[i] == 0) {
        cnt++;
        for (int j : g[i]) {
          if (state[j] == 0) adj[i].push_back(j);
        }
      }
    }
    if (cnt == 0) {
      chmin(ans, num_used);
      return;
    }

    for (int i = 0; i < N; i++) {
      // 次数が0なら、確定で使わない
      if (state[i] == 0 && adj[i].size() == 0) {
        state[i] = 2;
        return dfs(state, num_used);
      }
      // 次数が1なら、確定で使わないでとなりの頂点を使う
      if (state[i] == 0 && adj[i].size() == 1) {
        state[i] = 2;
        state[adj[i].front()] = 1;
        return dfs(state, num_used + 1);
      }
      // 次数がKより大きいなら、絶対使う
      if (state[i] == 0 && adj[i].size() > K) {
        state[i] = 1;
        return dfs(state, num_used + 1);
      }
    }

    // 未決定の頂点の内最小のindexで分岐
    int v = 0;
    while (v < N && state[v] != 0) v++;

    // vを使う場合
    state[v] = 1;
    dfs(state, num_used + 1);

    // vを使わない場合 周りの頂点は確定で使う
    state[v] = 2;
    for (int u : adj[v]) state[u] = 1;
    dfs(state, num_used + adj[v].size());
  };

  vector<int> state(N, 0);
  dfs(state, 0);

  if (ans < INF)
    cout << ans << endl;
  else
    cout << "Impossible" << endl;
  return;
}

int main() {
  fastio();
  if (!multitest) {
    solve();
  } else {
    cerr << "[Warning] Multi testcase mode on" << endl;
    int t;
    cin >> t;
    while (t--) solve();
  }
  return 0;
}
accuracy: 1
time_ms: 170
memory_kb: 258348
final_rank: 15