#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target("sse4")
#pragma GCC optimize("unroll-loops")
using namespace std;
int bit[200005], n, sz;
set<int> adj[200005];
void update(int p) {
  for (int i = p; i <= n; i += i & (-i)) bit[i]++;
}
int query(int p) {
  int s = 0;
  for (int i = p; i; i -= i & (-i)) s += bit[i];
  return s;
}
int range_query(int i, int j) { return query(j) - query(i - 1); }
void dfs(int u) {
  int low, mid, high, pre = 0;
  update(u);
  sz++;
  for (auto x : adj[u]) {
    while (1) {
      low = pre + 1, high = x - 1;
      while (low <= high) {
        mid = (low + high) >> 1;
        if (range_query(pre + 1, mid) == mid - pre)
          low = mid + 1;
        else
          high = mid - 1;
      }
      if (low < x)
        dfs(low);
      else
        break;
    }
    pre = x;
  }
}
int main() {
  std::ios::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  int m, i, u, v;
  vector<int> res;
  cin >> n >> m;
  while (m--) {
    cin >> u >> v;
    adj[u].insert(v);
    adj[v].insert(u);
  }
  for (i = 1; i <= n; i++) adj[i].insert(n + 1);
  for (i = 1; i <= n; i++)
    if (!range_query(i, i)) {
      sz = 0;
      dfs(i);
      res.push_back(sz);
    }
  cout << (int)res.size() << '\n';
  sort((res).begin(), (res).end());
  for (auto x : res) cout << x << " ";
  return 0;
}
