#include using namespace std; using ll = long long; using ull = unsigned long long; #define rep(i,a,b) for (int i=a; i=b; i--) #define fore(i,a) for(auto &i:a) #define pb push_back #define _GLIBCXX_DEBUG #define All(a) (a).begin(), (a).end() #define YN(a) ((a) ? "Yes" : "No") template inline bool chmin(T& a, const T& b) {bool c=a>b; if(a>b) a=b; return c;} template inline bool chmax(T& a, const T& b) {bool c=a inline T gcd(T a,T b) {return (b==0)?a:gcd(b,a%b);} template inline T lcm(T a, T b) {return (a*b)/gcd(a,b);} const int inf = INT_MAX / 2; const ll infl = 1LL << 61; using vi = vector; using vvi = vector>; using vvvi = vector>>; using vll = vector; using vvll = vector>; using vvvll = vector>>; template void OUT(const T& x) { cout << x; } // ----- pair ----- template void OUT(const pair& p) { cout << "("; OUT(p.first); cout << ", "; OUT(p.second); cout << ")"; } // ----- vector ----- template void OUT(const vector& v) { cout << "[ "; for (const auto& x : v) { OUT(x); cout << " "; } cout << "]"; } // ----- set ----- template void OUT(const set& s) { cout << "{ "; for (const auto& x : s) { OUT(x); cout << " "; } cout << "}"; } // ----- map ----- template void OUT(const map& mp) { cout << "{ "; for (const auto& [k,v] : mp) { OUT(k); cout << ": "; OUT(v); cout << ", "; } cout << "}"; } // ----- queue ----- template void OUT(queue q) { cout << "< "; while (!q.empty()) { OUT(q.front()); cout << " "; q.pop(); } cout << ">"; } // ----- priority_queue ----- template void OUT(priority_queue pq) { cout << "< "; while (!pq.empty()) { OUT(pq.top()); cout << " "; pq.pop(); } cout << ">"; } // ----- stack ----- template void OUT(stack st) { cout << "< "; while (!st.empty()) { OUT(st.top()); cout << " "; st.pop(); } cout << ">"; } // ----- deque ----- template void OUT(const deque& dq) { cout << "[ "; for (const auto& x : dq) { OUT(x); cout << " "; } cout << "]"; } #define out(x) cerr << #x << ": ", OUT(x), cerr << '\n'; template // costの型 struct Graph { ///////////////辺の構造体↓///////////// struct Edge{ T c; int u,v; // u→vの辺 // 辺同士の比較は、c → u → vの順番に比較 bool operator<(const Edge &other) const { return tie(c,u,v) < tie(other.c, other.u, other.v); } }; /////////////メンバ変数↓/////////////// vector>> _nexts; // nexts[i] := i番目からの隣接リスト{コスト、行き先} vector _edges; // 辺リスト T _total_edge_cost; // 全ての辺のコストの合計 vector _deg_in; // 全ての頂点の入次数を保持 vector _deg_out; // 全ての頂点の出次数を保持 //////////コンストラクタ↓//////////// Graph(int n): _nexts(n), _total_edge_cost(0), _deg_in(n,0), _deg_out(n,0) {} //////////メンバ関数↓//////////////// //コスト1の辺u → vを追加する関数 void add_edge(int u, int v){ add_edge(T(1), u, v); } //コストcの辺u → vを追加する関数 void add_edge(T c, int u, int v){ _nexts[u].push_back({c, v}); _edges.push_back(Edge{c, u, v}); _total_edge_cost += c; _deg_out[u]++; _deg_in[v]++; } //頂点数を返す関数 int size_n() const { return _nexts.size(); } //辺の本数を返す関数 int size_e() const { return _edges.size(); } // 全ての辺のコストの合計を返す T total_edge_cost() const { return _total_edge_cost; } // 辺リストを返す関数 const vector& edges() const { return _edges; } // 隣接リストを返す関数 const vector>>& nexts() const { return _nexts; } // iから行ける場所の{コスト、行き先}の集合を返す関数 const vector>& nexts(int i) const { return _nexts[i]; } // 入次数配列を返す関数 const vector& deg_in() const { return _deg_in; } // 頂点iの入次数を返す関数 int deg_in(int i) const { return _deg_in[i]; } // 出次数配列を返す関数 const vector& deg_out() const { return _deg_out; } // 頂点iの出次数を返す関数 int deg_out(int i) const { return _deg_out[i]; } }; int main() { ios::sync_with_stdio(false); cin.tie(nullptr); int n,m; cin >> n >> m; Graph G(n); rep(i,0,m){ int u,v; cin >> u >> v; u--; v--; G.add_edge(u,v); G.add_edge(v,u); } vi col(n,-1); vi visited(n,0); queue q; col[0] = 1; visited[0] = 1; rep(i,0,G.deg_out(0)){ q.push(G.nexts(0)[i].second); visited[G.nexts(0)[i].second] = 1; } while(!q.empty()){ int cur = q.front(); q.pop(); vi used(5,0); rep(i,0,G.deg_out(cur)){ int nx = G.nexts(cur)[i].second; if(col[nx] != -1){ used[col[nx]] = 1; //out(col[nx]); } if(!visited[nx]){ q.push(nx); visited[nx] = 1; } } rep(i,1,5){ if(!used[i]){ col[cur] = i; break; } } } cout << "Yes" << endl; rep(i,0,n){ cout << col[i] << " "; } cout << endl; cout << fixed << setprecision(30); return 0; }