#include <stdio.h>
#include <stdlib.h>
#define rep(i, n) for (int i = 0; i < (int)(n); i++)
#define max(a, b) ((a) > (b) ? (a) : (b))
#define min(a, b) ((a) < (b) ? (a) : (b))
#define MAX_DATA 100100
typedef long long ll;

struct queue
{
    int arr[MAX_DATA];
    int first; //次にpopする配列の添え字
    int last;  //次にpushする配列の添え字
};

int push(struct queue *que, int input)
{
    if (que->arr[que->last] <= MAX_DATA)
    {
        que->arr[que->last] = input;
        que->last++;
        //printf("push:%d\n", input);
        return 0;
    }
    else
    {
        printf("これ以上データを追加できません。\n");
        return -1;
    }
}

int pop(struct queue *que)
{
    int output = que->arr[que->first];

    if (output != -1)
    {
        que->arr[que->first] = -1;
        que->first++;
        //printf("pop:%d\n", output);
        return output;
    }
    else
    {
        printf("データがありません。\n");
        return -1;
    }
}

void init_queue(struct queue *que)
{
    int i;

    for (i = 0; i < MAX_DATA; i++)
        que->arr[i] = -1;

    que->first = 0;
    que->last = 0;
}

void show_queue(struct queue *que, int n)
{
    int i;
    for (i = 0; i < n; i++)
    {
        if (que->arr[i] != -1)
            printf("%d ", que->arr[i]);
    }

    printf("\nfirst:%d last%d\n\n", que->first, que->last);
}

int main(void)
{
    long *graph[100001], cnt[100001] = {0};
    long n, m;
    int ans[100100] = {0};

    scanf("%ld%ld", &n, &m);
    rep(i, m)
    {
        long a, b;
        scanf("%ld%ld", &a, &b);

        graph[a] = (long *)realloc(graph[a], sizeof(long) * (cnt[a] + 1));
        graph[a][cnt[a]] = b;
        cnt[a]++;

        graph[b] = (long *)realloc(graph[b], sizeof(long) * (cnt[b] + 1));
        graph[b][cnt[b]] = a;
        cnt[b]++;
    }
    graph[0] = (long *)realloc(graph[0], sizeof(long) * (cnt[0] + 1));
    graph[0][cnt[0]] = 0;
    cnt[0]++;
    /*
    rep(i, n + 1)
    {
        printf("graph[%d]={ ", i);
        rep(j, cnt[i])
            printf("%ld ", graph[i][j]);
        printf("} cnt:%ld\n", cnt[i]);
    }
*/
    // 初期化してから先頭に1をpush
    struct queue que;
    init_queue(&que);
    push(&que, 1);

    // -1：未発見の頂点
    // 頂点1を初期ノードとして初期化
    int dist[n + 1];
    rep(i, n + 1)
        dist[i] = -1;
    dist[1] = 0;

    // queが空になるまで探索
    while (que.first != que.last)
    {
        // queから先頭頂点を取り出す
        int v = pop(&que);

        // vから訪問できる頂点を調べる
        rep(i, cnt[v])
        {
            // graphから頂点を取得し発見済みは探索しない
            int nv = graph[v][i];
            if (dist[nv] != -1)
                continue;

            // 未発見の頂点nvについて距離を更新してqueにpush
            dist[nv] = dist[v] + 1;
            ans[nv] = v;
            push(&que, nv);
        }
        //show_queue(&que, n);
    }

    puts("Yes");
    for (int i = 2; i < n + 1; i++)
        printf("%d\n", ans[i]);

    return 0;
}