#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<queue>
#include<cmath>
#include<cstdio>
#include<tuple>
#include<bitset>

using namespace std;
#define int long long
#define rep(i,n) for(int i=0;i<n;++i)
#define rep1(i,n) for(int i=1;i<=n;++i)
#define ALL(x) x.begin(),x.end()
#define ll long long
typedef pair<int,int> P;
const int inf=1000000007;
const int MOD=1000000007;
class Edge{
public:
//int s;
int t;
long long len;
};
class Node{
    public:
    int num;//node番号
    long long dist;//startからの距離
    vector<Edge> edge;//自分から生えている辺
    vector<Node*> par;
    bool comp;//dijkstra中で到達しているかどうか
    void in_edge(int in_t,int in_len){
        Edge in;in.t=in_t;in.len=in_len;
        edge.push_back(in);
    }  
};
bool operator >(const Node& a,const Node &r){
        return a.dist > r.dist;
    }
void dijkstra(vector<Node> &node,int s,int n){
    //n個のノードでできたグラフのsからtまでの最短距離を計算する
    //この時各要素のdistの値はsからの最短距離となる
    for(int i=1;i<=n;i++){
        //初期化
        node[i].dist=inf;
        node[i].num=i;
        node[i].comp=true;
        node[i].par.resize(0);
    }
    node[s].dist=0;
    priority_queue<Node,vector<Node>,greater<Node>> que;
    que.push(node[s]);
    while(!que.empty()){
        Node buf;
        buf=que.top();//
        que.pop();
        int k=buf.num;
        if(node[k].comp){
            node[k].comp=false;
            int edge_num=buf.edge.size();
            for(int i=0;i<edge_num;i++){
                int buf_t=node[k].edge[i].t;
                int buf_len=node[k].edge[i].len;
                node[buf_t].par.push_back(&node[k]);
                if(node[buf_t].dist>node[k].dist+buf_len){
                node[buf_t].dist=node[k].dist+buf_len;
                que.push(node[buf_t]);
                }
            }
        }
    }
}
bool solve(vector<Node> const& node,P input,int n){
  int a=input.first;int b=input.second;
  bool flag=true;
  vector<int> res;
  res.push_back(a);
  queue<Node> que;
  que.push(node[a]);
  while(!que.empty()){
    Node buf=que.front();que.pop();
    int num=buf.par.size();
    rep(i,num){
      if(buf.par[i]->dist==buf.dist-1){
        res.push_back(buf.par[i]->num);
        que.push(*buf.par[i]);
      }
    }
  }
  sort(res.begin(),res.end());
  que.push(node[a]);
  while(!que.empty()){
    Node buf=que.front();que.pop();
    int num=buf.par.size();
    int cur=0;
    rep(i,num){
      if(!binary_search(ALL(res),buf.par[i]->num))continue;
      cur++;
      if(buf.par[i]->dist==buf.dist-1){
        //res.push_back(buf.par[i]->num);
        que.push(*buf.par[i]);
      }
    }
    if(cur>1){
      flag=false;
      break;
    }
  }
  if(!flag){
    return false;
  }
  int num=res.size();
  cout<<num<<"\n";
  rep(i,num){
    cout<<res[i]<<"\n";
  }
  return flag;
}
signed main(){
  int n,m;cin>>n>>m;
  vector<Node> node(n+1);
  vector<P> input(m);
  rep(i,m){
    int a,b;cin>>a>>b;
    node[a].in_edge(b,1);
    input[i].first=a;input[i].second=b;
  }
  bool flag=true;
  rep(i,m){
    dijkstra(node,input[i].second,n);
    if(node[input[i].first].dist==inf){
      continue;
    }
    else{
      if(solve(node,input[i],n)){
        flag=false;
        break;
      }
      
    }
  }
  if(flag){
    cout<<-1<<endl;
  }
  return 0;
}


Measured memory_bytes: 512