Problem:
Score : 600 points

Problem Statement

Given is a directed graph G with N vertices and M edges.

The vertices are numbered 1 to N, and the i-th edge is directed from Vertex A_i to Vertex B_i.

It is guaranteed that the graph contains no self-loops or multiple edges.

Determine whether there exists an induced subgraph (see Notes) of G such that the in-degree and out-degree of every vertex are both 1. If the answer is yes, show one such subgraph.

Here the null graph is not considered as a subgraph.

Notes

For a directed graph G = (V, E), we call a directed graph G' = (V', E') satisfying the following conditions an induced subgraph of G:

V' is a (non-empty) subset of V.

E' is the set of all the edges in E that have both endpoints in V'.

Constraints

1 \leq N \leq 1000

0 \leq M \leq 2000

1 \leq A_i,B_i \leq N

A_i \neq B_i

All pairs (A_i, B_i) are distinct.

All values in input are integers.

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
A_2 B_2
:
A_M B_M

Output

If there is no induced subgraph of G that satisfies the condition, print -1.
Otherwise, print an induced subgraph of G that satisfies the condition, in the following format:

K
v_1
v_2
:
v_K

This represents the induced subgraph of G with K vertices whose vertex set is \{v_1, v_2, \ldots, v_K\}. (The order of v_1, v_2, \ldots, v_K does not matter.)
If there are multiple subgraphs of G that satisfy the condition, printing any of them is accepted.

Sample Input 1

4 5
1 2
2 3
2 4
4 1
4 3

Sample Output 1

3
1
2
4

The induced subgraph of G whose vertex set is \{1, 2, 4\} has the edge set \{(1, 2), (2, 4), (4, 1)\}. The in-degree and out-degree of every vertex in this graph are both 1.

Sample Input 2

4 5
1 2
2 3
2 4
1 4
4 3

Sample Output 2

-1

There is no induced subgraph of G that satisfies the condition.

Sample Input 3

6 9
1 2
2 3
3 4
4 5
5 6
5 1
5 2
6 1
6 2

Sample Output 3

4
2
3
4
5

Solution in C++14 (GCC 5.4.1) (judge verdict: Wrong Answer)

#include <bits/stdc++.h>
using namespace std;

using ull = unsigned long long;
using ll = long long;
#define repi(n) for (int i = 0; i < (n); i++)
#define repj(n) for (int j = 0; j < (n); j++)
#define repk(n) for (int k = 0; k < (n); k++)
#define repl(n) for (int l = 0; l < (n); l++)
#define rep(i, n) for (int i = 0; (i) < (n); i++)
#define repr(i, a, b) for (auto i = (a); i < (b); i++)
#define repv(itr) for (auto&& v : (itr))
#define updatemax(t, v) (t = max((t), (v)))
#define updatemin(t, v) (t = min((t), (v)))
const int dx[] = {-1, 0, 0, 1, -1, -1, 1, 1};
const int dy[] = {0, -1, 1, 0, -1, 1, -1, 1};
template <typename T>
T minptr(T begin, T end) {
  T re = begin;
  for (T i = begin + 1; i != end; i++) {
    if (*i < *re) re = i;
  }
  return re;
}
template <typename T>
T maxptr(T begin, T end) {
  T re = begin;
  for (T i = begin + 1; i != end; i++) {
    if (*i > *re) re = i;
  }
  return re;
}
int __vmax(int x) {
  return INT_MAX;
}
double __vmax(double x) {
  return 1e+300;
}
ll __vmax(ll x) {
  return LLONG_MAX;
}
int __vmin(int x) {
  return INT_MIN;
}
double __vmin(double x) {
  return -1e+300;
}
ll __vmin(ll x) {
  return LLONG_MIN;
}
template <typename T>
T gcd(T a, T b) {
  return b == 0 ? a : b == 1 ? 1 : gcd(b, a % b);
}
template <typename T>
T ib_binary_search(T begin, T end, function<bool(T)> f) {
  if (!f(end)) return end;
  while (abs(end - begin) > 1) {
    T m = (begin + end) / 2;
    if (f(m)) {
      end = m;
    } else {
      begin = m;
    }
  }
  return end;
}
ll modpow(ll a, ll b, ll m) {
  ll re = 1, k = 1;
  while (k <= b) {
    if (b & k) {
      re *= a;
      re %= m;
    }
    k = k << 1;
    a *= a;
    a %= m;
  }
  return re;
}
ll modinv(ll a, ll m) {
  ll b = m, u = 1, v = 0;
  while (b) {
    ll t = a / b;
    a -= t * b;
    swap(a, b);
    u -= t * v;
    swap(u, v);
  }
  u %= m;
  if (u < 0) u += m;
  return u;
}
ll modbinomial(ll n, ll k, ll m) {
  k = min(k, n - k);
  if (k < 0) return 0;
  ll re = 1;
  for (ll i = 0; i < k; i++) {
    re *= n - i;
    re %= m;
    re *= modinv(i + 1, m);
    re %= m;
  }
  return re;
}
template <typename T>
vector<T> lis(T begin, T end, bool allowequal = false, bool lds = false) {
  using V = typename iterator_traits<T>::value_type;
  int n = end - begin;
  vector<V> a(n, lds ? __vmin(*begin) : __vmax(*begin));
  vector<int> id(n);
  if (lds && allowequal) {
    for (int i = 0; i < n; i++) {
      id[i] = n - 1 -
              (lower_bound(a.rbegin(), a.rend(), begin[i]) - 1 - a.rbegin());
      a[id[i]] = begin[i];
    }
  } else if (lds) {
    for (int i = 0; i < n; i++) {
      id[i] = n - 1 -
              (upper_bound(a.rbegin(), a.rend(), begin[i]) - 1 - a.rbegin());
      a[id[i]] = begin[i];
    }
  } else if (allowequal) {
    for (int i = 0; i < n; i++) {
      id[i] = upper_bound(a.begin(), a.end(), begin[i]) - a.begin();
      a[id[i]] = begin[i];
    }
  } else {
    for (int i = 0; i < n; i++) {
      id[i] = lower_bound(a.begin(), a.end(), begin[i]) - a.begin();
      a[id[i]] = begin[i];
    }
  }
  int m = *maxptr(id.begin(), id.end());
  vector<T> re(m + 1);
  for (int i = n - 1; i >= 0; i--) {
    if (id[i] == m) re[m--] = begin + i;
  }
  return re;
}
template <typename T>
class segtree {
 private:
  int n;
  function<T(T, T)> f;
  T e;
  vector<T> data;
  void _updateP(int i) {
    data[i] = f(data[i * 2 + 1], data[i * 2 + 2]);
    if (i) _updateP((i - 1) / 2);
  }
  T _calc(int begin, int end, int node, int nodeBegin, int nodeEnd) {
    if (end <= nodeBegin || nodeEnd <= begin) {
      return e;
    } else if (begin <= nodeBegin && nodeEnd <= end) {
      return data[node];
    } else {
      int m = (nodeBegin + nodeEnd) / 2;
      T left = _calc(begin, end, node * 2 + 1, nodeBegin, m);
      T right = _calc(begin, end, node * 2 + 2, m, nodeEnd);
      return f(left, right);
    }
  }

 public:
  segtree(int n_, function<T(T, T)> f_, T e_, T fill) {
    n = pow(2, ceil(log2(n_)));
    f = f_;
    e = e_;
    data.resize(n * 2 - 1);
    for (int i = 0; i < n * 2 - 1; i++) data[i] = fill;
  }
  segtree(int n_, function<T(T, T)> f_, T e_) : segtree(n_, f_, e_, e_) {}
  T value(int i) { return data[n - 1 + i]; }
  void update(int i, T value) {
    data[n - 1 + i] = value;
    if (n) _updateP((n - 2 + i) / 2);
  }
  T calc(int begin, int end) { return _calc(begin, end, 0, 0, n); }
  static T max(T a, T b) { return std::max(a, b); }
  static T min(T a, T b) { return std::min(a, b); }
  static T sum(T a, T b) { return a + b; }
};

vector<int> g[1000];
int nexts[1000];
int dfs(int p) {
  if (nexts[p] < -1) return -1;
  if (nexts[p] >= 0) return p;
  repv(g[p]) {
    nexts[p] = v;
    int re = dfs(v);
    if (re >= 0) return re;
  }
  nexts[p] = -2;
  return -1;
}
int main() {
  int n, m;
  cin >> n >> m;
  repi(m) {
    int a, b;
    cin >> a >> b;
    a--;
    b--;
    g[a].push_back(b);
  }
  repi(n) nexts[i] = -1;
  while (true) {
    int p = -1;
    repi(n) if (nexts[i] == -1) {
      p = i;
      break;
    }
    if (p == -1) {
      cout << -1 << endl;
      break;
    }
    int re = dfs(p);
    if (re != -1) {
      vector<int> loop;
      int current = re;
      while (true) {
        loop.push_back(current);
        current = nexts[current];
        if (current == re) break;
      }
      cout << loop.size() << endl;
      repv(loop) cout << v + 1 << endl;
      break;
    }
  }
}