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 C# (.NET Core 3.1.201) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Threading;

namespace AtCoder
{
    class Program
    {
        static void Main(string[] args)
        {
            input_iter = LazyLoadAllLines();
            //------------------------------------------------//
            //var n = Read<long>();
            //var s = Read();
            //var als = Read<long>(n);
            //var sls = Read(n);
            //List<List<long>> abls = new List<List<long>>();
            //List<long> cls = new List<long>();
            /*List<long> edgeNum = Enumerable.Repeat(0L, (int)n).ToList();
            for (int i = 0; i < n - 1; ++i)
            {
                abls.Add(Read<long>(2));
                abls[i].Add(i);
                abls[i].Add(-1);
                --abls[i][0];
                --abls[i][1];
                //cls.Add(Read<long>());
                ++edgeNum[(int)abls[i][0]];
                ++edgeNum[(int)abls[i][1]];
            }*/

            //als.Sort((l, r) => (r - l));
            //sls.Sort(StringComparer.OrdinalIgnoreCase);

            // ***********************
            // ***** int -> long *****
            // ***********************
            // よくわからなかったら簡単な数学的変形をしてみる
            // DP?Graph?
            // 単調数列(上界有)を全探索 -> ボールと仕切り、仕切りの左右のボールの数 (N^M -> N+M C N)

            var n = Read<long>();
            var m = Read<long>();
            var abls = Read<long, long>(m);

            var edges = abls.Select(val => new Edge((int)val.Item1 - 1, (int)val.Item2 - 1, 1.0))
                .Concat(abls.Select(val => new Edge((int)val.Item2 - 1, (int)val.Item1 - 1, 1.0)));

            Graph graph = new Graph(n, edges);

            Dijkstra dijkstra = new Dijkstra(graph);
            var res = dijkstra.Execute(0);

            Console.WriteLine("Yes");
            for (int i = 1; i < res.Length; i++)
            {
                Console.WriteLine(res[i].prevIndex + 1);
            }
        }

        // グラフ表現
        public struct Edge
        {
            public int start, end;
            public double cost;

            public Edge(int s, int e, double c)
            {
                start = s; end = e; cost = c;
            }
        }

        public class Vertex : IComparable<Vertex>
        {
            public double distance = double.MaxValue;
            public int index = -1;
            public int prevIndex = -1;

            public int CompareTo([AllowNull] Vertex other)
            {
                return distance.CompareTo(other.distance);
            }
        }

        public class Graph
        {
            public List<Edge> Edges { get; private set; }
            public int vertexNum;

            public Graph(long vertexNum, IEnumerable<Edge> edges)
            {
                this.vertexNum = (int)vertexNum;
                Edges = new List<Edge>(edges);
            }

            public Graph(long vertexNum, List<List<long>> edgeDatas)
                : this(vertexNum, edgeDatas.Select(ll => new Edge((int)ll[0], (int)ll[1], ll[2]))) { }

            // minimizeCost: 多重辺が存在する場合最小コストのものを選択するかどうか
            public double[][] GetAdjacencyMatrix(bool minimizeCost = true)
            {
                double[][] res = new double[vertexNum][];
                for (int i = 0; i < vertexNum; ++i) res[i] = new double[vertexNum];

                for (int i = 0; i < vertexNum; ++i) res[i][i] = 0;
                if (minimizeCost)
                {
                    foreach (var edge in Edges)
                        res[edge.start][edge.end] = Math.Min(edge.cost, res[edge.start][edge.end]);
                }
                else
                {
                    foreach (var edge in Edges)
                        res[edge.start][edge.end] = edge.cost;
                }
                return res;
            }
        }

        // Dijkstra Algorithm
        // 非負コストのグラフに適用可能
        // 2点間最短経路探索、O((E + V)logV)
        public class Dijkstra
        {
            private Graph graph;

            public Dijkstra(Graph g) { graph = g; }

            public Vertex[] Execute(long start)
            {
                Vertex[] vertices = new Vertex[graph.vertexNum];
                for (int i = 0; i < vertices.Length; ++i)
                {
                    vertices[i] = new Vertex
                    {
                        index = i
                    };
                }
                //var adjGraph = graph.GetAdjacencyMatrix();

                //始点への最短距離 = 0
                vertices[start].distance = 0;

                PriorityQueue<Vertex> queue = new PriorityQueue<Vertex>();
                queue.Enqueue(vertices[start]);
                while (queue.Count > 0)
                {
                    var fromV = queue.Dequeue();
                    foreach (var edge in graph.Edges) // 頂点vから出る辺eを走査
                    {
                        if (edge.start == fromV.index &&
                            vertices[edge.end].distance > vertices[edge.start].distance + edge.cost)
                        {
                            vertices[edge.end].distance = vertices[edge.start].distance + edge.cost;
                            vertices[edge.end].prevIndex = edge.start;
                            queue.Enqueue(vertices[edge.end]);
                        }
                    }
                }

                return vertices;
            }
        }


        static IEnumerator<string> input_iter;
        
        static IEnumerator<string> LazyLoadAllLines(bool doSplit = true)
        {
            string line;
            if (doSplit)
            {
                do
                {
                    line = Console.ReadLine();
                    foreach (var s in line.Split(' '))
                        yield return s;
                } while (line != null);
            }
            else
            {
                do
                {
                    line = Console.ReadLine();
                    yield return line;
                } while (line != null);
            }
        }
        // single 1 elem.
        static _T Read<_T>() where _T : struct
        {
            input_iter.MoveNext();
            return (_T)Convert.ChangeType(input_iter.Current, typeof(_T));
        }
        static string Read()
        {
            input_iter.MoveNext();
            return input_iter.Current;
        }
        // single n-elems.
        static List<_T> Read<_T>(long num) where _T : struct
        {
            List<_T> res = new List<_T>();
            for (long i = 0; i < num; ++i)
            {
                input_iter.MoveNext();
                res.Add((_T)Convert.ChangeType(input_iter.Current, typeof(_T)));
            }
            return res;
        }
        static List<string> Read(long num)
        {
            List<string> res = new List<string>();
            for (long i = 0; i < num; ++i)
            {
                input_iter.MoveNext();
                res.Add(input_iter.Current);
            }
            return res;
        }
        // multiple(single type) n-elems. (Range, Edge etc.)
        static List<List<_T>> Read<_T>(long elemNum, long typeNum, bool toSort = false) where _T : struct
        {
            List<List<_T>> res = new List<List<_T>>();
            for (int i = 0; i < elemNum; ++i)
            {
                var elem = Read<_T>(typeNum);
                if (toSort) elem.Sort();
                res.Add(elem);
            }
            return res;
        }
        // multiple(multiple type) n-elems.
        static List<(_T1, _T2)> Read<_T1, _T2>(long num) where _T1 : struct where _T2 : struct
        {
            List<(_T1, _T2)> res = new List<(_T1, _T2)>();
            for (int i = 0; i < num; ++i)
            {
                res.Add((Read<_T1>(), Read<_T2>()));
            }
            return res;
        }
        static List<(_T1, _T2, _T3)> Read<_T1, _T2, _T3>(long num) where _T1 : struct where _T2 : struct where _T3 : struct
        {
            List<(_T1, _T2, _T3)> res = new List<(_T1, _T2, _T3)>();
            for (int i = 0; i < num; ++i)
            {
                res.Add((Read<_T1>(), Read<_T2>(), Read<_T3>()));
            }
            return res;
        }

        static void Swap<_T>(ref _T l, ref _T r)
        {
            _T temp = l;
            l = r;
            r = temp;
        }

        public class PriorityQueue<T> : IEnumerable<T>
        {
            private readonly List<T> _data = new List<T>();
            private readonly IComparer<T> _comparer;
            private readonly bool _isDescending;

            public PriorityQueue(IComparer<T> comparer, bool isDescending = true)
            {
                _comparer = comparer;
                _isDescending = isDescending;
            }

            public PriorityQueue(Comparison<T> comparison, bool isDescending = true)
                : this(Comparer<T>.Create(comparison), isDescending)
            {
            }

            public PriorityQueue(bool isDescending = true)
                : this(Comparer<T>.Default, isDescending)
            {
            }

            public void Enqueue(T item)
            {
                _data.Add(item);
                var childIndex = _data.Count - 1;
                while (childIndex > 0)
                {
                    var parentIndex = (childIndex - 1) / 2;
                    if (Compare(_data[childIndex], _data[parentIndex]) >= 0)
                        break;
                    Swap(childIndex, parentIndex);
                    childIndex = parentIndex;
                }
            }

            public T Dequeue()
            {
                var lastIndex = _data.Count - 1;
                var firstItem = _data[0];
                _data[0] = _data[lastIndex];
                _data.RemoveAt(lastIndex--);
                var parentIndex = 0;
                while (true)
                {
                    var childIndex = parentIndex * 2 + 1;
                    if (childIndex > lastIndex)
                        break;
                    var rightChild = childIndex + 1;
                    if (rightChild <= lastIndex && Compare(_data[rightChild], _data[childIndex]) < 0)
                        childIndex = rightChild;
                    if (Compare(_data[parentIndex], _data[childIndex]) <= 0)
                        break;
                    Swap(parentIndex, childIndex);
                    parentIndex = childIndex;
                }
                return firstItem;
            }

            public T Peek()
            {
                return _data[0];
            }

            public void Clear()
            {
                _data.Clear();
            }

            private void Swap(int a, int b)
            {
                var tmp = _data[a];
                _data[a] = _data[b];
                _data[b] = tmp;
            }

            private int Compare(T a, T b)
            {
                return _isDescending ? _comparer.Compare(b, a) : _comparer.Compare(a, b);
            }

            public int Count => _data.Count;

            public IEnumerator<T> GetEnumerator()
            {
                return _data.GetEnumerator();
            }

            IEnumerator IEnumerable.GetEnumerator() => GetEnumerator();
        }

    }
}