// C++(Clang 10.0.0)

//GCC用 ナゾです
//#pragma GCC target("avx")
//#pragma GCC optimize("O3")
//#pragma GCC optimize("unroll-loops")

#include <iostream>
#include <stdio.h>
#include <stdlib.h> //rand() 0~RAND_MAX2147483647
#include <math.h>
#include <time.h>   //srand((unsigned int)time(NULL));
#include <unistd.h> //sleep
#include <algorithm>
#include <cmath>
#include <vector>
#include <regex> //正規表現
#include <map>
#include <unordered_map>
#include <set>
#include <cassert> //assert(x>=0) -> x<0の時異常終了
#include <numeric>
#include <iterator>
#include <list>
#include <tuple>
#include <queue>

using namespace std;
#define ll long long int
#define FOR(i,min,max) for(ll i=(min);i<(max);i++)
#define FOReq(i,min,max) for(ll i=(min);i<=(max);i++)
#define FORREV(i,max,min) for(ll i=(max)-1;i>=(min);i--)
#define FORREVeq(i,max,min) for(ll i=(max);i>=(min);i--)

#define all(vec) (vec).begin(),(vec).end()

const int MOD=1e9+7;
const int MOD2=998244353;
const int not0=1;
const int INF=2000000001;
const ll INFll=2e18;
//const int MAX_V=10000;
const double  Micro=1e-5;

int UnUsedVariable(){
    if(INF || Micro || MOD || INFll || MOD2 || not0){;}
    return 0;
}

#define inarray(array,min,max) FOR(i,min,max){cin>>array[i];}
#define inarrayW(arrayA,arrayB,min,max) FOR(i,min,max){cin>>arrayA[i]>>arrayB[i];}
//#define br printf("\n");
#define br cout<<"\n";
#define OutputAndReturn0(x) {cout<<(x)<<endl;return 0;}
#define elif else if

#define issame(a,b,c,d) ((a)==(b) and (b)==(c) and (c)==(d))
#define isdiff3(a,b,c) ((a)!=(b) and (b)!=(c) and (c)!=(a))
#define isdiff4(a,b,c,d) ((a)!=(b) and (b)!=(c) and (c)!=(a) and (d)!=(a) and (d)!=(b) and (d)!=(c))
#define isdiff5(a,b,c,d,e) ((a)!=(b) and (b)!=(c) and (c)!=(a) and (d)!=(a) and (d)!=(b) and (d)!=(c) and (e)!=(a) and (e)!=(b) and (e)!=(c) and (e)!=(d))
#define Func3(f,a,b,c) (f)((f)((a),(b)),(c))
#define Func4(f,a,b,c,d) (f)((f)((f)((a),(b)),(c)),(d))

inline int isEven(int x){return x%2==0;}
inline int isOdd (int x){return x%2==1;}
inline ll samepair(ll x){return x*(x-1)/2;}
inline void printD(double d){printf("%15.15lf ",d);}
inline ll  gcd(ll a,ll b){ if(b==0)return a;else return gcd(b,a%b);}//最大公約数 なお一方が0なら答えは他方になるので番兵は０で良い また、負の数もOK -4%3=-1となるため
inline ll  lcm(ll a,ll b){return a*b/gcd(a,b);}//MODやオーバーフローには注意！
//inline ll  ceil(double a){return (ll)a+1;}
//ans = accumulate(A, A+N, 0, [](int a, int b) {return gcd(a,b);});
//auto count = std::count_if(v.begin(), v.end(), [](int x) { return x == 1 || x == 3; } );

ll dx[4]={1,0,-1,0};
ll dy[4]={0,1,0,-1};

//番兵　累積和　しゃくとり法　木構造　DP キュー　乱択アルゴリズム　嘘解法　ハッシュ　next_permulation

//課題：DP 木構造　Xor

//多い失敗：小数点以下表示しきれてない　オーバーフロー　そもそも嘘解法 

//Nが10^6 → O(N)かO(N log N)
//Nが10^5 → O(N log N)かO(N log2 N)
//Nが3000 → O(N^2)
//Nが300 → O(N^3)(シンプルな処理)
//Nが100 → O(N^3)
//Nが50 → O(N^4)
//Nが20 → O(2^N)かO(N * 2^N)


ll probA(){
    ll ans;ans=0;
    ll N;N=0;
    cin>>N;
    
    ll one=N%10;
    
    if(one==3){OutputAndReturn0("bon");}
    else if (one==0 or one==1 or one==6 or one==8){OutputAndReturn0("pon");}
    else OutputAndReturn0("hon")
    
    
    OutputAndReturn0(ans);
    return 0;
}


ll probB(){
    string ans;
    ll K;
    string S;
    cin>>K>>S;
    
    cout<<S.substr(0,K);
    
    if(K<S.length())cout<<"...";
    
    br;
    
    
    
    
    //OutputAndReturn0(ans);
    return 0;
}




ll probC(){
    double ans;ans=0;
    double hourM,miniM,H,M;
    cin>>hourM>>miniM>>H>>M;
    const double pi=3.14159265358979323846;
    
    double hx,hy,mx,my;
    
    mx=miniM*cos(2*pi*M/60);
    my=miniM*sin(2*pi*M/60);
    
    double nowmin=60*H+M;
    double totalmin=60*12;
    
    hx=hourM*cos(2*pi*nowmin/totalmin);
    hy=hourM*sin(2*pi*nowmin/totalmin);
    
    ans=sqrt(  pow((hx-mx),2) + pow( (hy-my),2)  );
    
    printf("%15.15lf \n",ans);
    //OutputAndReturn0(ans);
    return 0;
}

ll probD(){
    ll ans;ans=0;
    ll N;N=0;
    cin>>N;
    
    ll A[N],B[N];
    
    inarrayW(A, B, 0, N);
    
    double ratio[N];
    
    
    
    const ll Ais0=pow(10,18)+100;
    const ll Bis0=pow(10,18)+150;
    const ll ABis0=pow(10,18)+200;
    
    FOR(i, 0, N){
        if(A[i]==0){
            if(B[i]==0){ratio[i]=ABis0;}
            else{ratio[i]=Ais0;}
        }
        else if(B[i]==0){ratio[i]=Bis0;}
        else ratio[i]=A[i]/B[i];
        
    }
    
    
    
    
    OutputAndReturn0(ans);
    return 0;
}



ll probE(){
    ll ans;ans=0;
    ll N,M;
    cin>>N>>M;
    
    vector<vector<ll>> Graph(N+1);
    
    
    for (ll i = 0; i < M; ++i) {
        ll a, b;
        cin >> a >> b;
        Graph[b].push_back(a); // 逆向きに辺を張る
        Graph[a].push_back(b);
    }
    
    cout<<"Yes"<<endl;
    
    deque<ll> dq;
    
    dq.push_back(1);
    
    ll arrived[N+1];
    FOR(i, 0, N+1){arrived[i]=-1;}
    arrived[0]=0;arrived[1]=0;
    
    while (!dq.empty()) {
        ll now;
        now=dq.front();
        dq.pop_front();
        for(auto& e:Graph[now]){
            if(arrived[e]==-1){
                arrived[e]=now;
                dq.push_back(e);
            }
        }
    }
    
    
    
    FOR(i, 2, N+1){
        cout<<arrived[i]<<endl;
    }
    
    
    
    
    
    //OutputAndReturn0(ans);
    return 0;
}


ll probF(){
    ll ans;ans=0;
    ll N;N=0;
    cin>>N;
    OutputAndReturn0(ans);
    return 0;
}




signed main(){
    //cin.tie(0);    //cinとcoutの結び付き解除（cout時にcinの内容を吐き出さなくなる）
    //ios::sync_with_stdio(false);  //coutとprintfの結び付き解除（coutとprintfを同時に使うな！）
    probE();
    //cout<<(ll)pow(10,18)+10 ;
    return 0;
}


Measured memory_bytes: 12560