#include <bits/stdc++.h>
using namespace std;
const int maxn = 1e6 + 5;
vector<int> g[maxn], grp[maxn];
int visit[maxn], degree[maxn], vdegree[maxn];
set<int> s1, c, nc;
map<pair<int, int>, int> m1;
vector<int> ans;
int gnum;
void dfs(int node) {
  visit[node] = 1;
  for (int i = 0; i <= (int)g[node].size() - 1; i++) {
    if (visit[g[node][i]]) continue;
    dfs(g[node][i]);
  }
}
void dfs1(int node) {
  visit[node] = 1;
  grp[gnum].push_back(node);
  for (auto it = c.begin(); it != c.end(); ++it) {
    if (visit[*it]) continue;
    if (!m1[{node, *it}]) dfs1(*it);
  }
}
void solve() {
  int n, m;
  scanf("%d", &n);
  scanf("%d", &m);
  for (int i = 1; i <= m; i++) {
    int n1, n2;
    scanf("%d", &n1);
    scanf("%d", &n2);
    g[n1].push_back(n2);
    g[n2].push_back(n1);
    m1[{n1, n2}] = 1;
    m1[{n2, n1}] = 1;
    degree[n1]++;
    degree[n2]++;
  }
  dfs(1);
  for (int i = 1; i <= n; i++) {
    if (!visit[i]) {
      puts("1");
      printf("%d\n", n);
      return;
    }
  }
  int x = INT_MAX, element = -1;
  for (int i = 1; i <= n; i++) {
    if (x > degree[i]) {
      x = degree[i];
      element = i;
    }
  }
  s1.insert(element);
  for (int i = 0; i <= (int)g[element].size() - 1; i++) {
    s1.insert(g[element][i]);
  }
  cerr << "sz(s1)"
       << ": " << (int)s1.size() << endl;
  ;
  for (int i = 0; i <= (int)g[element].size() - 1; i++) {
    for (int j = 0; j <= (int)g[g[element][i]].size() - 1; j++) {
      if (s1.find(g[g[element][i]][j]) != s1.end()) {
        vdegree[g[element][i]]++;
      }
    }
  }
  int siz = n - (int)g[element].size() - 1, cnt = 0;
  for (int i = 0; i <= (int)g[element].size() - 1; i++) {
    if ((degree[g[element][i]] - vdegree[g[element][i]]) == siz) {
      c.insert(g[element][i]);
    } else {
      nc.insert(g[element][i]);
    }
  }
  memset(visit, 0, sizeof(visit));
  gnum = 1;
  for (auto it = c.begin(); it != c.end(); ++it) {
    if (visit[*it]) continue;
    dfs1(*it);
    gnum++;
  }
  memset(vdegree, 0, sizeof(vdegree));
  if ((int)nc.size()) {
    auto it = nc.begin();
    while (it != nc.end()) {
      for (auto it1 = c.begin(); it1 != c.end(); ++it1) {
        if (m1[{(*it), (*it1)}]) vdegree[*it1]++;
      }
      it++;
    }
  }
  for (int i = 1; i <= gnum - 1; i++) {
    int flag = 0;
    for (int j = 0; j <= (int)grp[i].size() - 1; j++) {
      if (vdegree[grp[i][j]] != (int)nc.size()) {
        flag = 1;
        break;
      }
    }
    if (!flag) {
      ans.push_back((int)grp[i].size());
      cnt += (int)grp[i].size();
    }
  }
  if (n - cnt) ans.push_back(n - cnt);
  printf("%d\n", (int)ans.size());
  sort((ans).begin(), (ans).end());
  for (int i = 0; i <= (int)ans.size() - 1; i++) {
    printf("%d ", ans[i]);
  }
  printf("\n");
}
int main() {
  int t = 1;
  while (t--) {
    solve();
  }
  return 0;
}
