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);
    }
}


Measured memory_bytes: 6524