#include <iostream>
#include <iomanip>
#include <vector>
#include <algorithm>

using namespace std;

struct slistEl
{
	slistEl * next;
	int v;
};

class stack
{
private:
	slistEl * S;   // lista przechowująca stos

public:
	stack();       // konstruktor
	~stack();      // destruktor
	bool empty(void);
	int  top(void);
	void push(int v);
	void pop(void);
};
long d;
vector<int> zbior;
int n, m;                   // Liczba wierzchołków i krawędzi
vector<int> * A;              // Tablica list sąsiedztwa
int * C;                   // Tablica z numerami spójnych 
int * visited;
int * ILE;
stack S;                   // Stos
int cn, i, j, v, u, u2, v2;
slistEl *p, *r, *p2;

stack::stack()
{
	S = NULL;
}

stack::~stack()
{
	while (S) pop();
}

bool stack::empty(void)
{
	return !S;
}

int stack::top(void)
{
	return S->v;
}

void stack::push(int v)
{
	slistEl * e = new slistEl;
	e->v = v;
	e->next = S;
	S = e;
}

void stack::pop(void)
{
	if (S)
	{
		slistEl * e = S;
		S = S->next;
		delete e;
	}
}

int compare(const void * a, const void * b)
{
	if (*(int*)a <  *(int*)b) return -1;
	if (*(int*)a == *(int*)b) return 0;
	if (*(int*)a >  *(int*)b) return 1;
}


int sprawdz(long wierzcholek)
{
	if (visited[wierzcholek]) return 0;
	visited[wierzcholek] = 1;
	for (long i = 0; i < A[wierzcholek].size(); i++) ILE[wierzcholek] += sprawdz(A[wierzcholek].at(i));
	if (ILE[wierzcholek] < d) {
		ILE[wierzcholek] = 0;
		//cout << "V: " << wierzcholek; 
		return -1;
	}
	else return 0;
}


bool nalezy(int v)
{
	slistEl *p, *r;
	int u;
	int ile;
	ile = 0;
	//cout << "NALEZY " << v+1 << endl;
	for (long i = 0; i < A[v].size(); i++)
	{
		for (int j = 0; j < zbior.size(); j++)
		{
		//	cout << zbior[i]+1 << " | "<<u+1<< endl;
			if (zbior[j] == A[v].at(i)) { ile++; }
		}
	}
	if (ile < d) return false;
	else return true;
}

int main()
{

	cin >> n >> m;             // Odczytujemy liczbę wierzchołków i krawędzi
	cin >> d;

	A = new vector<int> [n];     // Tworzymy tablice dynamiczne
	C = new int[n];
	visited = new int[n];
	ILE = new int[n];

	// Tablicę A wypełniamy pustymi listami, a tablicę C wypełniamy zerami

	for (i = 0; i < n; i++)
	{
		A[i].clear();
		visited[i] = 0;
		C[i] = 0;
		ILE[i] = 0;
	}

	// Odczytujemy kolejne definicje krawędzi.

	for (i = 0; i < m; i++)
	{
		cin >> v >> u;           // Wierzchołki tworzące krawędź
		ILE[v-1]++;
		ILE[u-1]++;
		A[v - 1].push_back(u - 1);
		A[u - 1].push_back(v - 1);
	}

	cn = 0;                    // Zerujemy licznik spójnych składowych

	for (i = 0; i < n; i++)
	{
		sprawdz(i);
		/*if (A[i].size() < d)
		{
			ILE[i] = 0;
			for (long j = 0; j < A[i].size(); j++)
			{
				ILE[A[i].at(j)]--;
			}
			continue;
		}*/
		if ((!C[i]))                // Szukamy nieodwiedzonego jeszcze wierzchołka
		{
			if (ILE[i] >= d)
			{
				cn++;                  // Zwiększamy licznik składowych
				S.push(i);             // Na stosie umieszczamy numer bieżącego wierzchołka
				C[i] = cn;             // i oznaczamy go jako odwiedzonego i ponumerowanego
				zbior.push_back(i);
				while (!S.empty())      // Przechodzimy graf algorytmem DFS
				{
					v = S.top();         // Pobieramy wierzchołek
					S.pop();             // Usuwamy go ze stosu

					// Przeglądamy sąsiadów wierzchołka v

					for (long k = 0; k < A[v].size(); k++)
					{
						u = A[v].at(k);          // Numer sąsiada do u
						if (!C[u])
						{
							if (ILE[u] >= d)
							{
								S.push(u);       // Na stos idą sąsiedzi 
								C[u] = cn;       // i ponumerowani
								zbior.push_back(u);
							}
						}
					}
				}
			}
		}
	}
	/*for (j = 0; j < n; j++)
		cout << ILE[j] << " ";
	cout << endl;*/
	int ilosc = 0;
	if (!cn)
	{
		cout << "NIE";
	}
	else
	{
		for (i = 1; i <= cn; i++)
		{
			/*for (j = 0; j < n; j++)
			{
				if ((C[j] == i))
				{
					cout << setw(2) << j + 1 << " "; // Wierzchołki tej składowej
					ilosc++;
				}

			}
			cout << "ILOSC: " << ilosc << endl;*/
			cout << zbior.size() << endl;
			qsort(&zbior[0], zbior.size(), sizeof(long), compare);
			for (int k = 0; k < zbior.size(); k++)
			cout << zbior[k]+1 << " ";
		}
	}

	cout << endl;

	// Usuwamy tablicę list sąsiedztwa

	delete[] C;
	delete[] visited;
	getchar();
	getchar();
	return 0;
}