use std::fmt::Debug;
use std::str::FromStr;

#[allow(dead_code)]
#[allow(deprecated)]
fn read_line_from_stdin() -> String {
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).unwrap();
    buffer.trim_right().to_owned()
}

#[allow(dead_code)]
#[allow(deprecated)]
fn parse_line_to_single<T>() -> T
where
    T: FromStr,
    T::Err: Debug,
{
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).unwrap();
    T::from_str(buffer.trim_right()).unwrap()
}

#[allow(dead_code)]
#[allow(deprecated)]
fn parse_line_to_multiple<T>() -> Vec<T>
where
    T: FromStr,
    T::Err: Debug,
{
    let mut buffer = String::new();
    std::io::stdin().read_line(&mut buffer).unwrap();
    buffer
        .trim_right()
        .split_whitespace()
        .flat_map(|s| T::from_str(s))
        .collect()
}

#[allow(unused_macros)]
macro_rules! parse_line {
    [$( $x:tt : $t:ty ),+] => {
        //declare variables
        $( let $x: $t; )+
        {
            use std::str::FromStr;
            // read
            let mut buf = String::new();
            std::io::stdin().read_line(&mut buf).unwrap();
            #[allow(deprecated)]
            let mut splits = buf.trim_right().split_whitespace();
            // assign each variable
            $(
                $x = splits.next().and_then(|s| <$t>::from_str(s).ok()).unwrap();
            )+
            // all strs should be used for assignment
            assert!(splits.next().is_none());
        }
    };
}

use std::collections::HashMap;

fn main() {
    parse_line![room_count: usize, aisle_count: usize];

    let connections = {
        let mut temp = HashMap::with_capacity(room_count);

        for i in 1..room_count + 1 {
            temp.insert(i, vec![]);
        }

        for _ in 0..aisle_count {
            parse_line![room_label1: usize, room_label2: usize];

            temp.get_mut(&room_label1).unwrap().push(room_label2);
            temp.get_mut(&room_label2).unwrap().push(room_label1);
        }

        temp
    };

    let depths = scan_all_node_minimum_depth(1, &connections);

    let mut guides = HashMap::with_capacity(room_count);

    search(1, 0, &connections, &depths, &mut guides);

    let mut buffer = String::with_capacity(1000000);
    for i in 2..room_count + 1 {
        if let Some(guide) = guides.get(&i) {
            buffer.push_str(&format!("{}\n", guide.to));
        } else {
            println!("No",);
            return;
        }
    }
    println!("Yes");
    println!("{}", buffer);
}

#[derive(Debug, Clone, Copy, PartialEq, Eq)]
struct Guide {
    from: usize,
    to: usize,
    cost: i32,
}

fn scan_all_node_minimum_depth<N: Copy + Eq + std::hash::Hash>(
    root_node: N,
    connections: &HashMap<N, Vec<N>>,
) -> HashMap<N, usize> {
    let mut depths = HashMap::new();
    let mut current_depth = 0;

    depths.insert(root_node, current_depth);

    let mut scan_target_nodes = match connections.get(&root_node) {
        Some(connected_nodes) => connected_nodes.to_vec(),
        None => return HashMap::new(),
    };

    while !scan_target_nodes.is_empty() {
        current_depth += 1;

        let mut next_targets = vec![];

        for target in scan_target_nodes.into_iter() {
            if depths.get(&target).is_some() {
                continue;
            }
            depths.insert(target, current_depth);

            if let Some(connected_to_target) = connections.get(&target) {
                for &next_target in connected_to_target.into_iter() {
                    next_targets.push(next_target);
                }
            }
        }

        scan_target_nodes = next_targets;
    }

    depths
}

fn search(
    current_room: usize,
    current_cost: i32,
    connections: &HashMap<usize, Vec<usize>>,
    node_depths: &HashMap<usize, usize>,
    current_guides: &mut HashMap<usize, Guide>,
) {
    let connected_rooms = &connections[&current_room];

    for &connected_room in connected_rooms.iter() {
        if node_depths[&current_room] + 1 != node_depths[&connected_room] {
            continue;
        }
        match current_guides.get_mut(&connected_room) {
            Some(Guide { from, to, cost }) => {
                if *cost > current_cost {
                    *from = connected_room;
                    *to = current_room;
                    *cost = current_cost;
                } else {
                    continue;
                }
            }
            None => {
                let guide = Guide {
                    from: connected_room,
                    to: current_room,
                    cost: current_cost,
                };
                current_guides.insert(connected_room, guide);
            }
        }

        // next connection
        search(
            connected_room,
            current_cost + 1,
            connections,
            node_depths,
            current_guides,
        );
    }
}


Measured memory_bytes: 31924