#include <algorithm>
#include <bitset>
#include <cassert>
#include <cctype>
#include <chrono>
#define _USE_MATH_DEFINES
#include <cmath>
#include <cstdio>
#include <cstring>
#include <ctime>
#include <deque>
#include <functional>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <utility>
#include <unordered_map>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(v) (v).begin(),(v).end()

const int INF = 0x3f3f3f3f;
const long long LINF = 0x3f3f3f3f3f3f3f3fLL;
const double EPS = 1e-8;
const int MOD = 1000000007; // 998244353;
const int dy[] = {1, 0, -1, 0}, dx[] = {0, -1, 0, 1};
/*-------------------------------------------------*/
struct Edge {
  int src, dst;
  Edge(int src, int dst) : src(src), dst(dst) {}
};

struct SCC {
  vector<int> id;
  vector<vector<int> > vertices;
  vector<vector<Edge> > comp;

  SCC(const vector<vector<Edge> > &graph) : graph(graph) {
    n = graph.size();
    rev_graph.resize(n);
    REP(i, n) for (const Edge &e : graph[i]) {
      rev_graph[e.dst].emplace_back(e.dst, e.src);
    }
    used.assign(n, false);
    id.assign(n, -1);
    REP(i, n) {
      if (!used[i]) dfs(i);
    }
    int now = 0;
    for (int i = n - 1; i >= 0; --i) {
      if (id[order[i]] == -1) {
        vertices.emplace_back();
        rev_dfs(order[i], now++);
      }
    }
    comp.resize(now);
    REP(i, n) for (const Edge &e : graph[i]) {
      if (id[i] != id[e.dst]) comp[id[i]].emplace_back(id[i], id[e.dst]);
    }
    // REP(i, now) sort(ALL(vertices[i]));
  }

private:
  int n;
  vector<vector<Edge> > graph, rev_graph;
  vector<bool> used;
  vector<int> order;

  void dfs(int ver) {
    used[ver] = true;
    for (const Edge &e : graph[ver]) {
      if (!used[e.dst]) dfs(e.dst);
    }
    order.emplace_back(ver);
  }

  void rev_dfs(int ver, int now) {
    id[ver] = now;
    vertices[now].emplace_back(ver);
    for (Edge &e : rev_graph[ver]) {
      if (id[e.dst] == -1) rev_dfs(e.dst, now);
    }
  }
};

struct Xor128 {
  int rand() {
    unsigned t = x ^ (x << 11);
    x = y; y = z; z = w; w = (w ^ (w >> 19)) ^ (t ^ (t >> 8));
    return static_cast<int>(w);
  }
  int rand(int ub) {
    int res = rand() % ub;
    return (res < 0 ? res + ub : res);
  }
  int rand(int lb, int ub) { return lb + rand(ub - lb); }
  long long randll() {
    unsigned long long res = static_cast<unsigned long long>(rand()) << 32;
    return static_cast<long long>(res | rand());
  }
  long long randll(long long ub) {
    long long res = randll() % ub;
    return (res < 0 ? res + ub : res);
  }
  long long randll(long long lb, long long ub) { return lb + rand(ub - lb); }
private:
  unsigned x = 123456789, y = 362436069, z = 521288629, w = static_cast<unsigned>(time(nullptr));
} xor128;

int main() {
  cin.tie(nullptr); ios::sync_with_stdio(false);
  // freopen("input.txt", "r", stdin);

  int n, m; cin >> n >> m;
  vector<vector<Edge> > graph(n);
  vector<int> a(m), b(m);
  REP(i, m) {
    cin >> a[i] >> b[i]; --a[i]; --b[i];
    graph[a[i]].emplace_back(a[i], b[i]);
  }
  SCC scc(graph);
  int mn = INF;
  REP(i, scc.comp.size()) {
    if (scc.vertices[i].size() > 2) mn = min(mn, (int)scc.vertices[i].size());
  }
  if (mn == INF) {
    cout << -1 << '\n';
    return 0;
  }
  vector<int> v;
  REP(i, scc.comp.size()) {
    if (scc.vertices[i].size() == mn) {
      for (int e : scc.vertices[i]) v.emplace_back(e);
      break;
    }
  }
  sort(ALL(v));
  unordered_map<int, int> mp, rev;
  for (int e : v) {
    int tmp = mp.size();
    mp[e] = tmp;
    rev[tmp] = e;
  }
  int sz = v.size();
  vector<vector<int> > g(sz);
  REP(i, m) {
    if (mp.count(a[i]) == 1 && mp.count(b[i]) == 1) {
      g[mp[a[i]]].emplace_back(mp[b[i]]);
    }
  }
  while (true) {
    // REP(i, sz) {
    //   cout << i << ": ";
    //   for (int e : g[i]) cout << e << ' ';
    //   cout << '\n';
    // }
    // cout << '\n';
    int mx = 1;
    REP(i, sz) mx = max(mx, (int)g[i].size());
    if (mx == 1) break;
    int s;
    for (s = 0; s < sz; ++s) {
      if (g[s].size() == mx) break;
    }
    vector<bool> visited(sz, false);
    int pos = g[s][xor128.rand(g[s].size())];
    vector<int> ver{s, pos};
    visited[s] = visited[pos] = true;
    while (true) {
      int nx = g[pos][0];
      if (visited[nx]) {
        reverse(ALL(ver));
        while (true) {
          if (ver.back() == nx) {
            fill(ALL(visited), false);
            for (int e : ver) visited[e] = true;
            break;
          }
          ver.pop_back();
        }
        break;
      } else {
        ver.emplace_back(nx);
        visited[nx] = true;
      }
      pos = nx;
    }
    mp.clear();
    unordered_map<int, int> nx_rev;
    REP(i, sz) {
      if (visited[i]) {
        // cout << i << ' ' << rev[i] << '\n';
        int tmp = mp.size();
        mp[i] = tmp;
        nx_rev[tmp] = rev[i];
      }
    }
    swap(rev, nx_rev);
    vector<int> ai, bi;
    REP(i, sz) {
      if (mp.count(i) == 0) continue;
      for (int e : g[i]) {
        if (mp.count(e) == 1) {
          ai.emplace_back(mp[i]);
          bi.emplace_back(mp[e]);
        }
      }
    }
    sz = mp.size();
    g.assign(sz, vector<int>());
    REP(i, ai.size()) g[ai[i]].emplace_back(bi[i]);
  }
  cout << sz << '\n';
  for (auto pr : mp) cout << rev[mp[pr.first]] + 1 << '\n';
  // for (auto pr : mp) cout << rev[pr.first] + 1 << '\n';
  return 0;
}


Measured memory_bytes: 640