#include <stdio.h>
#include <set>
#include <map>
#include <unordered_map>
#include <unordered_set>
#include <list>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <vector>
#include <string>
#include <bitset>
#include <cctype>
#include <cstdlib>
#include <cstring>
#include <utility>
#include <numeric>
#include <complex>
#include <sstream>
#include <fstream>
#include <iomanip>
#include <cassert>
#include <iostream>
#include <iterator>
#include <algorithm>
#include <functional>
using namespace std;
typedef long long ll;
const double EPS = 1e-9;
typedef vector<int> vint;
typedef vector<vector<int>> v2int;
typedef vector<ll> vll;
typedef vector<vector<ll>> v2ll;
typedef list<int> liint;
typedef pair<int, int> pint;
const int INF = int(2e9);
const ll LINF = ll(2e9) * ll(2e9);
#define rep(i, n) REP(i, 0, n)
#define ALL(v) v.begin(), v.end()
#define MSG(a) cout << #a << " " << a << endl;
#define REP(i, x, n) for(int i = x; i < n; i++)
template<class T, class C> void chmax(T& a, C b) { a > b ? : a = b; }
template<class T, class C> void chmin(T& a, C b) { a < b ? : a = b; }


unordered_map<int, unordered_set<int>> make_induced_subgraph(unordered_map<int, unordered_set<int>>& graph, 
                                                             unordered_set<int>& vset) {
    unordered_map<int, unordered_set<int>> sub_graph;
    for (auto &v : vset) {
        for (auto &u : graph[v]) {
            if (vset.find(u) != vset.end())
                sub_graph[v].insert(u);
        }
    }
    return sub_graph;
}

bool in_cond(unordered_map<int, unordered_set<int>>& graph) {
    unordered_map<int, int> in_cnt, out_cnt;
    
    for (auto &ed : graph) {
        if (ed.second.size() != 1) return false;
        out_cnt[ed.first]++;
        in_cnt[*ed.second.begin()]++;
    }
    for (auto &ed : graph) {
        if (out_cnt[ed.first] != 1) return false;
        if (in_cnt[ed.first] != 1) return false;
    }
    return true;

}

unordered_set<int> vset;
bool search_cycle(unordered_map<int, unordered_set<int>>& graph,
    unordered_set<int> visited_set, vint& root, int nd, int max_nodes) {
    visited_set.insert(nd);
    
    for (auto & adj : graph[nd]) {
        if (visited_set.find(adj) != visited_set.end()) {
            vset.clear();
            for(int i = root.size() - 1; i >= 0; i--) {
                vset.insert(root[i]);
                if (adj == root[i]) break;
            }
            if (vset.size() <= max_nodes) return true;
            return false;
        }
            
        root.push_back(adj);
        bool is_find = search_cycle(graph, visited_set, root, adj, max_nodes);
        if (is_find == true) return true;
        root.pop_back();
        
    }
    visited_set.erase(nd);
    return false;
}

int main() {
    int N, M;
    cin >> N >> M;
    unordered_map<int, unordered_set<int>> graph;
    rep(i, M) {
        int a, b;
        cin >> a >> b;
        graph[a].insert(b);
    }
    if (M == 0) {
        cout << -1 << endl;
        return 0;
    }
    REP(i, 1, N + 1) vset.insert(i);
    auto sub_graph = graph;
    while (1) {
        //unordered_set<int> vset;
        if (in_cond(sub_graph) == true) {
            cout << sub_graph.size() << endl;
            for (auto & ed : sub_graph) {
                cout << ed.first << endl;
            }
            return 0;
        }

        unordered_set<int> is_visited;
        
        bool is_find;
        
        REP(i, 1, N + 1) {
            vint root(1, i);
            if (is_visited.find(i) == is_visited.end()) {
                is_find = search_cycle(graph, is_visited, root, i, graph.size() - 1);
            }
            if (is_find == true) break;
        }
        if (is_find == false) break;
        sub_graph = make_induced_subgraph(graph, vset);
        
        graph = sub_graph;
    }
    cout << -1 << endl;
    return 0;
}

Measured memory_bytes: 21952