#include <iostream>
#include <vector>
#include <algorithm>
#include <map>
#include <set>
#include <cmath>
#include <cstring>
#include <iomanip>
#include <random>
#include <chrono>
#include <queue>
#include <math.h>
#include <string>
#include <sstream>
#include <stack>
#include <deque>
#define pb push_back
#define make make_pair
#define kaku(a) cout << a << endl
#define isort(a) sort(a.begin(),a.end())

using namespace std;

#define ll long long
#define rep(i,n) for(ll i=0;i<n;i++)
#define PI 3.14159265359
long long gcd(long long a,long long b){ return b==0?a:gcd(b,a%b);}
long long lcm(long long a,long long b){ return a/gcd(a,b)*b;}


const long double pi=3.14159265359;

const ll inf =1000000007;

void asolve(){
    string s;
    cin >> s;

    ll n=s.size();
    ll t=s[n-1]-'0';
    if(s[n-1]-'0'==3){
        cout <<"bon" << endl;
    }
    else if (t==0 || t==1 ||t==6 || t==8){
        cout << "pon" << endl;
    }
    else {
        cout << "hon" << endl;
    }


}

void bsolve(){
    ll k;
    string s;
    cin >> k >> s;
    if(s.size()>k){
        string t="";
        for(ll i=0;i<k;i++) t+=s[i];
        t+="...";
        cout << t << endl;
    }
    else {
        cout << s << endl;
    }

}

void csolve() {
    long double a, b, h, m;
    cin >> a >> b >> h >> m;
    long double t, l;
    t = (5.500000000000 * (60 * h + m)) ;
    while(t>=360){
        t-=360;
    }
    l = min(t, 360 - t);
    l = l*2*pi/360;
    long double c=cos(l);
    long double ans1 = a*a+b*b-2*a*b*c;

    double ans;
    ans=sqrt(ans1);
    printf("%.12f\n",ans);
}


typedef vector<ll> vl;
typedef vector<pair<ll,ll>> vp;
typedef pair<ll,ll> Pair;

#define ALL(x) (x).begin(), (x).end()
#define inputv(v,n) rep(i,n){\
ll x;\
cin>>x;\
v.push_back(x);\
}

const ll INF=99999999999999;
const ll MOD=1000000007;

using Edge = pair<ll,ll>;  //　1つ目は結んでいるノード、2つ目はその辺の重みを指す
using Graph = vector<vector<Edge> >;  //隣接リスト

const ll max_A=100007;
ll kita[max_A];

void dijkstra(const Graph &G, vl &dist, ll s,ll n){  // sを始点とする最短経路
    priority_queue<Pair, vector<Pair>, greater<Pair> > que; //secondが頂点、firstがその頂点への暫定最小コストを表す
    dist[s] = 0;  //sへの距離は0

    que.emplace(0, s);

    while(!que.empty()){
        Pair p = que.top(); //キューから辺を取り出す
        que.pop(); //取り出した辺は破棄
        ll v = p.second;
        if(dist[v] < p.first) continue; //辺の行き先の距離が辺のコスト未満なら、そのまま
        for(auto e : G[v]){  //頂点vから出る各辺について
            if(dist[e.first] > dist[v] + e.second){  //辺Eを通るとコストが改善される場合
                dist[e.first] = dist[v] + e.second;  //更新
                kita[e.first]=v;
                que.emplace(Pair(dist[e.first], e.first));  //キューにその頂点を格納
            }
        }
    }
}


void dsolve(){
    ll n,m;
    cin >> n>> m;
    Graph g(n);
    vl dist(n,INF);
    rep(i,max_A) kita[i]=inf;
    rep(i,m){
        ll a,b,c;
        c=1;
        cin >> a >> b ;
        g[a-1].push_back(Edge(b-1,c));
        g[b-1].push_back(Edge(a-1,c));
    }
    dijkstra(g,dist,0,n);
    map<ll,ll> mp;
    bool can=true;
    for(ll i=1;i<n;i++){
        if(kita[i]==inf){
            can=false;
            break;
        }
        else{
            mp[i]=kita[i];
        }
    }
    if(can){
        cout <<"Yes" << endl;
        for(ll i=1;i<n;i++){
            cout << mp[i]+1 << endl;
        }
    }
    else {
        cout <<"No" << endl;
    }
}

int main(){
    dsolve();
}

Measured memory_bytes: 23412