#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 2;
int siz[N], par[N];
void make_set(int x) {
  siz[x] = 1;
  par[x] = x;
}
int find_set(int x) {
  if (x == par[x]) return x;
  return par[x] = find_set(par[x]);
}
void union_sets(int x, int y) {
  x = find_set(x);
  y = find_set(y);
  if (x != y) {
    if (siz[x] > siz[y]) swap(x, y);
    siz[y] += siz[x];
    par[x] = y;
  }
}
int n, m;
bool vis[N];
vector<int> g[N];
void dfs(int x) {
  vis[find_set(x)] = 1;
  for (int i = 0, j = 1; j <= n; j = g[x][i++] + 1) {
    while (j < g[x][i]) {
      if (!vis[find_set(j)]) dfs(j);
      union_sets(x, find_set(j++));
    }
  }
}
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);
  cin >> n >> m;
  while (m--) {
    int x, y;
    cin >> x >> y;
    g[x].push_back(y);
    g[y].push_back(x);
  }
  vector<int> z, o;
  for (int i = 1; i <= n; make_set(i++)) {
    if (g[i].size() < (n + 1) >> 1)
      z.push_back(i);
    else
      o.push_back(i);
    sort(g[i].begin(), g[i].end());
    g[i].push_back(n + 1);
  }
  for (int i = 1; i < z.size(); ++i) union_sets(z[i], z[i - 1]);
  for (int &i : o)
    if (!vis[find_set(i)]) dfs(i);
  vector<int> ans;
  map<int, bool> done;
  for (int i = 1; i <= n; ++i) done[find_set(i)] = 1;
  cout << done.size() << '\n';
  for (auto &i : done) ans.push_back(siz[i.first]);
  sort(ans.begin(), ans.end());
  for (int &i : ans) cout << i << ' ';
  return 0;
}
