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 Rust (1.15.1) (judge verdict: Accepted)

fn read_ints() -> Vec<i32> {
    let mut s = String::new();
    std::io::stdin().read_line(&mut s).unwrap();
    let s = s.trim_right().to_owned();
    let ws = s.split_whitespace();
    let mut ints = Vec::new();
    for num_s in ws {
        ints.push(num_s.parse().unwrap());
    }
    ints
}

use std::collections::HashMap;
use std::collections::HashSet;
use std::hash::Hash;
use std::iter::FromIterator;

pub struct DirectedGraph<T> {
    nodes: HashSet<T>,
    edges: HashSet<(T, T)>,
    nexts: Option<HashMap<T, HashSet<T>>>,
}

impl<T: Clone + Copy + Eq + Hash + std::fmt::Debug> DirectedGraph<T> {
    pub fn new() -> Self {
        DirectedGraph {
            nodes: HashSet::new(),
            edges: HashSet::new(),
            nexts: None,
        }
    }

    pub fn get_nodes_num(&self) -> usize {
        self.nodes.len()
    }

    pub fn get_edges_num(&self) -> usize {
        self.edges.len()
    }

    pub fn get_edges(&self) -> HashSet<(T, T)> {
        self.edges.clone()
    }

    pub fn set_node(&mut self, node: T) {
        self.nodes.insert(node);
    }

    pub fn set_edge(&mut self, edge: (T, T)) {
        self.edges.insert(edge);
    }

    pub fn calc_nexts(&mut self) {
        let mut nexts = HashMap::new();
        for &node in self.nodes.iter() {
            nexts.insert(node, HashSet::new());
        }
        for &edge in self.edges.iter() {
            nexts.get_mut(&edge.0).unwrap().insert(edge.1);
        }
        self.nexts = Some(nexts);
    }

    pub fn search_example_of_circuit(
        &self,
        current_path: &mut Vec<T>,
        current_nodes: &mut HashSet<T>,
    ) -> Option<Vec<T>> {
        let current_node = current_path[current_path.len() - 1];
        for &next_node in self
            .nexts
            .as_ref()
            .unwrap()
            .get(&current_node)
            .unwrap()
            .iter()
        {
            if next_node == current_path[0] {
                return Some(current_path.clone());
            }
            if !current_nodes.contains(&next_node) {
                current_path.push(next_node);
                current_nodes.insert(next_node);

                if let Some(path) = self.search_example_of_circuit(current_path, current_nodes) {
                    return Some(path);
                }
                current_path.pop();
                current_nodes.remove(&next_node);
            }
        }
        None
    }

    pub fn get_example_of_circuit(&self, start_node: T) -> Option<Vec<T>> {
        let mut current_path = Vec::new();
        let mut current_nodes = HashSet::new();
        current_path.push(start_node);
        current_nodes.insert(start_node);
        self.search_example_of_circuit(&mut current_path, &mut current_nodes)
    }

    pub fn get_example_of_circuit_with_any_start(&self) -> Option<Vec<T>> {
        for &node in self.nodes.iter() {
            if let Some(path) = self.get_example_of_circuit(node) {
                return Some(path);
            }
        }
        None
    }

    pub fn get_induced_subgraph(&self, nodes: HashSet<T>) -> Self {
        let new_nodes: HashSet<T> = HashSet::from_iter(self.nodes.intersection(&nodes).cloned());
        let mut new_edges: HashSet<(T, T)> = HashSet::new();
        for &edge in self.edges.iter() {
            if new_nodes.contains(&edge.0) && new_nodes.contains(&edge.1) {
                new_edges.insert(edge);
            }
        }
        DirectedGraph {
            nodes: new_nodes,
            edges: new_edges,
            nexts: None,
        }
    }
}

fn get_example_of_unused_edge(
    graph: &DirectedGraph<usize>,
    circuit: &Vec<usize>,
) -> (usize, usize) {
    let mut used_edges = HashSet::new();
    for i in 0..circuit.len() {
        used_edges.insert((circuit[i % circuit.len()], circuit[(i + 1) % circuit.len()]));
    }
    let total_edges = graph.get_edges();
    let mut unused_edges = total_edges.difference(&used_edges);
    *unused_edges.next().unwrap()
}

fn main() {
    let ints = read_ints();
    let (n, m) = (ints[0] as usize, ints[1] as usize);

    let mut graph = DirectedGraph::new();

    for i in 0..n {
        graph.set_node(i + 1);
    }

    for i in 0..m {
        let e = read_ints();
        graph.set_edge((e[0] as usize, e[1] as usize));
    }

    graph.calc_nexts();
    let mut circuit = graph.get_example_of_circuit_with_any_start();
    if circuit.is_none() {
        println!("-1");
        return;
    }
    let mut circuit = circuit.unwrap();
    let mut subgraph = graph.get_induced_subgraph(HashSet::from_iter(circuit.iter().cloned()));
    subgraph.calc_nexts();

    while subgraph.get_nodes_num() != subgraph.get_edges_num() {
        let unused_edge = get_example_of_unused_edge(&subgraph, &circuit);

        let mut current_search_path = Vec::new();
        current_search_path.push(unused_edge.0);
        current_search_path.push(unused_edge.1);
        let mut current_search_nodes = HashSet::from_iter(current_search_path.iter().cloned());
        circuit = subgraph
            .search_example_of_circuit(&mut current_search_path, &mut current_search_nodes)
            .unwrap();
        subgraph = subgraph.get_induced_subgraph(HashSet::from_iter(circuit.iter().cloned()));
        subgraph.calc_nexts();
    }

    println!("{}", circuit.len());
    for n in circuit.iter() {
        println!("{}", n);
    }
}