#include <bits/stdc++.h>
using namespace std;
const int MOD1 = 1e9 + 9;
const int MOD2 = 1e9 + 21;
const int A1 = 300017;
const int A2 = 300111;
const int MAX = 3e5 + 5;
const int v[2] = {A1, A2};
const int m[2] = {MOD1, MOD2};
int pa[2][MAX];
inline int add(int a, int b, int M) {
  a += b;
  if (a >= M) {
    a -= M;
  }
  return a;
}
inline int mult(int a, int b, int M) { return (1LL * a * b) % M; }
void prepare() {
  for (int i = int(0); i < int(2); i++) {
    pa[i][0] = 1;
    for (int j = int(1); j < int(MAX); j++) {
      pa[i][j] = mult(pa[i][j - 1], v[i], m[i]);
    }
  }
}
pair<int, int> ruben_hash(const vector<int> &s) {
  int n = s.size();
  int h[2];
  h[0] = h[1] = 0;
  for (int i = int(0); i < int(2); i++) {
    for (int j = int(0); j < int(n); j++) {
      h[i] = add(h[i], mult(s[j], pa[i][j], m[i]), m[i]);
    }
  }
  return make_pair(h[0], h[1]);
}
const int MIDDLE = (int)1e7;
int N, M;
vector<int> adj[MAX];
set<int> new_adj[MAX];
int pset[MAX], set_color[MAX];
pair<int, int> h[MAX];
int find_set(int i) { return pset[i] == i ? i : pset[i] = find_set(pset[i]); }
inline void union_sets(int i, int j) { pset[find_set(i)] = find_set(j); }
int main() {
  prepare();
  scanf("%d %d", &N, &M);
  for (int i = int(1); i < int(N + 1); i++) {
    adj[i].push_back(i);
  }
  for (int i = int(1); i < int(N + 1); i++) {
    pset[i] = i;
  }
  for (int i = int(0); i < int(M); i++) {
    int a, b;
    scanf("%d %d", &a, &b);
    adj[a].push_back(b);
    adj[b].push_back(a);
  }
  for (int i = int(1); i < int(N + 1); i++) {
    sort(adj[i].begin(), adj[i].end());
    h[i] = ruben_hash(adj[i]);
  }
  for (int i = int(1); i < int(N + 1); i++) {
    for (auto &each : adj[i]) {
      if (h[i] == h[each]) {
        union_sets(i, each);
      }
    }
  }
  set<int> sets;
  for (int i = int(1); i < int(N + 1); i++) {
    sets.insert(find_set(i));
  }
  for (int i = int(1); i < int(N + 1); i++) {
    for (auto &each : adj[i]) {
      if (find_set(i) != find_set(each)) {
        new_adj[find_set(i)].insert(find_set(each));
      }
    }
  }
  memset(set_color, -1, sizeof set_color);
  queue<int> q;
  q.push(*sets.begin());
  set_color[*sets.begin()] = MIDDLE;
  while (!q.empty()) {
    int cur = q.front();
    q.pop();
    set<int> to_use{set_color[cur] - 1, set_color[cur] + 1};
    for (auto &each : new_adj[cur]) {
      if (set_color[each] == -1) {
      } else if (abs(set_color[cur] - set_color[each]) > 1) {
        puts("NO");
        return 0;
      } else {
        if (to_use.count(set_color[each])) {
          to_use.erase(set_color[each]);
        } else {
          puts("NO");
          return 0;
        }
      }
    }
    for (auto &each : new_adj[cur]) {
      if (set_color[each] == -1) {
        if (to_use.empty()) {
          puts("NO");
          return 0;
        } else {
          set_color[each] = *to_use.begin();
          to_use.erase(to_use.begin());
        }
        q.push(each);
      }
    }
  }
  puts("YES");
  for (int i = int(1); i < int(N + 1); i++) {
    printf("%d ", set_color[find_set(i)]);
  }
  puts("");
  return 0;
}
