import java.util.*

fun main() {

    val (n, m) = readLine()!!.split(" ").map(String::toInt)

    data class Edge(val from: Int, val to: Int, val cost: Int)

    val list = mutableListOf<Edge>()
    repeat(m) {
        val (f, t) = readLine()!!.split(" ").map(String::toInt)
        list.add(Edge(f - 1, t - 1, 1))
        list.add(Edge(t - 1, f - 1, 1))
    }
    val graph = list.groupBy { it.from }

    val d = Array(n) { Pair(Integer.MAX_VALUE, -1) }

    fun dijkstra(s: Int) {
        // first 頂点番号 second 最短距離
        val q = PriorityQueue<Pair<Int, Int>>(n) { p1, p2 ->
            p1.second - p2.second
        }

        d[s] = 0 to 0
        q.add(s to 0)

        while (q.isNotEmpty()) {
            val (from, cost) = q.poll()
//            println(from)
//            println("from:$from cost:$cost")
            // コストが低いのが登録済みであれば処理をスキップする。
            if (d[from].first < cost) {
                continue
            }

            for (edge in graph[from] ?: emptyList()) {
                if (d[edge.to].first > d[edge.from].first + edge.cost) {
                    d[edge.to] = (d[edge.from].first + edge.cost) to edge.from
                    q.add(edge.to to d[edge.to].first)
                }
            }
        }
    }

    dijkstra(0)

    if (d.any { it.first == Integer.MAX_VALUE }) {
        println("No")
    } else {
        println("Yes")
        for (i in 1..d.lastIndex) {
            println(d[i].second+1)
        }
    }

}



