Problem:
Score: 400 points

Problem Statement

There is a cave.

The cave has N rooms and M passages. The rooms are numbered 1 to N, and the passages are numbered 1 to M. Passage i connects Room A_i and Room B_i bidirectionally. One can travel between any two rooms by traversing passages. Room 1 is a special room with an entrance from the outside.

It is dark in the cave, so we have decided to place a signpost in each room except Room 1. The signpost in each room will point to one of the rooms directly connected to that room with a passage.

Since it is dangerous in the cave, our objective is to satisfy the condition below for each room except Room 1.

If you start in that room and repeatedly move to the room indicated by the signpost in the room you are in, you will reach Room 1 after traversing the minimum number of passages possible.

Determine whether there is a way to place signposts satisfying our objective, and print one such way if it exists.

Constraints

All values in input are integers.

2 \leq N \leq 10^5

1 \leq M \leq 2 \times 10^5

1 \leq A_i, B_i \leq N\ (1 \leq i \leq M)

A_i \neq B_i\ (1 \leq i \leq M)

One can travel between any two rooms by traversing passages.

Input

Input is given from Standard Input in the following format:

N M
A_1 B_1
:
A_M B_M

Output

If there is no way to place signposts satisfying the objective, print No.

Otherwise, print N lines. The first line should contain Yes, and the i-th line (2 \leq i \leq N) should contain the integer representing the room indicated by the signpost in Room i.

Sample Input 1

4 4
1 2
2 3
3 4
4 2

Sample Output 1

Yes
1
2
2

If we place the signposts as described in the sample output, the following happens:

Starting in Room 2, you will reach Room 1 after traversing one passage: (2) \to 1. This is the minimum number of passages possible.

Starting in Room 3, you will reach Room 1 after traversing two passages: (3) \to 2 \to 1. This is the minimum number of passages possible.

Starting in Room 4, you will reach Room 1 after traversing two passages: (4) \to 2 \to 1. This is the minimum number of passages possible.

Thus, the objective is satisfied.

Sample Input 2

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

Sample Output 2

Yes
6
5
5
1
1

If there are multiple solutions, any of them will be accepted.

Solution in Java (OpenJDK 11.0.6) (judge verdict: Runtime Error)

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;


class Main {

    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        int n = sc.nextInt();
        int m = sc.nextInt();
        Main g = new Main(false, true, n);
        for(int i = 1; i <= n; i++){
            g.addVertex(i);
        }
        for (int i = 0; i < m; i++ ){
            int a = sc.nextInt();
            int b = sc.nextInt();
            g.addEdge(a-1, b-1, 1);
        }
        System.out.println("Yes");
        g.Dijkstra(0);

    }
    public static final boolean UNDIRECTED_GRAPH = false;//无向图标志
    public static final boolean DIRECTED_GRAPH = true;//有向图标志

    public static final boolean ADJACENCY_MATRIX = true;//邻接矩阵实现
    public static final boolean ADJACENCY_LIST = false;//邻接表实现

    public static final int MAX_VALUE = Integer.MAX_VALUE;
    private boolean graphType;
    private boolean method;
    private int vertexSize;
    private int matrixMaxVertex;

    //存储所有顶点信息的一维数组
    private Object[] vertexesArray;
    //存储图中顶点之间关联关系的二维数组,及边的关系
    private int[][] edgesMatrix;

    // 记录第i个节点是否被访问过
    private boolean[] visited;

    /**
     * @param graphType 图的类型：有向图/无向图
     * @param method    图的实现方式：邻接矩阵/邻接表
     */
    public Main(boolean graphType, boolean method, int size) {
        this.graphType = graphType;
        this.method = method;
        this.vertexSize = 0;
        this.matrixMaxVertex = size;

        if (this.method) {
            visited = new boolean[matrixMaxVertex];
            vertexesArray = new Object[matrixMaxVertex];
            edgesMatrix = new int[matrixMaxVertex][matrixMaxVertex];

            //对数组进行初始化，顶点间没有边关联的值为Integer类型的最大值
            for (int row = 0; row < edgesMatrix.length; row++) {
                for (int column = 0; column < edgesMatrix.length; column++) {
                    edgesMatrix[row][column] = MAX_VALUE;
                }
            }

        }
    }

    /********************最短路径****************************/
    //计算一个顶点到其它一个顶点的最短距离
    public void Dijkstra(Object obj) throws Exception {
        Dijkstra(getVertexIndex(obj));
    }
    public void Dijkstra(int v0) {
        int[] dist = new int[matrixMaxVertex];
        int[] prev = new int[matrixMaxVertex];

        //初始化visited、dist和path
        for (int i = 0; i < vertexSize; i++) {
            //一开始假定取直达路径最短
            dist[i] = edgesMatrix[v0][i];
            visited[i] = false;

            //直达情况下的最后经由点就是出发点
            if (i != v0 && dist[i] < MAX_VALUE)
                prev[i] = v0;
            else
                prev[i] = -1; //无直达路径
        }

        //初始时源点v0∈visited集，表示v0 到v0的最短路径已经找到
        visited[v0] = true;

        // 下来假设经由一个点中转到达其余各点,会近些,验证之
        // 再假设经由两个点中转,会更近些,验证之,.....
        // 直到穷举完所有可能的中转点
        int minDist;
        int v = 0;
        for (int i = 1; i < vertexSize; i++) {
            //挑一个距离最近经由点,下标装入 v
            minDist = MAX_VALUE;

            for (int j = 0; j < vertexSize; j++) {
                if ((!visited[j]) && dist[j] < minDist) {
                    v = j;                             // 经由顶点j中转则距离更短
                    minDist = dist[j];
                }
            }
            visited[v] = true;

            /*顶点v并入S，由v0到达v顶点的最短路径为min.
              假定由v0到v，再由v直达其余各点，更新当前最后一个经由点及距离*/
            for (int j = 0; j < vertexSize; j++) {
                if ((!visited[j]) && edgesMatrix[v][j] < MAX_VALUE) {

                    if (minDist + edgesMatrix[v][j] <= dist[j]) {
                        //如果多经由一个v点到达j点的 最短路径反而要短,就更新
                        dist[j] = minDist + edgesMatrix[v][j];

                        prev[j] = v;                    //经由点的序号
                    }

                }
            }

        }

        for (int i = 1; i < matrixMaxVertex; i++) {
            System.out.println(dist[i]);
        }
    }

    //获取顶点值在数组里对应的索引
    private int getVertexIndex(Object obj) throws Exception {
        int index = -1;
        for (int i = 0; i < vertexSize; i++) {
            if (vertexesArray[i].equals(obj)) {
                index = i;
                break;
            }
        }
        if (index == -1) {
            throw new Exception("没有这个值！");
        }

        return index;
    }

    /**
     * 单源最短路径算法，用于计算一个节点到其他!!所有节点!!的最短路径
     */
    public void Dijkstra2(int v0) {
        // LinkedList实现了Queue接口 FIFO
        Queue<Integer> queue = new LinkedList<Integer>();
        for (int i = 0; i < vertexSize; i++) {
            visited[i] = false;
        }

        //这个循环是为了确保每个顶点都被遍历到
        for (int i = 0; i < vertexSize; i++) {
            if (!visited[i]) {
                queue.add(i);
                visited[i] = true;

                while (!queue.isEmpty()) {
                    int row = queue.remove();
                    System.out.print(vertexesArray[row] + "-->");

                    for (int k = getMin(row); k >= 0; k = getMin(row)) {
                        if (!visited[k]) {
                            queue.add(k);
                            visited[k] = true;
                        }
                    }

                }
            }
        }
    }

    private int getMin( int row) {
        int minDist = MAX_VALUE;
        int index = 0;
        for (int j = 0; j < vertexSize; j++) {
            if ((!visited[j]) && edgesMatrix[row][j] < minDist) {
                minDist = edgesMatrix[row][j];
                index = j;
            }
        }
        if (index == 0) {
            return -1;
        }
        return index;
    }

    public boolean addVertex(Object val) {
        assert (val != null);
        vertexesArray[vertexSize] = val;
        vertexSize++;
        return true;
    }

    public boolean addEdge(int vnum1, int vnum2, int weight) {
        assert (vnum1 >= 0 && vnum2 >= 0 && vnum1 != vnum2 && weight >= 0);

        //有向图
        if (graphType) {
            edgesMatrix[vnum1][vnum2] = weight;

        } else {
            edgesMatrix[vnum1][vnum2] = weight;
            edgesMatrix[vnum2][vnum1] = weight;
        }

        return true;
    }

}