#include <bits/stdc++.h>

#define REP(i,n) for (int i=0;i<(n);++i)

using namespace std;

enum value_class_type {
    finite_class,
    pos_inf_class,
    neg_inf_class
};

template <class T>
struct non_standard {
    value_class_type value_class;
    T value;

    non_standard(T value) : value_class(value_class_type::finite_class), value(value) { }

    non_standard(value_class_type value_class, T value) : value_class(value_class), value(value) { }

    inline bool is_finite() const {
        return value_class == value_class_type::finite_class;
    }

    inline bool is_pos_inf() const {
        return value_class == value_class_type::pos_inf_class;
    }

    inline bool is_neg_inf() const {
        return value_class == value_class_type::neg_inf_class;
    }

    static inline non_standard pos_inf() {
        return non_standard(value_class_type::pos_inf_class, 0);
    }

    static inline non_standard neg_inf() {
        return non_standard(value_class_type::neg_inf_class, 0);
    }

    friend std::ostream& operator<<(std::ostream &os, const non_standard &x) {
        if (x.is_finite()) {
            os << x.value;
        } else if (x.is_pos_inf()) {
            os << "INF";
        } else if (x.is_neg_inf()) {
            os << "-INF";
        }
        return os;
    }
};

struct edge {
    typedef size_t weight_type;

    size_t m_to;

    edge(size_t to) : m_to(to) { }

    inline size_t to() const { return m_to; }

    inline weight_type weight() const { return 1; }

    friend std::ostream& operator<<(std::ostream &os, const edge &e) {
        os << "{ to: " << e.m_to << " }";
        return os;
    }
};

template <typename Weight>
struct weighted_edge : public edge {
    using weight_type = Weight;

    weight_type m_weight;

    weighted_edge(size_t to, weight_type weight) : edge(to), m_weight(weight) { }

    inline weight_type weight() const { return m_weight; }

    friend std::ostream& operator<<(std::ostream &os, const weighted_edge &e) {
        os << "{ to: " << e.m_to << ", weight = " << e.m_weight << " }";
        return os;
    }
};

template <class Edge>
struct graph {
    using edge_type = Edge;

    const size_t m_n_vertices;
    std::vector<std::vector<edge_type>> m_edges;

    graph(size_t n_vertices) : m_n_vertices(n_vertices), m_edges(n_vertices) { }

    inline size_t n_vertices() const { return m_n_vertices; }

    inline void add_edge(size_t from, size_t to, typename edge_type::weight_type weight) {
        m_edges[from].emplace_back(to, weight);
    }

    inline void add_edge(size_t from, size_t to) {
        m_edges[from].push_back(to);
    }

    inline void add_edge(size_t from, const edge_type &e) {
        m_edges[from].emplace_back(e);
    }

    inline void add_biedge(size_t v0, size_t v1, typename edge_type::weight_type weight) {
        m_edges[v0].emplace_back(v1, weight);
        m_edges[v1].emplace_back(v0, weight);
    }

    inline void add_biedge(size_t v0, size_t v1) {
        m_edges[v0].push_back(v1);
        m_edges[v1].push_back(v0);
    }

    inline std::vector<edge_type> edges_from(size_t v) const {
        return m_edges[v];
    }
};

template <class Graph>
std::vector<non_standard<typename Graph::edge_type::weight_type>> dijkstra(const Graph &g, size_t start) {
    using Edge = typename Graph::edge_type;
    using Weight = typename Edge::weight_type;
    using ExtendedWeight = non_standard<Weight>;
    using P = std::pair<Weight, size_t>;

    std::vector<ExtendedWeight> dp(g.n_vertices(), ExtendedWeight::pos_inf());

    std::priority_queue<P, std::vector<P>, std::greater<P>> q;

    dp[start] = ExtendedWeight(0);
    q.emplace(dp[start].value, start);

    while (!q.empty()) {
        Weight w0;
        size_t v0;
        std::tie(w0, v0) = q.top();
        q.pop();

        if (dp[v0].value < w0)
            continue;

        for (const Edge &e: g.edges_from(v0)) {
            size_t v1 = e.to();
            Weight w1 = w0 + e.weight();
            if (dp[v1].is_pos_inf() || dp[v1].value > w1) {
                dp[v1] = w1;
                q.emplace(dp[v1].value, v1);
            }
        }
    }

    return dp;
}

int main() {
    cin.tie(0);
    ios::sync_with_stdio(false);

    using Graph = graph<edge>;
    using ExtWeight = non_standard<size_t>;

    int N, M;
    cin >> N >> M;
    Graph g(N);
    REP(i, M) {
        int A, B;
        cin >> A >> B;
        --A;
        --B;
        g.add_edge(A, B);
    }

    vector<vector<ExtWeight>> dist(N);
    REP(u, N) {
        dist[u] = dijkstra(g, u);
    }

    const int INF = N + 1;
    int min_cycle_cost = INF;
    int min_cycle_vertex = -1;
    REP(u, N) {
        for (const edge &e: g.edges_from(u)) {
            int v = e.to();
            ExtWeight d = dist[v][u];
            if (d.is_finite() && min_cycle_cost > d.value) {
                min_cycle_cost = d.value + 1;
                min_cycle_vertex = u;
            }
        }
    }

    if (min_cycle_cost == INF) {
        cout << -1 << endl;
    } else {
        cout << min_cycle_cost << '\n';
        int u = min_cycle_vertex;
        int cost = min_cycle_cost;
        while (cost--) {
            cout << (u + 1) << '\n'; // 1-based indexing
            for (const edge &e: g.edges_from(u)) {
                int v = e.to();
                ExtWeight d = dist[v][min_cycle_vertex];
                if (d.is_finite() && d.value == cost) {
                    u = v;
                    break;
                }
            }
        }
        cout << flush;
    }

    return 0;
}


Measured memory_bytes: 16000