Problem: Petr is a detective in Braginsk. Somebody stole a huge amount of money from a bank and Petr is to catch him. Somebody told Petr that some luxurious car moves along the roads without stopping.

Petr knows that it is the robbers who drive the car. The roads in Braginsk are one-directional and each of them connects two intersections. Petr wants to select one intersection such that if the robbers continue to drive the roads indefinitely, they will sooner or later come to that intersection. The initial position of the robbers is unknown. Find such an intersection that fits the requirements.

Input

The first line of the input contains two integers n and m (2 ≤ n ≤ 10^5, 2 ≤ m ≤ 5 ⋅ 10^5) — the number of intersections and the number of directed roads in Braginsk, respectively.

Each of the next m lines contains two integers u_i and v_i (1 ≤ u_i, v_i ≤ n, u_i ≠ v_i) — the start and finish of the i-th directed road. It is guaranteed that the robbers can move along the roads indefinitely.

Output

Print a single integer k — the intersection Petr needs to choose. If there are multiple answers, print any. If there are no such intersections, print -1.

Examples

Input

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


Output

3

Input

3 3
1 2
2 3
3 1


Output

1

Note

In the first example the robbers can move, for example, along the following routes: (1-2-3-1), (3-4-5-3), (1-2-3-4-5-3-1). We can show that if Petr chooses the 3-rd intersection, he will eventually meet the robbers independently of their route.

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 7;
const int DEBUG = 0;
int n, m;
int dfn[N], low[N], tag, in_stk[N], father[N];
vector<int> comp, stk;
int deep[N];
bool exist[N], visit[N];
void nie() {
  puts("-1");
  exit(0);
}
void fail() {
  puts("-1\n\n");
  exit(0);
}
struct Edge {
  int y, next;
} edges[N * 2];
int l = 1, idx[N];
void build(int x, int y) {
  edges[++l].next = idx[x];
  edges[l].y = y;
  idx[x] = l;
}
void tarjan(int u) {
  dfn[u] = low[u] = ++tag;
  stk.push_back(u);
  in_stk[u] = true;
  for (int p(idx[u]); p; p = edges[p].next) {
    int v(edges[p].y);
    if (!dfn[v]) {
      tarjan(v);
      low[u] = min(low[u], low[v]);
    } else if (in_stk[v]) {
      low[u] = min(low[u], low[v]);
    }
  }
  if (low[u] == dfn[u]) {
    if (stk.back() == u) {
      stk.pop_back();
      in_stk[u] = false;
      return;
    }
    if (comp.size()) fail();
    int t;
    do {
      t = stk.back();
      comp.push_back(t);
      in_stk[t] = false;
      stk.pop_back();
    } while (t != u);
    reverse(comp.begin(), comp.end());
  }
}
int lp[N], rp[N];
int cover[N], sum[N], high, lower, upper, up_num, go_up[N], go_down[N];
vector<pair<int, int> > down;
void check_deep_min(int &a, int b) {
  if (a == -1 || (b != -1 && deep[a] > deep[b])) {
    a = b;
  }
}
void check_deep_max(int &a, int b) {
  if (a == -1 || (b != -1 && deep[a] < deep[b])) {
    a = b;
  }
}
void dfs(int u) {
  lp[u] = tag++;
  in_stk[u] = true;
  visit[u] = true;
  go_up[u] = -1;
  for (int p(idx[u]); p; p = edges[p].next) {
    int v(edges[p].y);
    if (!exist[v]) continue;
    if (visit[v]) {
      if (in_stk[v]) {
        cover[u]++;
        cover[father[v]]--;
        check_deep_min(high, v);
        check_deep_min(go_up[u], v);
        up_num++;
        if (DEBUG) {
          cout << "up " << u << " ^ " << v << endl;
        }
      } else {
        if (lp[u] <= lp[v] && rp[v] <= tag) {
          down.push_back({u, v});
        } else {
          check_deep_min(go_up[u], go_up[v]);
        }
      }
    } else {
      father[v] = u;
      deep[v] = deep[u] + 1;
      if (DEBUG) {
        cout << "tree " << u << " -> " << v << endl;
      }
      dfs(v);
      check_deep_min(go_up[u], go_up[v]);
    }
  }
  rp[u] = tag;
  in_stk[u] = false;
}
bool is_anc(int u, int v) { return lp[u] <= lp[v] && lp[v] < rp[u]; }
bool in_tree(int u) { return is_anc(upper, u) && is_anc(u, lower); }
bool under_tree(int u) { return is_anc(lower, u) && u != lower; }
void fuck_in_tree(int u) {
  go_down[u] = -1;
  visit[u] = true;
  in_stk[u] = true;
  for (int p(idx[u]); p; p = edges[p].next) {
    int v(edges[p].y);
    if (!exist[v]) continue;
    if (visit[v]) {
      if (!in_stk[v] && !is_anc(u, v)) {
        check_deep_max(go_down[u], go_down[v]);
      }
    } else {
      fuck_in_tree(v);
      check_deep_max(go_down[u], go_down[v]);
    }
  }
  if (in_tree(u)) go_down[u] = u;
  in_stk[u] = false;
}
void fuck_under_tree(int u) {
  go_down[u] = -1;
  visit[u] = true;
  in_stk[u] = true;
  for (int p(idx[u]); p; p = edges[p].next) {
    int v(edges[p].y);
    if (!exist[v]) continue;
    if (visit[v]) {
      if (in_stk[v])
        check_deep_min(go_down[u], v);
      else
        check_deep_min(go_down[u], go_down[v]);
    } else {
      fuck_under_tree(v);
      check_deep_min(go_down[u], go_down[v]);
    }
  }
  if (in_tree(u)) go_down[u] = -1;
  in_stk[u] = false;
}
int collect(int u) {
  visit[u] = true;
  sum[u] = cover[u];
  for (int p(idx[u]); p; p = edges[p].next) {
    int v(edges[p].y);
    if (exist[v] && !visit[v]) {
      sum[u] += collect(v);
    }
  }
  return sum[u];
}
int nextInt() {
  int res(0);
  char c(getchar());
  while (c < '0') c = getchar();
  while (c >= '0') {
    res = res * 10 + (c - '0');
    c = getchar();
  }
  return res;
}
int main() {
  n = nextInt();
  m = nextInt();
  for (int i = 0; i < m; i++) {
    int u = nextInt(), v = nextInt();
    build(u, v);
  }
  tag = 0;
  for (int i = 1; i <= n; i++) {
    if (!dfn[i]) tarjan(i);
  }
  if (comp.size() == 0) nie();
  for (auto v : comp) {
    exist[v] = true, visit[v] = false, in_stk[v] = false;
    cover[v] = sum[v] = 0;
  }
  tag = 0;
  high = lower = upper = -1;
  up_num = 0;
  dfs(comp[0]);
  for (auto v : comp) visit[v] = false;
  collect(comp[0]);
  for (auto v : comp)
    if (sum[v] == up_num) {
      check_deep_min(upper, v);
      check_deep_max(lower, v);
    }
  if (upper == -1) fail();
  if (DEBUG) {
    cout << "lower = " << lower << endl;
    cout << "upper = " << upper << endl;
    cout << "high = " << high << endl;
  }
  for (auto v : comp) cover[v] = sum[v] = 0;
  for (auto d : down) {
    int u = d.first, v = d.second;
    if (DEBUG) {
      cout << "down = " << u << " " << v << endl;
    }
    assert(u != v);
    if (go_up[v] != -1 && deep[go_up[v]] <= deep[u]) {
      cover[father[v]]++;
      cover[u]--;
    }
  }
  for (auto v : comp) visit[v] = false;
  fuck_in_tree(comp[0]);
  {
    int u = lower;
    while (true) {
      for (int p(idx[u]); p; p = edges[p].next) {
        int v(edges[p].y);
        if (is_anc(v, u)) continue;
        if (exist[v] && go_down[v] != -1 && go_down[v] != u &&
            deep[go_down[v]] > deep[u]) {
          cover[father[go_down[v]]]++;
          cover[u]--;
        }
      }
      if (u == high) break;
      u = father[u];
    }
  }
  for (auto v : comp) visit[v] = false;
  fuck_under_tree(comp[0]);
  {
    int u = lower;
    while (true) {
      for (int p(idx[u]); p; p = edges[p].next) {
        int v(edges[p].y);
        if (is_anc(v, u)) continue;
        if (exist[v] && go_down[v] != -1 && deep[go_down[v]] <= deep[u]) {
          cover[lower]++;
          cover[u]--;
        }
      }
      if (u == comp[0]) break;
      u = father[u];
    }
  }
  for (auto v : comp) visit[v] = false;
  collect(comp[0]);
  vector<int> ans;
  for (int i = 1; i <= n; i++) {
    if (in_tree(i) && sum[i] == 0) {
      ans.push_back(i);
    }
  }
  if (ans.size() == 0) fail();
  printf("%d\n", (int)ans[0]);
  return 0;
}