#include <bits/stdc++.h>
using namespace std;

#define d(x) cerr << #x ":" << x << endl;
#define dd(x, y) cerr << "(" #x "," #y "):(" << x << "," << y << ")" << endl
#define rep(i, n) for (int i = (int)(0); i < (int)(n); i++)
#define repp(i, a, b) for (int i = (int)(a); i < (int)(b); i++)
#define all(v) v.begin(), v.end()
#define dump(v)                  \
    cerr << #v ":[ ";            \
    for (auto macro_vi : v) {    \
        cerr << macro_vi << " "; \
    }                            \
    cerr << "]" << endl;
#define ddump(v)                           \
    cerr << #v ":" << endl;                \
    for (auto macro_row : v) {             \
        cerr << "[";                       \
        for (auto macro__vi : macro_row) { \
            cerr << macro__vi << " ";      \
        }                                  \
        cerr << "]" << endl;               \
    }
using lint       = long long;
const int INF    = 1e9;
const lint LINF  = 1e18;
const lint MOD   = 1e9 + 7;
const double EPS = 1e-10;

struct Graph {
    struct Edge {
        int from;
        int to;
        int cost;
        int index;
        int color;
    };
    struct Node {
        int index;
        bool check;
        int color;
        lint dist;
        std::vector<Edge> edges;
        Node() {
            index = -1;
            check = false;
            color = -1;
            dist  = INF;
            std::vector<Edge>(0);
        }
    };

    int numNodes;
    int numColor;
    bool directed;
    std::vector<Node> nodes;
    std::vector<Edge> edges;

    Graph(int N) : numNodes(N), nodes(N) {
        for (int i = 0; i < N; i++)
            nodes[i].index = i;
        numColor = -1;
        directed = false;
    }
    Graph(int N, bool directed) : numNodes(N), nodes(N) {
        for (int i = 0; i < N; i++)
            nodes[i].index = i;
        numColor = -1;
        directed = true;
    }

    void addEdge(int from, int to) {
        nodes[from].edges.push_back(Edge({from, to}));
        if (!directed) nodes[to].edges.push_back(Edge({to, from}));
    }

    void bfs(int startIndex) {
        for (auto& node : nodes)
            node.dist = INF;
        nodes[startIndex].dist = 0;
        std::queue<int> que({startIndex});
        while (!que.empty()) {
            int currentIndex = que.front();
            que.pop();
            for (auto edge : nodes[currentIndex].edges) {
                if (nodes[edge.to].dist == INF) {
                    nodes[edge.to].dist = nodes[currentIndex].dist + 1;
                    que.push(edge.to);
                }
            }
        }
    }

    void coloring() {
        int c = 0;
        for (auto& node : nodes) {
            if (node.color != -1) continue;
            node.color = c;
            std::queue<int> que({node.index});
            while (!que.empty()) {
                int currentIndex = que.front();
                for (auto edge : nodes[currentIndex].edges) {
                    if (nodes[edge.to].color != -1) continue;
                    nodes[edge.to].color = c;
                    que.push(nodes[edge.to].index);
                }
            }
            c++;
        }
        numColor = c;
    }
};

int main() {
    lint N, M;
    cin >> N >> M;
    vector<vector<int>> G(N, vector<int>(0));
    rep(i, M) {
        int u, v;
        cin >> u >> v;
        u--, v--;
        G[u].push_back(v);
        G[v].push_back(u);
    }
    vector<int> dist(N, INF);
    vector<int> to(N, INF);
    // ddump(G);
    int cn = 0;
    queue<int> q;
    q.push(cn);
    dist[cn] = 0;
    to[cn]   = INF;
    while (!q.empty()) {
        cn = q.front();
        q.pop();
        for (auto nx : G[cn]) {
            if (dist[nx] == INF) {
                dist[nx] = dist[cn] + 1;
                to[nx]   = cn;
                q.push(nx);
            }
        }
    }
    // dump(dist);
    // dump(to);
    cout << "Yes" << endl;
    for (int i = 1; i < N; i++) {
        int u = i + 1, t = to[i] + 1;
        cout << t << endl;
    }
    return 0;
}

Measured memory_bytes: 10668