#include <bits/stdc++.h>
using namespace std;
const int N = 300000 + 10;
struct Node {
  int x, y;
  Node(int x, int y) : x(x), y(y) {}
  bool operator<(const Node& rhs) const {
    return x < rhs.x || (x == rhs.x && y < rhs.y);
  }
};
int n, m, size[N], color[N], col = 1;
vector<int> G[N], grp[N];
map<int, int> toid;
map<vector<int>, int> id;
map<Node, int> check;
void dfs(int u) {
  color[u] = col++;
  for (int v : grp[u])
    if (!color[v]) dfs(v);
}
int main() {
  std::ios_base::sync_with_stdio(false);
  cin.tie(0);
  cin >> n >> m;
  for (int i = 0; i < n; i++) G[i].push_back(i);
  int x, y;
  for (int i = 0; i < m; i++) {
    cin >> x >> y;
    x--;
    y--;
    G[x].push_back(y);
    G[y].push_back(x);
  }
  m = 0;
  for (int i = 0; i < n; i++) {
    sort(G[i].begin(), G[i].end());
    if (id.count(G[i]))
      toid[i] = id[G[i]];
    else {
      id[G[i]] = m;
      toid[i] = m++;
    }
  }
  for (int i = 0; i < n; i++)
    for (int u : G[i])
      if (toid[i] != toid[u] && !check.count(Node(toid[i], toid[u]))) {
        grp[toid[i]].push_back(toid[u]);
        grp[toid[u]].push_back(toid[i]);
        check[Node(toid[i], toid[u])] = 1;
        check[Node(toid[u], toid[i])] = 1;
      }
  for (int i = 0; i < m; i++)
    if (grp[i].size() >= 3) {
      cout << "NO" << endl;
      return 0;
    }
  for (int i = 0; i < m; i++)
    if (!color[i] && ((grp[i].size() == 1) || grp[i].size() == 0)) {
      dfs(i);
      col++;
    }
  for (int i = 0; i < m; i++)
    if (!color[i]) {
      cout << "NO" << endl;
      return 0;
    }
  cout << "YES" << endl;
  for (int i = 0; i < n; i++) cout << color[toid[i]] << ' ';
  cout << endl;
  return 0;
}
