using System;
using System.IO;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace AtCoder.Contest.D
{
	static class Program
	{
		public static void Main(string[] args)
		{
			var sw = new StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false };
			Console.SetOut(sw);

			Scanner cin = new Scanner();

			int n = cin.NextInt();
			int m = cin.NextInt();
			var link = new List<List<int>>();
			var par = new List<int>();

			for (int i = 0; i < n; i++)
			{
				link.Add(new List<int>());
				par.Add(-1);
			}
			par[0] = 0;
			for (int i = 0; i < m; i++)
			{
				int a = cin.NextInt();
				int b = cin.NextInt();
				link[a - 1].Add(b - 1);
				link[b - 1].Add(a - 1);
			}
			var q = new Queue<int>();
			q.Enqueue(0);
			int seen = 1;
			bool ok = true;
			while (seen < n)
			{
				int now = q.Dequeue();
				foreach (var item in link[now])
				{
					if (par[item] == -1)
					{
						par[item] = now;
						q.Enqueue(item);
						seen++;
					}
				}
			}
			if (ok)
			{
				Console.WriteLine("Yes");
				for (int i = 1; i < n; i++)
				{
					Console.WriteLine(par[i] + 1);
				}
			}
			else
			{
				Console.WriteLine("No");
			}

			Console.Out.Flush();
		}
	}

	/// <summary>
	/// Get min cost between two points
	/// </summary>
	public class Dijkstra
	{
		private int maxIndex = -1;
		private const int INF = Int32.MaxValue;

		private int[,] _edgeArray;

		/// <summary>
		/// Dijkstra, get min cost between two points
		/// should not contain negatie cost path
		/// </summary>
		/// <param name="size">max index of vertices</param>
		public Dijkstra(int size)
		{
			maxIndex = size + 1;
			_edgeArray = new int[maxIndex, maxIndex];

			for (int i = 0; i < _edgeArray.GetLength(0); i++)
			{
				for (int j = 0; j < _edgeArray.GetLength(1); j++)
				{
					_edgeArray[i, j] = INF;
					if (i == j) _edgeArray[i, j] = 0;
				}
			}
		}

		// Add a path(no direction) with its cost
		public void AddPath(int s, int t, int cost)
		{
			_edgeArray[s, t] = Math.Min(_edgeArray[s, t], cost);
			_edgeArray[t, s] = _edgeArray[s, t];
		}

		//Get the min cost between s and t
		//return Int32.MaxValue if no path
		public int GetMinCost(int s, int t)
		{
			int[] cost = new int[maxIndex];
			for (int i = 0; i < cost.Length; i++) cost[i] = INF;
			cost[s] = 0;

			var priorityQueue = new PriorityQueue<ComparablePair<int, int>>(maxIndex);
			priorityQueue.Push(new ComparablePair<int, int>(0, s));

			while (priorityQueue.Count() > 0)
			{
				var costDestinationPair = priorityQueue.Pop();
				if (cost[costDestinationPair.Item2] < costDestinationPair.Item1) continue;

				for (int i = 0; i < maxIndex; i++)
				{
					int newCostToi = _edgeArray[costDestinationPair.Item2, i] == INF ? INF :
						costDestinationPair.Item1 + _edgeArray[costDestinationPair.Item2, i];
					if (newCostToi < cost[i])
					{
						cost[i] = newCostToi;
						priorityQueue.Push(new ComparablePair<int, int>(newCostToi, i));
					}
				}
			}

			return cost[t];
		}
	}

	public class PriorityQueue<T> where T : IComparable
	{
		private IComparer<T> _comparer = null;
		private int _type = 0;

		private T[] _heap;
		private int _sz = 0;

		private int _count = 0;

		/// <summary>
		/// Priority Queue with custom comparer
		/// </summary>
		public PriorityQueue(int maxSize, IComparer<T> comparer)
		{
			_heap = new T[maxSize];
			_comparer = comparer;
		}

		/// <summary>
		/// Priority queue
		/// </summary>
		/// <param name="maxSize">max size</param>
		/// <param name="type">0: asc, 1:desc</param>
		public PriorityQueue(int maxSize, int type = 0)
		{
			_heap = new T[maxSize];
			_type = type;
		}

		private int Compare(T x, T y)
		{
			if (_comparer != null) return _comparer.Compare(x, y);
			return _type == 0 ? x.CompareTo(y) : y.CompareTo(x);
		}

		public void Push(T x)
		{
			_count++;

			//node number
			var i = _sz++;

			while (i > 0)
			{
				//parent node number
				var p = (i - 1) / 2;

				if (Compare(_heap[p], x) <= 0) break;

				_heap[i] = _heap[p];
				i = p;
			}

			_heap[i] = x;
		}

		public T Pop()
		{
			_count--;

			T ret = _heap[0];
			T x = _heap[--_sz];

			int i = 0;
			while (i * 2 + 1 < _sz)
			{
				//children
				int a = i * 2 + 1;
				int b = i * 2 + 2;

				if (b < _sz && Compare(_heap[b], _heap[a]) < 0) a = b;

				if (Compare(_heap[a], x) >= 0) break;

				_heap[i] = _heap[a];
				i = a;
			}

			_heap[i] = x;

			return ret;
		}

		public int Count()
		{
			return _count;
		}

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

		public bool Contains(T x)
		{
			for (int i = 0; i < _sz; i++) if (x.Equals(_heap[i])) return true;
			return false;
		}

		public void Clear()
		{
			while (this.Count() > 0) this.Pop();
		}

		public IEnumerator<T> GetEnumerator()
		{
			var ret = new List<T>();

			while (this.Count() > 0)
			{
				ret.Add(this.Pop());
			}

			foreach (var r in ret)
			{
				this.Push(r);
				yield return r;
			}
		}

		public T[] ToArray()
		{
			T[] array = new T[_sz];
			int i = 0;

			foreach (var r in this)
			{
				array[i++] = r;
			}

			return array;
		}
	}

	public class ComparablePair<T, U> : IComparable where T : IComparable<T>
	{
		public readonly T Item1;
		public readonly U Item2;

		public int CompareTo(object obj)
		{
			ComparablePair<T, U> castedObj = (ComparablePair<T, U>)obj;
			return this.Item1.CompareTo(castedObj.Item1);
		}

		public ComparablePair(T t, U u)
		{
			Item1 = t;
			Item2 = u;
		}
	}

	class Scanner
	{
		string[] s;
		int i;

		char[] cs = new char[] { ' ' };

		public Scanner()
		{
			s = new string[0];
			i = 0;
		}

		public string Next()
		{
			if (i < s.Length) return s[i++];
			string st = Console.ReadLine();
			while (st == "") st = Console.ReadLine();
			s = st.Split(cs, StringSplitOptions.RemoveEmptyEntries);
			if (s.Length == 0) return Next();
			i = 0;
			return s[i++];
		}

		public int NextInt()
		{
			return int.Parse(Next());
		}

		public int[] ArrayInt(int N, int add = 0)
		{
			int[] Array = new int[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = NextInt() + add;
			}
			return Array;
		}

		public long NextLong()
		{
			return long.Parse(Next());
		}

		public long[] ArrayLong(int N, long add = 0)
		{
			long[] Array = new long[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = NextLong() + add;
			}
			return Array;
		}

		public double NextDouble()
		{
			return double.Parse(Next());
		}

		public double[] ArrayDouble(int N, double add = 0)
		{
			double[] Array = new double[N];
			for (int i = 0; i < N; i++)
			{
				Array[i] = NextDouble() + add;
			}
			return Array;
		}
	}
}

Measured memory_bytes: 51360