#define _CRT_SECURE_NO_WARNINGS
#include <iostream>
#include <cmath>
#include <algorithm>
#include <vector>
#include <numeric>
#include <queue>
#include <stack>
#include <map> 
#include <set>
#include <string>
#include <functional>
#include <list>
#include <random>
#include <time.h>
#include <iomanip>
#include <assert.h>
#include <numeric>
#include <new>
#define BIT(nr) (1ULL << (nr))
#define int long long
//#define ll long long
#define double long double
#define mod 1000000007
#define MAXN (int)1e+5 * 2+1
#define LL_MAX 9223372036854775807	//ない環境用
#define LL_HALFMAX 9223372036854775807 / 2	//ない環境用
#define MIN -(9223372036854775807 / 2)
#define REP(i,a,n) for(int i=(a); i<(int)(n); i++)
#define rep(i,n) REP(i,0,n)
#define FOR(it,c) for(__typeof((c).begin()) it=(c).begin(); it!=(c).end(); ++it)
#define ALLOF(c) (c).begin(), (c).end()
#define REPS(i,x) for(int i=1;i<=(int)(x);i++)
#define RREP(i,x) for(int i=((int)(x)-1);i>=0;i--)
#define RREPS(i,x) for(int i=((int)(x));i>0;i--)
#define repl(i,a,b) for(int i=(int)(a);i<(int)(b);i++)
#define mp make_pair
template<typename T1, typename T2> inline void chmin(T1 & a, T2 b) { if (a > b) a = b; }
template<typename T1, typename T2> inline void chmax(T1& a, T2 b) { if (a < b) a = b; }


using namespace std;

using Weight = int;
using Flow = int;
struct Edge {
    int src, dst;
    Weight weight;
    Flow cap;
    Edge() : src(0), dst(0), weight(0) {}
    Edge(int s, int d, Weight w) : src(s), dst(d), weight(w) {}
};
using Edges = std::vector<Edge>;
using Graph = std::vector<Edges>;
using Array = std::vector<Weight>;
using Matrix = std::vector<Array>;

void add_edge(Graph &g, int a, int b, Weight w = 1) {
    g[a].emplace_back(a, b, w);
    g[b].emplace_back(b, a, w);
}
void add_arc(Graph &g, int a, int b, Weight w = 1) { g[a].emplace_back(a, b, w); }


signed main() {
    int N, M;
    cin >> N >> M;
    Graph G(N + 1);
    rep(i, M) {
        int A, B;
        cin >> A >> B;
        add_arc(G, A, B);
    }

    vector<bool> seen(N+1, false), finished(N+1, false);
    vector<int> hist;

    //pos: 閉路の最初のノード
    int pos = -1;
    function<void(int)> dfs = [&](int nowNode) {
        seen[nowNode] = true;
        hist.push_back(nowNode);
        for (auto e : G[nowNode]) {
            int nv = e.dst;
            if (finished[nv]) {
                continue;
            }

            if (seen[nv] && !finished[nv]) {
                pos = nv;
                return;
            }

            dfs(nv);

            if (pos != -1) return;
        }
        hist.pop_back();
        finished[nowNode] = true;
    };

    REPS(i, N) {
        pos = -1;
        dfs(i);
        if (pos != -1) break;
    }

    //閉路が無い
    if (pos == -1) {
        cout << -1 << "\n";
        return 0;
    }

    vector<int> cycle;
    while (!hist.empty()) {
        int t = hist.back();
        cycle.push_back(t);
        hist.pop_back();
        if (t == pos) break;
    }
    reverse(ALLOF(cycle));

    //弦を見て閉路を小さくする
    while (true){
        int from = -1, to = -1;
        vector<int> ord(N+1, -1);

        //ord[i]: cycle におけるノードiのインデックス
        rep(i, cycle.size()) {
            ord[cycle[i]] = i;
        }
        rep(i, cycle.size()) {
            for (auto e : G[cycle[i]]) {
                int nv = e.dst;
                //cycle[(i+1)%cycle.size()] : サイクル上での次のノード(循環する)
                //次のノードじゃない行先がある -> もっと小さくできる
                if (nv != cycle[(i + 1) % cycle.size()] && ord[nv] != -1) {
                    from = i, to = ord[nv];
                }
            }
        }
        if (from == -1) break;

        vector<int> ncycle;

        //新規from, to から始める
        ncycle.push_back(cycle[from]);
        int id = to;
        while (id != from) {
            ncycle.push_back(cycle[id]);
            id = (id + 1) % cycle.size();
            
        }
        cycle = ncycle;

    }

    cout << cycle.size() << endl;
    for (auto v : cycle) cout << v << endl;

    return 0;
}


Measured memory_bytes: 384