#include <iostream>
#include <cstdio>
#include <vector>
#include <cmath>
#include <cstring>
#include <numeric>
#include <algorithm>
#include <functional>
#include <array>
#include <map>
#include <queue>
#include <time.h>
#include <limits.h>
#include <set>
#include <stack>
#include <random>
#include <complex>
#include <unordered_map>
#include <unordered_set>
#define rep(i,s,n) for(int i = (s); (n) > i; i++)
#define REP(i,n) rep(i,0,n)
#define RANGE(x,a,b) (min(a,b) <= (x) && (x) <= max(a,b)) //hei
#define DUPLE(a,b,c,d) (RANGE(a,c,d) || RANGE(b,c,d) || RANGE(c,a,b) || RANGE(d,a,b))
#define INCLU(a,b,c,d) (RANGE(a,c,d) && (b,c,d))
#define PW(x) ((x)*(x))
#define ALL(x) (x).begin(), (x).end()
#define RALL(x) (x).rbegin(), (x).rend()
#define MODU 1000000007LL
#define bitcheck(a,b)   ((a >> b) & 1)
#define bitset(a,b)      ( a |= (1 << b))
#define bitunset(a,b)    (a &= ~(1 << b))
#define MP(a,b) make_pair((a),(b))
#define Manh(a,b) (abs((a).first-(b).first) + abs((a).second - ((b).second))
#define pritnf printf
#define scnaf scanf
#define itn int
#define PI 3.141592653589


#define izryt bool
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
template<typename A, size_t N, typename T>
void Fill(A(&array)[N], const T & val) {
	std::fill((T*)array, (T*)(array + N), val);
}
pll Dir[4] = {
	{ -1 ,0 },{ 0 , 1 },{ 1 ,0 },{ 0 ,-1 }
};

//[a, b)
#define Getsum(ar, a,b) (ar[b] - ar[a])
#define INF 10000000000000000LL
#define chmax(a,b) a = max(a,b)
#define chmin(a,b) a = min(a,b)

struct Edge {
	int from, to;
	ll w;
	bool operator<(const Edge& rhs) const {
		return MP(w, MP(from, to)) < MP(rhs.w, MP(rhs.from, rhs.to));
	}

};

ll gcd(ll a, ll b) {
	if (b == 0) return a;
	return gcd(b, a % b);
}
class Graph {
public:
	int vn = 0;
	vector<vector<pii>> g;

	Graph(int n) {
		vn = n;
		g.resize(n);
	}
	virtual void con(int a, int b, int w) = 0;
};
class BiDGraph : public Graph {//無向
public:
	BiDGraph(int n) : Graph(n) {}

	void con(int a, int b, int w = 1) {
		g[a].push_back({ b,w });
		g[b].push_back({ a, w });
	}
};
class DGraph : public Graph {//有向
public:
	DGraph(int n) : Graph(n) {}
	void con(int a, int b, int w = 1) {
		g[a].push_back({ b,w });

	}
};

struct UnionFind {
	vector<int> data;
	UnionFind(int size) : data(size, -1) { }
	bool unionSet(int x, int y) { //ｘの入ってる集合と yの入ってる集合を併合
		x = root(x); y = root(y);
		if (x != y) {
			if (data[y] < data[x]) swap(x, y);
			data[x] += data[y]; data[y] = x;
		}
		return x != y;
	}
	bool findSet(int x, int y) { //xとyが同じ集合に入っているかどうかを判定
		return root(x) == root(y);
	}
	int root(int x) {
		return data[x] < 0 ? x : data[x] = root(data[x]);
	}
	bool isroot(int x) {
		return data[x] < 0;
	}
	int size(int x) {
		return -data[root(x)];
	}
};
void SCC(DGraph & g, vector<int> & scc) {
	vector<int>  orb(g.vn, -1);
	scc.resize(g.vn, -1);
	int cc = 0;
	int k = 0;
	vector<bool> used(g.vn);
	stack<int> st;
	function<int(int)> dfs = [&](int cur) {
		int low = orb[cur] = ++k;
		st.push(cur);
		used[cur] = 1;
		for (auto itr : g.g[cur]) {
			if (orb[itr.first] == -1)
				low = min(low, dfs(itr.first));
			else if (used[itr.first])
				low = min(low, orb[itr.first]);
		}
		if (low == orb[cur]) {
			while (1) {
				int cp = st.top(); st.pop();
				used[cp] = 0;
				scc[cp] = cc;
				if (cp == cur)
					break;
			}
			cc++;
		}
		return low;
	};
	REP(i, g.vn)
		if (orb[i] < 0)
			dfs(i);
}

vector<int> solve(DGraph & g) {

	vector<int> reached(g.vn), can(g.vn);
	vector<int> ans;

	stack<int> path;

	function<bool(int)> dfs = [&](int cur) {


		if (can[cur]) {
			return false;
		}

		path.push(cur);
		reached[cur] = path.size();

		int Maxdep = 0, utl = -1;

		for (auto edges : g.g[cur]) {
			if (Maxdep < reached[edges.first])
				utl = edges.first;
			Maxdep = max(Maxdep, reached[edges.first]);
			

			can[edges.first]++;
		}

		if (Maxdep > 0) {
			while (1) {
				int cs = path.top();
				path.pop();
				ans.push_back(cs);
				if (cs == utl) {
					break;
				}
			}
			return true;
		}

		for (auto edges : g.g[cur]) {
			can[edges.first]--;
			bool res = dfs(edges.first);
			can[edges.first]++;
			if (res) return true;
		}

		reached[cur] = 0;
		path.pop();
		return false;
	};

	dfs(0);


	return ans;
}

signed main(void) {
	int n, m;
	cin >> n >> m;
	vector<pii> edges(m);
	DGraph g(n);
	REP(i, m) {
		int a, b;
		cin >> a >> b;
		a--, b--;
		g.con(a, b);
		edges[i] = MP(a, b);
	}
	vector<int> scc;
	map<int, set<int>> grp;
	SCC(g, scc);
	int Max = 0;
	REP(i, n) {
		Max = max(Max, scc[i]);
		grp[scc[i]].insert(i);

	}

	REP(i, Max + 1) {
		DGraph ng(grp[i].size());

		map<int, int> vnum, ivnum;
		int cou = 0;
		for (auto v : grp[i]) {
			vnum[v] = cou;
			ivnum[cou] = v;
			cou++;

		}
		for (auto ed : edges) {
			if (grp[i].find(ed.first) != grp[i].end() && grp[i].find(ed.second) != grp[i].end()) {
				ng.con(vnum[ed.first], vnum[ed.second]);

			}
		}

		if (ng.vn) {
			vector<int> ans = solve(ng);

			if (ans.size()) {
				cout << ans.size() << endl;
				for (auto itr : ans) {
					cout << ivnum[itr] + 1 << endl;
				}
				return 0;

			}
		}
	}
	cout << -1 << endl;

	return 0;
}


Measured memory_bytes: 640