import heapq
class Dijkstra:
    """
    使用方法

    # ゴールが設定されていなかった場合、
    # スタートから各頂点までの最短距離を格納したリストを返す
    dijkstra_result = Dijkstra(n, mp2, s - 1).execute()

    # 設定されていた場合、
    # ゴールまでの最短経路と距離を2つ返す
    dijkstra_result = Dijkstra(n, mp2, s - 1, t - 1).execute()

    # mp2の例 [[現在地, 繋がっている先の場所, 距離], [...]]
    # mp2 = [[2, 4, 2], [3, 4, 5], [3, 2, 1], [1, 3, 2], [2, 0, 8], [0, 2, 8], [1, 2, 4], [0, 1, 3]]
    """

    def __init__(self, n, mp2, start_point, goal_point=None):
        rote_map = [dict() for _ in range(n)]
        for ele in mp2:
            u, v, l = map(int, ele)
            rote_map[u-1][v-1] = l
            # 道が一方通行の場合は下の１行を消す
            rote_map[v - 1][u - 1] = l
        self.rote_map = rote_map
        self.start_point = start_point - 1
        if goal_point == None:
            self.goal_point = goal_point
        else:
            self.goal_point = goal_point - 1

    def execute(self):
        num_of_city = len(self.rote_map)
        dist = [float("inf") for _ in range(num_of_city)]
        prev = [float("inf") for _ in range(num_of_city)]

        dist[self.start_point] = 0
        heap_q = []
        heapq.heappush(heap_q, (0, self.start_point))
        while len(heap_q) != 0:
            prev_cost, src = heapq.heappop(heap_q)

            if dist[src] < prev_cost:
                continue

            for dest, cost in self.rote_map[src].items():
                if cost != float("inf") and dist[dest] > dist[src] + cost:
                    dist[dest] = dist[src] + cost
                    heapq.heappush(heap_q, (dist[dest], dest))
                    prev[dest] = src
        if self.goal_point is not None:
            return self.get_path(self.goal_point, prev), dist[self.goal_point]
        else:
            return dist

    def get_path(self, goal, prev):
        path = [goal]
        dest = goal

        while prev[dest] != float("inf"):
            path.append(prev[dest])
            dest = prev[dest]

        return [n + 1 for n in list(reversed(path))]


n, m = map(int, input().split())
mp2 =[]

for _ in range(m):
    aa, bb = map(int, input().split())
    mp2.append([aa-1, bb-1, 1])

dijkstra_result = []
for i in range(2, n+1):
    result = Dijkstra(n, mp2, i - 1, 1 - 1).execute()
    # print(result)
    dijkstra_result.append(result)

# print(dijkstra_result)
if float('inf') in dijkstra_result[1]:
    print("No")
else:
    print("Yes")
    for i in dijkstra_result:
        print(i[0][1]+1)

### FIXED CODE ###

# ダイクストラ法
# connections = [[[町ｘ, コスト], [町y, コスト]], ...]
import heapq as hq


def D_stra(N, connections, st):
    mxc = float("inf") #2 ** 29
    cost = [mxc for i in range(N)]
    route = [mxc for i in range(N)]
    visited = [False for i in range(N)]
    cost[st] = 0
    q = []

    hq.heappush(q, (0, st))

    while q:
        c, node = hq.heappop(q)
        if visited[node]:
            continue
        visited[node] = True

        for connection in connections[node]:
            target, mc = connection
            if cost[target] > c + mc:
                cost[target] = c + mc
                hq.heappush(q, (c + mc, target))
                route[target] = node


    return cost, route

n, m = map(int, input().split())
mp2 =[]

connections = [[] for _ in range(n)]
for _ in range(m):
    aa, bb = map(int, input().split())
    connections[aa-1].append([bb-1, 1])
    connections[bb-1].append([aa-1, 1])

dijkstra_result = []
_, result = D_stra(n, connections, 0)

if float("inf") in result[1:]:
    print("No")
else:
    print("Yes")
    for i in range(1, n):
        print(result[i]+1)