#pragma GCC optimize("Ofast,unroll-loops,no-stack-protector,fast-math")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
//#pragma comment(linker, "/stack:200000000")
 
#include <bits/stdc++.h>
 
using namespace std;
 
typedef long long ll;
typedef unsigned long long ull;
typedef double ld;
typedef pair<int,int> pii;
typedef pair<ll,ll> pll;
typedef pair<ld,ld> pdd;
 
#define X first
#define Y second
 
//#include <boost/unordered_map.hpp>
//using namespace boost;
 
/*
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> rbtree;
rbtree T;
*/
 
using i32 = int;
using i64 = long long;
using u8 = unsigned char;
using u32 = unsigned;
using u64 = unsigned long long;
using f64 = double;
using f80 = long double;
//using i128 = __int128_t;
//using u128 = __uint128_t;
//using i128 = i64;
//using u128 = u64;
 
ll power(ll a, ll b, ll p)
{
	if (!b) return 1;
	ll t = power(a, b/2, p);
	t = t*t%p;
	if (b&1) t = t*a%p;
	return t;
}
 
ll exgcd(ll a, ll b, ll &x, ll &y)
{
	if (b == 0)
	{
		x = 1;
		y = 0;
		return a;
	}
	ll px, py;
	ll d = exgcd(b, a%b, px, py);
	x = py;
	y = px-a/b*py;
	return d;
}
 
template<class T>
inline void freshmin(T &a, const T &b)
{
	if (a > b) a = b;
}
 
template<class T>
inline void freshmax(T &a, const T &b)
{
	if (a < b) a = b;
}
 
//#define getchar getchar_unlocked
//#define putchar putchar_unlocked

#define FWRITE

namespace io
{

#ifndef FWRITE
#include <unistd.h>
#endif
const int BUFSIZE = 1<<20;

int isize, osize;
char ibuf[BUFSIZE+10], obuf[BUFSIZE+10];
char *is, *it, *os = obuf, *ot = obuf+BUFSIZE;

char getchar()
{
	if (is == it)
	{
		is = ibuf;
		#ifdef FWRITE
		it = ibuf+fread(ibuf, 1, BUFSIZE, stdin);
		#else
		it = ibuf+read(STDIN_FILENO, ibuf, BUFSIZE);
		#endif
		if (is == it) return EOF;
	}
	return *is ++;
}

char getalpha()
{
	char c = getchar();
	while (!isalpha(c)) c = getchar();
	return c;
}

void putchar(char c)
{
	*os ++ = c;
	if (os == ot)
	{
		#ifdef FWRITE
		fwrite(obuf, 1, BUFSIZE, stdout);
		#else
		write(STDOUT_FILENO, obuf, BUFSIZE);
		#endif
		os = obuf;
	}
}

int inp() {
	int x = 0, f = 0; char ch;
	for(ch = getchar(); !isdigit(ch); ch = getchar())
		if(ch == '-') f = 1;
	for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
	return f ? -x : x;
}

ll inp_ll() {
	ll x = 0; int f = 0; char ch;
	for(ch = getchar(); !isdigit(ch); ch = getchar())
		if(ch == '-') f = 1;
	for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
	return f ? -x : x;
}

template<class T>
bool read(T &x)
{
	x = 0;
	char ch = getchar();
	if (ch == EOF) return 0;
	for(; !isdigit(ch); )
	{
		ch = getchar();
		if (ch == EOF) return 0;
	}
	for(; isdigit(ch); x = x * 10 + ch - '0', ch = getchar());
	return 1;
}

template<class T>
void write(T x)
{
	static char s[22];
	static char *it = s+20;
	static char *end = s+20;
	
	if (x < 0)
	{
		putchar('-');
		x = -x;
	}
	
	do
	{
		*-- it = x%10+'0';
		x /= 10;
	}
	while (x);
	/*
	if (!x)
		*-- it = '0';
	while (x)
	{
		*-- it = x%10+'0';
		x /= 10;
	}
	*/
	for (; it < end; ++ it)
		putchar(*it);
}

template<>
void write(const char *s)
{
	for (; *s; ++ s) putchar(*s);
}

template<>
void write(char c)
{
	putchar(c);
}

template<class T, class V>
void write(T x, V y)
{
	write(x);
	write(y);
}

template<class T>
void writeln(T x)
{
	write(x);
	putchar('\n');
}

struct ender
{
	~ender()
	{
		if (os != obuf)
			#ifdef FWRITE
			fwrite(obuf, 1, os-obuf, stdout);
			#else
			write(STDOUT_FILENO, obuf, os-obuf);
			#endif
	}
}__ender;

}

template<class T>
void print(const T &a)
{
	for (auto x : a) printf("%d ", x); puts("");
}

const int MAXN = 2010;
const int MAXM = 4010;
const int MAXK = 6;
const int INF = 2000000000;
//const i64 INF = 2000000000000000000LL;
const int MOD = 1000000007;
const int INV2 = (MOD+1)/2;
//const int INV6 = power(6, MOD-2, MOD);

using namespace io;

//mt19937 rd(chrono::steady_clock::now().time_since_epoch().count());

#define rep(i,a,b) for (int i = (a), I = (b); i <= I; ++ i)

struct directed_graph
{
	int n;
	vector<vector<int>> v;
	
	directed_graph (int n = 0)
	{
		init(n);
	}
	void init(int n)
	{
		assert(n >= 0);
		this->n = n;
		v = vector<vector<int>>(n+1);
	}
	void addedge(int x, int y)
	{
		assert(1 <= x && x <= n);
		assert(1 <= y && y <= n);
		v[x].push_back(y);
	}
	void erase_multiedges()
	{
		for (int i = 1; i <= n; ++ i)
		{
			sort(v[i].begin(), v[i].end());
			v[i].erase(unique(v[i].begin(), v[i].end()), v[i].end());
		}
	}
	
	vector<int> in_degree()
	{
		vector<int> ret(n+1);
		for (int x = 1; x <= n; ++ x)
			for (auto y : v[x])
				ret[y] ++;
		return ret;
	}
	vector<int> topsort()
	{
		vector<int> deg = in_degree();
		vector<int> ret;
		queue<int> q;
		for (int i = 1; i <= n; ++ i)
			if (!deg[i]) q.push(i);
		while (!q.empty())
		{
			int x = q.front();
			q.pop();
			ret.push_back(x);
			for (auto y : v[x])
				if (!-- deg[y]) q.push(y);
		}
		return ret;
	}
	
	int times;
	vector<int> dfn, low, in;
	vector<int> st;
	int scc;
	vector<int> belong;
	void tarjan(int x)
	{
		dfn[x] = low[x] = ++ times;
		st.push_back(x);
		in[x] = 1;
		for (auto y : v[x])
		{
			if (!dfn[y])
			{
				tarjan(y);
				freshmin(low[x], low[y]);
			}
			else if (in[y])
				freshmin(low[x], dfn[y]);
		}
		if (dfn[x] == low[x])
		{
			scc ++;
			while (1)
			{
				int y = st.back();
				st.pop_back();
				in[y] = 0;
				belong[y] = scc;
				if (x == y) break;
			}
		}
	}
	directed_graph strong_connected_component()
	{
		times = 0;
		dfn = vector<int>(n+1);
		low = vector<int>(n+1);
		in = vector<int>(n+1);
		st = vector<int>();
		scc = 0;
		belong = vector<int>(n+1);
		for (int i = 1; i <= n; ++ i)
			if (!dfn[i]) tarjan(i);
		directed_graph ret(scc);
		for (int x = 1; x <= n; ++ x)
			for (auto y : v[x]) if (belong[x] != belong[y])
				ret.addedge(belong[x], belong[y]);
		// ret.erase_multiedges();
		return ret;
	}
};

struct undirected_graph
{
	int n;
	vector<pii> edge;
	undirected_graph (int n)
	{
		init(n);
	}
	void init(int n)
	{
		assert(n >= 0);
		this->n = n;
	}
	void addedge(int x, int y)
	{
		assert(1 <= x && x <= n);
		assert(1 <= y && y <= n);
		edge.push_back({x, y});
	}
};

struct tree
{
	const static int K = 1; // for LCA
	int n;
	vector<vector<int>> v;
	tree (const undirected_graph &G)
	{
		n = G.n;
		v = vector<vector<int>>(n+1);
		for (auto e : G.edge)
		{
			int x = e.X, y = e.Y;
			v[x].push_back(y);
			v[y].push_back(x);
		}
	}
	
	vector<int> r;
	int times;
	vector<int> X, Y;
	vector<int> dis;
	vector<array<int, K>> pre;
	void dfs(int x, int p)
	{
		X[x] = ++ times;
		for (auto y : v[x])
		{
			if (y == p) continue;
			dis[y] = dis[x]+1;
			pre[y][0] = x;
			dfs(y, x);
		}
		Y[x] = times;
	}
	void build_dfs_order(int root = 1)
	{
		assert(1 <= root && root <= n);
		r = vector<int>(n+1);
		X = vector<int>(n+1);
		Y = vector<int>(n+1);
		dis = vector<int>(n+1);
		pre = vector<array<int, K>>(n+1);
		times = 0;
		for (int i = 1; i <= n; ++ i)
			if (!X[i]) dfs(i, 0);
		for (int k = 1; k < K; ++ k)
			for (int i = 1; i <= n; ++ i)
				pre[i][k] = pre[pre[i][k-1]][k-1];
	}
	
	int getLCA(int x, int y)
	{
		assert(n <= 1<<K);
		if (dis[x] < dis[y]) swap(x, y);
		for (int k = K-1; k >= 0; -- k)
			if (dis[x]-dis[y] >= 1<<k)
				x = pre[x][k];
		if (x == y) return x;
		for (int k = K-1; k >= 0; -- k)
			if (pre[x][k] == pre[y][k])
			{
				x = pre[x][k];
				y = pre[y][k];
			}
		return pre[x][0];
	}
};

int n;
struct node
{
	int x, y, z;
}e[MAXM];
int g[MAXN][MAXN];

int F[MAXN];

int father(int x)
{
	return F[x] == x ? x : F[x] = father(F[x]);
}

void solve()
{
	n = inp();
	int m = inp();
	for (int i = 1; i <= n; ++ i)
		F[i] = i;
	undirected_graph G(n);
	for (int i = 1; i <= m; ++ i)
	{
		int x = inp();
		int y = inp();
		g[x][y] = 1;
		if (father(x) != father(y))
		{
			F[father(x)] = father(y);
			G.addedge(x, y);
			e[i] = {x, y, 1};
		}
		else
		{
			e[i] = {x, y, 0};
		}
	}
	tree T(G);
	T.build_dfs_order();
	
	vector<int> u(n+1);
	auto check = [&](const vector<int> &p) -> bool
	{
		int len = p.size();
		if (len <= 1) return false;
		for (int i = 0; i < len; ++ i)
			if (!g[p[i]][p[(i+1)%len]]) return false;
		int ans = 0;
		for (auto x : p) u[x] = 1;
		for (int i = 1; i <= m; ++ i)
			if (u[e[i].x] && u[e[i].y]) ans ++;
		for (auto x : p) u[x] = 0;
		return ans == len;
	};
	
	auto ok = [](vector<int> &p)
	{
		writeln(p.size());
		for (auto x : p) writeln(x);
	};
	
	for (int i = 1; i <= m; ++ i)
	{
		if (e[i].z) continue;
		int x = e[i].x, y = e[i].y;
		vector<int> ax, ay;
		while (x != y)
		{
			if (T.dis[x] > T.dis[y])
			{
				ax.push_back(x);
				x = T.pre[x][0];
			}
			else
			{
				ay.push_back(y);
				y = T.pre[y][0];
			}
		}
		reverse(ay.begin(), ay.end());
		{
			vector<int> p;
			for (auto c : ax) p.push_back(c);
			p.push_back(x);
			for (auto c : ay) p.push_back(c);
			if (check(p))
			{
				ok(p);
				return;
			}
			reverse(p.begin(), p.end());
			if (check(p))
			{
				ok(p);
				return;
			}
		}
		
	}
	writeln(-1);
}

int main()
{
	
	//for (int T = inp(); T --; )
		solve();
	
	return 0;
}


Measured memory_bytes: 9728