#define _CRT_SECURE_NO_WARNINGS

#include <cstdio>
#include <stdio.h>
#include <iostream>
#include <string.h>
#include <math.h>
#include <algorithm>
#include <vector>
#include <stack>
#include <map>

typedef long long lLong;
typedef unsigned int uInt;
typedef unsigned long uLong;
typedef unsigned long long ulLong;
typedef std::vector<int> vi;
typedef std::vector<std::vector<int>*> vvi;

typedef long long unsigned LLU;
typedef long long LL;

using namespace std;

typedef struct Skrzyzowanie
{
	int Id;
	int Index;
	int Licznik;
	bool CzyOdwiedzono;
	bool CzyCzescStosu;
	bool CzyJestWCyklu;
	int LowestIndex;
	int LastSearchRootId;	
	vector<Skrzyzowanie*> Nastepne;
} Skrzyzowanie;



class PrzypadekTestowy
{
private:	
	vector<Skrzyzowanie> _skrzyzowania;
	int _dfsCount;
	vector<int> _stos;
	map<int,vi> _znalezioneCykle;
	int _liczbaZnalezionychCykli;

	inline void Reset()
	{	
		_skrzyzowania.clear();
		_liczbaZnalezionychCykli = 0;
	}
	inline void WczytajGraf(FILE *input)
	{	
		_skrzyzowania.resize(n);
		int licznik = 0;
		for (Skrzyzowanie &skrzyzowanie : _skrzyzowania)
		{
			skrzyzowanie.Id = licznik;			
			skrzyzowanie.Licznik = 0;
			skrzyzowanie.CzyOdwiedzono = false;		
			skrzyzowanie.CzyCzescStosu = false;		
			skrzyzowanie.CzyJestWCyklu = false;
			skrzyzowanie.LastSearchRootId = -1;
			licznik++;
		}
		for (uInt i = 0; i < m; i++)
		{				
			int a, b;
			fscanf(input, "%d %d", &a,&b);		
			_skrzyzowania[a - 1].Nastepne.push_back(&_skrzyzowania[b - 1]);
		}
	}
		
	inline void WczytajWspolczynniki(FILE *input)
	{
		fscanf(input, "%d %d\n", &n, &m);
	}
	
	inline void ZapamietajCykl(int rootId)
	{
		if (!_stos.empty())
		{			
			vi& cykl = _znalezioneCykle[rootId];			
			_liczbaZnalezionychCykli++;
			for (int id : _stos)
			{
				Skrzyzowanie& s = _skrzyzowania[id];								
				s.CzyJestWCyklu = true;				
				cykl.push_back(s.Id);
				s.Licznik++; //licznik w ilu cyklach vertex wystapil
			}			
		}
	}

	bool Dfs(int id, int rootId)
	{		
		Skrzyzowanie& v = _skrzyzowania[id];
		v.LowestIndex = _dfsCount++;
		v.Index = v.LowestIndex;
		
		//if (v.CzyOdwiedzono == false)
		if (v.LastSearchRootId !=rootId)
		{			
			_stos.push_back(v.Id);
			v.LastSearchRootId = rootId;
			v.CzyOdwiedzono = true;
			v.CzyCzescStosu = true;	

			if (v.Nastepne.size() > 0)
			{
				for (Skrzyzowanie* s : v.Nastepne)
				{
					if (s->Id == rootId)
					{
						//znaleziono cykl
						ZapamietajCykl(rootId);
						return true;
					}
					else if (s->LastSearchRootId!=rootId) //bylo czy nie parwda ze odwiedzono
					//else if (!s->CzyOdwiedzono)
					{
						if (Dfs(s->Id, rootId)) return true;
						v.LowestIndex = min(v.LowestIndex, s->LowestIndex);
						
					}
					else if (s->CzyJestWCyklu && s->LastSearchRootId==v.LastSearchRootId)
					{	
						//odwiedzono i nie jest rootem - wiec nie powtarzamy tej sciezki
						v.LowestIndex = min(v.LowestIndex, s->Index);
						//return true;
					}
					//return true;
				}
			}
			v.CzyCzescStosu = false;
			_stos.pop_back();
		}						
		return false;
	}

	bool Dfs()
	{		
		_dfsCount = 0;
		for (Skrzyzowanie& s : _skrzyzowania)
		{
			Dfs(s.Id, s.Id);
			_dfsCount = 0;
			_stos.clear();
		}					
		return false;
	}	

public:
	unsigned int n; //liczba skrzyżowań 
	unsigned int m; //liczba dróg
	int wynik;

	inline void WczytajPrzypadekTestowy()
	{
		WczytajPrzypadekTestowy(stdin);
	}
	inline void WczytajPrzypadekTestowy(FILE *input)
	{
		Reset();
		WczytajWspolczynniki(input);
		WczytajGraf(input);		
	}	

	inline void Rozwiaz()
	{		
		Dfs();
	}

	inline void WypiszWynik()
	{
		vector<Skrzyzowanie *> wynik;
		for (Skrzyzowanie& p : _skrzyzowania)
		{
			if (_liczbaZnalezionychCykli == p.Licznik)
			{
				wynik.push_back(&p);
			}
		}

		if (_liczbaZnalezionychCykli == 0)
		{
			printf("NIE\n");
		}
		else
		{			
			printf("%d\n", wynik.size());
			if (wynik.size() > 0)
			{
				int cnt = 0;
				for (Skrzyzowanie* p : wynik)
				{
					if (cnt++ > 0) printf(" ");
					printf("%d",p->Id+1);
				}
				printf("\n");
			}
		}				
	}	
};


int main(int argc, char **argv)
{		
	// Do celow testowych
	FILE *in=stdin;
	if(argc>1)
	{		
		in = fopen(argv[1],"rt");
		if(NULL==in)
		{
			in=stdin;
		}
	}
	///////////////////////////////////////////	
	PrzypadekTestowy przypadek;		
	przypadek.WczytajPrzypadekTestowy(in);		
	przypadek.Rozwiaz();
	przypadek.WypiszWynik();
	return 0;
}
