Buggy python submission (verdict: Time Limit Exceeded):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from itertools import permutations, accumulate, combinations, combinations_with_replacement
from math import sqrt, ceil, floor, factorial
from bisect import bisect_left, bisect_right, insort_left, insort_right
from copy import deepcopy
from operator import itemgetter
from functools import reduce
from fractions import gcd
import sys
def input(): return sys.stdin.readline().rstrip()
def I(): return int(input())
def Is(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def IR(n): return [I() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def TIR(n): return [TI() for _ in range(n)]
def S(): return input()
def Ss(): return input().split()
def LS(): return list(input())
def SR(n): return [S() for _ in range(n)]
def SsR(n): return [Ss() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
sys.setrecursionlimit(10**6)
MOD = 10**9+7
INF = 10**18
# ----------------------------------------------------------- #

n, m = Is()
AB = TIR(m)
C = [[INF]*n for _ in range(n)]
for a, b in AB:
    a -= 1
    b -= 1
    C[a][b] = 1
    C[b][a] = 1

# ANS = [INF]*n

#
# def dijkstra(s, n, w, cost):
#     # 始点sから各頂点への最短距離
#     # n:頂点数, w:辺の数, cost[u][v] : 辺uvのコスト(存在しないときはinf)
#     d = [float("inf")] * n
#     used = [False] * n
#     d[s] = 0
#
#     while True:
#         v = -1
#         # まだ使われてない頂点の中から最小の距離のものを探す
#         for i in range(n):
#             if (not used[i]) and (v == -1):
#                 v = i
#             elif (not used[i]) and d[i] < d[v]:
#                 v = i
#         if v == -1:
#             break
#         used[v] = True
#
#         for j in range(n):
#             d[j] = min(d[j], d[v] + cost[v][j])
#     return d

# print(dijkstra(0, n, m, C))

def dijkstra_back(s, t, n, w, cost):
    # sからtへの最短経路の経路復元
    prev = [s] * n  # 最短経路の直前の頂点
    d = [float("inf")] * n
    used = [False] * n
    d[s] = 0

    while True:
        v = -1
        for i in range(n):
            if (not used[i]) and (v == -1):
                v = i
            elif (not used[i]) and d[i] < d[v]:
                v = i
        if v == -1:
            break
        used[v] = True

        for i in range(n):
            if d[i] > d[v] + cost[v][i]:
                d[i] = d[v] + cost[v][i]
                prev[i] = v

    return prev

ANS = dijkstra_back(0, n-1, n, m, C)[1:]
print("Yes")
for ans in ANS:
    print(ans+1)


# for i in range(n):
#     if ANS[i] != INF:
#         continue
#     path = dijkstra_back(0, i, n, m, C)
#     for j, x in enumerate(path):
#         if j == 0:
#             continue
#         else:
#             ANS[x] = path[j-1]
#
# print("Yes")
# for ans in ANS[1:]:
#     print(ans+1)


Fixed submission:
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from itertools import permutations, accumulate, combinations, combinations_with_replacement
from math import sqrt, ceil, floor, factorial
from bisect import bisect_left, bisect_right, insort_left, insort_right
from copy import deepcopy
from operator import itemgetter
from functools import reduce
from fractions import gcd
import sys
def input(): return sys.stdin.readline().rstrip()
def I(): return int(input())
def Is(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def IR(n): return [I() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def TIR(n): return [TI() for _ in range(n)]
def S(): return input()
def Ss(): return input().split()
def LS(): return list(input())
def SR(n): return [S() for _ in range(n)]
def SsR(n): return [Ss() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
sys.setrecursionlimit(10**6)
MOD = 10**9+7
INF = 10**18
# ----------------------------------------------------------- #

n, m = Is()
AB = TIR(m)
C = [set() for _ in range(n)]
for a, b in AB:
    a -= 1
    b -= 1
    C[a].add(b)
    C[b].add(a)

ANS = [INF]*n
visited = [False]*n
def bfs():
    que = deque()
    que.append(0)
    while que:
        x = que.popleft()
        visited[x] = True
        for y in C[x]:
            if not visited[y]:
                ANS[y] = x
                que.append(y)
                visited[y] = True

bfs()
print("Yes")
for ans in ANS[1:]:
    print(ans+1)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from itertools import permutations, accumulate, combinations, combinations_with_replacement
from math import sqrt, ceil, floor, factorial
from bisect import bisect_left, bisect_right, insort_left, insort_right
from copy import deepcopy
from operator import itemgetter
from functools import reduce
from fractions import gcd
import sys
def input(): return sys.stdin.readline().rstrip()
def I(): return int(input())
def Is(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def IR(n): return [I() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def TIR(n): return [TI() for _ in range(n)]
def S(): return input()
def Ss(): return input().split()
def LS(): return list(input())
def SR(n): return [S() for _ in range(n)]
def SsR(n): return [Ss() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
sys.setrecursionlimit(10**6)
MOD = 10**9+7
INF = 10**18
# ----------------------------------------------------------- #

n, m = Is()
AB = TIR(m)
C = [[INF]*n for _ in range(n)]
for a, b in AB:
    a -= 1
    b -= 1
    C[a][b] = 1
    C[b][a] = 1

def dijkstra_back(s, t, n, w, cost):
    # sからtへの最短経路の経路復元
    prev = [s] * n  # 最短経路の直前の頂点
    d = [float("inf")] * n
    used = [False] * n
    d[s] = 0

    while True:
        v = -1
        for i in range(n):
            if (not used[i]) and (v == -1):
                v = i
            elif (not used[i]) and d[i] < d[v]:
                v = i
        if v == -1:
            break
        used[v] = True

        for i in range(n):
            if d[i] > d[v] + cost[v][i]:
                d[i] = d[v] + cost[v][i]
                prev[i] = v

    path = [t]
    while prev[t] != s:
        path.append(prev[t])
        prev[t] = prev[prev[t]]
    path.append(s)
    path = path[::-1]
    return path

ANS = [INF]*n
for i in range(n):
    if ANS[i] != INF:
        continue
    path = dijkstra_back(0, i, n, m, C)
    for j, x in enumerate(path):
        if j == 0:
            continue
        else:
            ANS[x] = path[j-1]

print("Yes")
for ans in ANS[1:]:
    print(ans+1)


Fixed submission:
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from itertools import permutations, accumulate, combinations, combinations_with_replacement
from math import sqrt, ceil, floor, factorial
from bisect import bisect_left, bisect_right, insort_left, insort_right
from copy import deepcopy
from operator import itemgetter
from functools import reduce
from fractions import gcd
import sys
def input(): return sys.stdin.readline().rstrip()
def I(): return int(input())
def Is(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def IR(n): return [I() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def TIR(n): return [TI() for _ in range(n)]
def S(): return input()
def Ss(): return input().split()
def LS(): return list(input())
def SR(n): return [S() for _ in range(n)]
def SsR(n): return [Ss() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
sys.setrecursionlimit(10**6)
MOD = 10**9+7
INF = 10**18
# ----------------------------------------------------------- #

n, m = Is()
AB = TIR(m)
C = [set() for _ in range(n)]
for a, b in AB:
    a -= 1
    b -= 1
    C[a].add(b)
    C[b].add(a)

ANS = [INF]*n
visited = [False]*n
def bfs():
    que = deque()
    que.append(0)
    while que:
        x = que.popleft()
        visited[x] = True
        for y in C[x]:
            if not visited[y]:
                ANS[y] = x
                que.append(y)
                visited[y] = True

bfs()
print("Yes")
for ans in ANS[1:]:
    print(ans+1)

Buggy python submission (verdict: Time Limit Exceeded):
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from itertools import permutations, accumulate, combinations, combinations_with_replacement
from math import sqrt, ceil, floor, factorial
from bisect import bisect_left, bisect_right, insort_left, insort_right
from copy import deepcopy
from operator import itemgetter
from functools import reduce
from fractions import gcd
import sys
def input(): return sys.stdin.readline().rstrip()
def I(): return int(input())
def Is(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def IR(n): return [I() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def TIR(n): return [TI() for _ in range(n)]
def S(): return input()
def Ss(): return input().split()
def LS(): return list(input())
def SR(n): return [S() for _ in range(n)]
def SsR(n): return [Ss() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
sys.setrecursionlimit(10**6)
MOD = 10**9+7
INF = 10**18
# ----------------------------------------------------------- #

n, m = Is()
AB = TIR(m)
C = [[INF]*n for _ in range(n)]
for a, b in AB:
    a -= 1
    b -= 1
    C[a][b] = 1
    C[b][a] = 1

def dijkstra_back(s, t, n, w, cost):
    # sからtへの最短経路の経路復元
    prev = [s] * n  # 最短経路の直前の頂点
    d = [float("inf")] * n
    used = [False] * n
    d[s] = 0

    while True:
        v = -1
        for i in range(n):
            if (not used[i]) and (v == -1):
                v = i
            elif (not used[i]) and d[i] < d[v]:
                v = i
        if v == -1:
            break
        used[v] = True

        for i in range(n):
            if d[i] > d[v] + cost[v][i]:
                d[i] = d[v] + cost[v][i]
                prev[i] = v

    path = [t]
    while prev[t] != s:
        path.append(prev[t])
        prev[t] = prev[prev[t]]
    path.append(s)
    path = path[::-1]
    return path


print("Yes")
for i in range(1, n):
    print(dijkstra_back(0, i, n, m, C)[-2] + 1)

Fixed submission:
from collections import defaultdict, deque, Counter
from heapq import heappush, heappop, heapify
from itertools import permutations, accumulate, combinations, combinations_with_replacement
from math import sqrt, ceil, floor, factorial
from bisect import bisect_left, bisect_right, insort_left, insort_right
from copy import deepcopy
from operator import itemgetter
from functools import reduce
from fractions import gcd
import sys
def input(): return sys.stdin.readline().rstrip()
def I(): return int(input())
def Is(): return map(int, input().split())
def LI(): return list(map(int, input().split()))
def TI(): return tuple(map(int, input().split()))
def IR(n): return [I() for _ in range(n)]
def LIR(n): return [LI() for _ in range(n)]
def TIR(n): return [TI() for _ in range(n)]
def S(): return input()
def Ss(): return input().split()
def LS(): return list(input())
def SR(n): return [S() for _ in range(n)]
def SsR(n): return [Ss() for _ in range(n)]
def LSR(n): return [LS() for _ in range(n)]
sys.setrecursionlimit(10**6)
MOD = 10**9+7
INF = 10**18
# ----------------------------------------------------------- #

n, m = Is()
AB = TIR(m)
C = [set() for _ in range(n)]
for a, b in AB:
    a -= 1
    b -= 1
    C[a].add(b)
    C[b].add(a)

ANS = [INF]*n
visited = [False]*n
def bfs():
    que = deque()
    que.append(0)
    while que:
        x = que.popleft()
        visited[x] = True
        for y in C[x]:
            if not visited[y]:
                ANS[y] = x
                que.append(y)
                visited[y] = True

bfs()
print("Yes")
for ans in ANS[1:]:
    print(ans+1)