#include<algorithm>
#include<chrono>
#include<climits>
#include<functional>
#include<numeric>
#include<iomanip>
#include<iostream>
#include<map>
#include<queue>
#include<random>
#include<set>
#include<stack>
#include<unordered_map>
#include<unordered_set>
#include<vector>
#include<cassert>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<string>
// #include<bits/stdc++.h>
using namespace std;
 
struct Debug{
    int cnt = 0;
    bool on = false;
    char debug[10] = "debug";
    template<class T>
    Debug & operator<<(const T & v) {
        if(on && cnt++ == 0) cerr << "debug: ";
        if(on) cerr << v << ' ';
        return *this;
    }
    Debug & operator<<(ostream&(*pManip)(ostream&)) {
        if(on) cerr << (*pManip);
        cnt = 0;
        return *this;
    }
} debug;
#define rep(i, a, b) for(auto i = (a); i < (b); i++)
#define rrep(i, a, b) for(auto i = (a); i > (b); i--)
#define all(v) (v).begin(), (v).end()
#define print(v) {if(debug.on){for(auto x : v) debug << x; debug << endl;}}
#define printn(v, n) {if(debug.on){for(int _i = 0; _i < n; _i++) debug << *(v + _i); debug << endl;}}
 
typedef unsigned long long ull;
typedef long long ll;
 
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef pair<double, double> pdd;
 
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<vvi> vvvi;
typedef vector<pii> vpii;

const int MAXN = 1e3 + 20;
unordered_set<int> graph[MAXN];
// int vis[MAXN] = {};
int tin[MAXN] = {}, tout[MAXN] = {};
int parent[MAXN] = {};
int t = 1;
int resnode = -2;

bool dfs(int i, int p) {
	tin[i] = t++;
	bool valid = false;
	for(int j : graph[i]) {
		if(j == p || tout[j] > 0 || graph[j].count(i) || !tin[j]) continue;
		valid = true;
		break;
	}
	if(valid) {
		int jj = -1;
		for(int j : graph[i]) {
			if(j == p || tout[j] > 0 || graph[j].count(i) || !tin[j]) continue;
			if(jj == -1 || tin[j] > tin[jj])
				jj = j;
		}
		parent[jj] = i;
		resnode = jj;
		tout[i] = t++;
		return true;
	}
	else {
		for(int j : graph[i]) {
			if(j == p || tin[j] || graph[j].count(i)) continue;
			parent[j] = i;
			if(dfs(j, i)) {
				tout[i] = t++;
				return true;
			}
			parent[j] = -1;
		}
	}
	tout[i] = t++;
	return false;
}

int main(int argc, char * argv[]) {
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
    if(argc > 1 && !strcmp(argv[1], debug.debug)) debug.on = true;
 	
 	int n, m, u, v;
    cin >> n >> m;
    for(int i = 0; i < m; i++) {
    	cin >> u >> v;
    	u--; v--;
    	graph[u].insert(v);
    }
    for(int i = 0; i < n; i++) {
    	for(int j : graph[i]) {
    		if(graph[j].count(i)) {
    			cout << 2 << endl << i + 1 << endl << j + 1 << endl;
    			return 0;
    		}
    	}
    }
    fill(parent, parent + n, -1);
    for(int i = 0; i < n; i++) {
    	if(!tin[i]) {
    		if(dfs(i, -1)) {
    			break;
    		}
    	}
    }

    if(resnode == -2){
    	cout << -1 << endl;
    	return 0;
    }
    vector<int> ret, ret1;
    for(int i = parent[resnode];; i = parent[i]) {
    	// cout << i + 1 << ' ';
    	ret.push_back(i);
    	if(i == resnode)
    		break;
    }
    print(ret);

    reverse(all(ret));
    int l = ret.size();
    unordered_set<int> rem(all(ret));
    ret.insert(ret.end(), all(ret));

    for(int i = 0; i < l;) {
    	ret1.push_back(ret[i]);

    	for(int j = i + l - 2; j > i; j--) {
    		if(rem.count(ret[j]) && graph[ret[i]].count(ret[j])) {
    			i = j;
    			for(int jj = j - 1; jj > i; jj--)
    				if(rem.count(ret[j]))
	    				rem.erase(ret[j]);
    			break;
    		}
    	}
    	debug << i << endl;
    }


    sort(all(ret1));
    cout << ret1.size() << endl;
    for(auto x : ret1) 
    	cout << x + 1 << endl;

    return 0;
}























Measured memory_bytes: 512