#include <cstdio>
#include <list>

const int MAX = 200001;

int n, m, d, a, b;

struct Edge{
	//krawedz z v->w
	int w;
//	Edge *rev;  // wska?nik na kraw?d? wsteczn?
	Edge(int w_in){
		w = w_in;
	}
};

struct Vertex{
	int x = 0; //numer wierzcholka
	int component = 0; //w jakim komponencie siê znjaduje
	int edges_num = 0; //ilosc krawedzi
	bool visited;
	int node = 0;
	void plusEdge(){
		++edges_num;
	}
	void minusEdge(){
		--edges_num;
	}
	Vertex(int x_in){
		visited = false;
		x = x_in; 
		component = 0; 
		edges_num = 0; 
	}
	Vertex(){
		visited = false;
		x = 0; 
		component = 0; 
		edges_num = 0; 	
	}
};

Vertex V[MAX+1]; 

int components[MAX+1];

std::list<Edge> E[MAX+1];

void dfs(int v, int comp){
  V[v].visited = true;
  V[v].component = comp;
  components[comp]++;
  //printf("%d\n", w);
  for (std::list<Edge>::iterator j = E[v].begin(); j != E[v].end(); ++j) {
  	//if(j->w == 15) printf("i co bedzie\n");
    if(!(V[j->w].visited)){ 
    //	if(j->w == 15) printf("kurwakurwakurawa\n");
      dfs(j->w, comp);
    }
  }
}




struct Node{
	Vertex* val;
	Node(){
	}
	Node(int id_in, Vertex* val_in){
		val = val_in;
	}
};

int heapSize = 0;
Node H[MAX+1];

bool cmpH(Node x, Node y){
	return x.val->edges_num < y.val->edges_num;
}



void upHeap(int i){
	Node tmp;
	int j = i/2;
	while(i > 1){
		if(cmpH(H[i],H[j])){
			H[i].val->node = j;
			H[j].val->node = i;
			tmp = H[i];
			H[i] = H[j];
			H[j] = tmp;
		}else{
			break;
		}
		i = j;
		j = i/2;
	}
}

void downHeap(int i, int heapSize){
	int left, right;
	Node tmp;
	while(i <= n/2){
		//printf("i: %d", i);
		int left = 2*i;
		int right = 2*i + 1;
		if(right > heapSize && left > heapSize){
			break;
		}
		if(right > heapSize && left <= heapSize){
			if(cmpH(H[left],H[i])){
				H[i].val->node = left;
				H[left].val->node = i;
				tmp = H[i];
				H[i] = H[left];
				H[left] = tmp;
				i = left;
			}else{
				break;
			}
		}
		if(right <= heapSize && left <= heapSize){
			if(cmpH(H[left],H[right])){
				if(cmpH(H[left],H[i])){
					H[i].val->node = left;
					H[left].val->node = i;
					tmp = H[i];
					H[i] = H[left];
					H[left] = tmp;
					i = left;
				}else{
					break;
				}
			}else{
				if(cmpH(H[right],H[i])){
					H[i].val->node = right;
					H[right].val->node = i;
					tmp = H[i];
					H[i] = H[right];
					H[right] = tmp;
					i = right;
				}else{
					break;
				}
			}
		}
	}
}

void buildHeap(int size){
	heapSize = size;
	for(int i = 1; i <= heapSize; ++i){
		H[i] = Node(i, &V[i]);
	}
	for(int i = (heapSize/2); i >= 1; --i){
		downHeap(i, heapSize);
	}
      
}

bool isEmptyHeap(){
	return (heapSize <= 0);
}

int popHeap(){
	Node tmp = H[1];
	H[1] = H[heapSize];
	H[heapSize] = tmp;
	heapSize--;
	downHeap(1, heapSize);
	return tmp.val->x;
}


int main(){
	scanf("%d %d %d", &n, &m, &d);
	for(int i = 1; i <= n; ++i){
		V[i] = Vertex(i);
	}
	for(int i = 1; i <= m; ++i){
		scanf("%d %d", &a, &b);
		E[a].push_back(Edge(b));
		E[b].push_back(Edge(a));
	//	E[a].back().rev = &E[b].back();
    //  	E[b].back().rev = &E[a].back();
      	V[a].edges_num++;
      	V[b].edges_num++;
	}
	
//	for(int i = 1; i <= n; ++i){
///		printf("%d ", V[i].edges_num);
//	}printf("\n");
	
//	printf("intro\n");
	///Heap
	buildHeap(n);
	
///	for(int i = 1; i <= n; ++i){
//		printf("%d ", H[i].val->x);
//	}printf("\n");
	
//	for(int i = 1; i <= n; ++i){
//		printf("%d ", H[i].val->edges_num);
//	}printf("\n");
//	printf("zbudowano\n");
	while(!isEmptyHeap()){
		int tmp = H[1].val->x;
//		if(tmp == 15) printf("15 ... %d e: %d\n", V[15].visited, V[15].edges_num);
		if(V[tmp].edges_num < d){
			for (std::list<Edge>::iterator j = E[tmp].begin(); j != E[tmp].end(); ++j) {
//				printf("dupa");
				V[j->w].edges_num--;
				upHeap(V[j->w].node);
			}
			E[tmp].clear();
			V[tmp].edges_num = 0;
			V[tmp].visited = true;
			popHeap();
		}else{
			break;
		}
//		for(int i = 1; i <= heapSize; ++i){
//		printf("%d ", H[i].val->edges_num);
//		}printf("\n");
//			for(int i = 1; i <= n; ++i){
//		printf("%d ", H[i].val->x);
//	}printf("\n");
	} //printf("\n");
//	for(int i = 1; i <= heapSize; ++i){
//		printf("%d ", H[i].val->x);
//		}printf("\n");
	//printf("Heap\n");
//	printf("co kurwa %d e: %d\n", V[15].visited, V[15].edges_num);
	
	for(int i = heapSize+1; i <= n; ++i){
		V[H[i].val->x].visited = true;
		}//printf("\n");
	
	///DFS
	int comp = 0;
	for(int i = 1; i <= n; ++i){
		if(!H[i].val->visited){
			comp++;
			dfs(H[i].val->x, comp);
		}
	}
	
//	printf("DFS\n");
	
	//MAX
	int max = 0;
	int ind_tmp = 0;
	for(int i = 1; i <= comp; ++i){
		if(components[i] > max) {
			max = components[i];
			ind_tmp = i;
		}
	}
	
	//solution
	//printf("i: %d c: %d\n", ind_tmp, components[ind_tmp]);
	if(max == 0){
		printf("NIE\n");
	} else {
		printf("%d\n", max);
		for(int i = 1; i <= n; ++i){
			if(V[i].component == ind_tmp) printf("%d ", V[i].x);
		}
	}//printf("\n");
	
/*	for(int i = 1; i <= n; ++i){
		printf("v: %d c: %d\n", V[i].x, V[i].component);
		for (std::list<Edge>::iterator j = E[i].begin(); j != E[i].end(); ++j) {
		    printf("e: (%d, %d)", j->v, j->w);
		}
		printf("\n");
	}
*/
}
