#include <bits/stdc++.h>
using namespace std;
const long long mod = 1e9 + 7;
long long read() {
  long long x = 0, f = 1;
  char ch = getchar();
  while (ch < '0' || ch > '9') {
    if (ch == '-') f = -1;
    ch = getchar();
  }
  while (ch >= '0' && ch <= '9') {
    x = x * 10 + ch - '0';
    ch = getchar();
  }
  return x * f;
}
void write(long long x) {
  if (x < 0) x = -x, putchar('-');
  if (x >= 10) write(x / 10);
  putchar(x % 10 + '0');
}
long long quickmod(long long x, long long y) {
  long long Ans = 1;
  while (y) {
    if (y & 1) Ans = (Ans * x) % mod;
    x = (x * x) % mod;
    y >>= 1;
  }
  return Ans;
}
struct st {
  long long v, e, id;
  st() {}
  st(long long A, long long B, long long C) { v = A, e = B, id = C; }
};
vector<st> G[200005];
long long fa[200005], siz[200005];
void makeSet(long long x) {
  for (long long i = 1; i <= x; i++) fa[i] = i, siz[i] = 1;
}
long long findSet(long long x) {
  if (x == fa[x]) return x;
  fa[x] = findSet(fa[x]);
  return fa[x];
}
long long tot = 0;
struct Edge {
  long long u, v, e;
} q[1000005];
bool cmp(Edge A, Edge B) { return A.e < B.e; }
long long vis[200005], vis2[200005];
vector<long long> V;
signed main() {
  long long n = read(), m = read();
  long long sum = 0;
  for (long long i = 1; i <= m; i++) {
    long long u = read(), v = read();
    long long e = 0;
    sum ^= e;
    G[u].push_back(st(v, e, i));
    G[v].push_back(st(u, e, i));
  }
  long long Ans = n;
  long long pl = 1;
  for (long long i = 1; i <= n; i++)
    if (G[i].size() < G[pl].size()) pl = i;
  makeSet(n);
  for (long long i = 0; i < (long long)G[pl].size(); i++) vis[G[pl][i].v] = 1;
  for (long long i = 1; i <= n; i++)
    if (vis[i] == 0)
      if (findSet(i) != findSet(pl))
        siz[findSet(pl)] += siz[findSet(i)], fa[findSet(i)] = findSet(pl),
                                             Ans--;
  for (long long i = 1; i <= n; i++) {
    if (vis[i]) {
      for (long long j = 0; j < (long long)G[i].size(); j++)
        vis2[G[i][j].v] = 1;
      for (long long j = 1; j <= n; j++) {
        if (vis2[j] == 0 && findSet(i) != findSet(j)) {
          siz[findSet(j)] += siz[findSet(i)];
          fa[findSet(i)] = findSet(j);
          Ans--;
        }
      }
      for (long long j = 0; j < (long long)G[i].size(); j++)
        vis2[G[i][j].v] = 0;
    }
  }
  memset(vis, 0, sizeof vis);
  printf("%lld\n", Ans);
  for (long long i = 1; i <= n; i++) {
    if (vis[findSet(i)] == 0) {
      vis[findSet(i)] = 1;
      V.push_back(siz[findSet(i)]);
    }
  }
  sort(V.begin(), V.end());
  for (long long i = 0; i < V.size(); i++) printf("%lld ", V[i]);
  return 0;
}
