#include <bits/stdc++.h>
#pragma optimization_level 3
#pragma GCC optimize("Ofast,no-stack-protector,unroll-loops,fast-math,O3")
#pragma GCC target("avx,avx2,fma")
using namespace std;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
int a, k, nc = 0, isz = 0;
vector<unordered_set<int>> n, l;
vector<int> cmp, vrt;
void dfs(int v) {
  cmp[v] = nc;
  vrt.push_back(v);
  for (int i : l[v]) {
    if (cmp[i] == -1)
      dfs(i);
    else if (cmp[i] != nc) {
      assert(cmp[i] == 0);
      isz = 1;
    }
  }
}
int main() {
  cin.tie(0);
  cout.tie(0);
  cin.sync_with_stdio(0);
  cout.sync_with_stdio(0);
  ;
  cin >> a >> k;
  cmp = vector<int>(a, -1);
  l = vector<unordered_set<int>>(a, unordered_set<int>());
  n = vector<unordered_set<int>>(a, unordered_set<int>());
  for (int q = 0; q < k; q++) {
    int x, y;
    cin >> x >> y;
    x--, y--;
    n[x].insert(y);
    n[y].insert(x);
  }
  for (int q = 0; q < a; q++) {
    int sos = (a - 1) - n[q].size();
    if (sos > a / 2) cmp[q] = 0;
  }
  for (int q = 0; q < a; q++) {
    if (cmp[q] != -1) continue;
    for (int w = 0; w < a; w++) {
      if (w == q || n[q].count(w)) continue;
      l[q].insert(w);
    }
  }
  for (int q = 0; q < a; q++) {
    if (cmp[q] != -1) continue;
    nc = q + 1;
    vrt.clear();
    isz = 0;
    dfs(q);
    if (isz) {
      for (int i : vrt) cmp[i] = 0;
    }
  }
  map<int, int> mp;
  for (int i : cmp) mp[i]++;
  vector<int> u;
  for (pair<int, int> p : mp) u.push_back(p.second);
  sort(u.begin(), u.end());
  cout << u.size() << "\n";
  for (int i : u) cout << i << " ";
}
