#include <bits/stdc++.h>
using namespace std;
vector<string> split(const string &s, char c) {
  vector<string> v;
  stringstream second(s);
  string x;
  while (getline(second, x, c)) v.emplace_back(x);
  return move(v);
}
void err(vector<string>::iterator it) {}
template <typename T, typename... Args>
void err(vector<string>::iterator it, T a, Args... args) {
  cout << it->substr((*it)[0] == ' ', it->length()) << " = " << a << ", ";
  err(++it, args...);
}
int ini() {
  int x;
  scanf("%d", &x);
  return x;
}
long long inl() {
  long long x;
  scanf("%lld", &x);
  return x;
}
double ind() {
  double x;
  scanf("%lf", &x);
  return x;
}
int set_1(int n, int pos) { return n = (n | (1 << pos)); }
int reset_0(int n, int pos) { return n = n & ~(1 << pos); }
bool check_bit(int n, int pos) { return n = n & (1 << pos); }
int dx[8] = {1, 0, -1, 0, -1, -1, 1, 1};
int dy[8] = {0, 1, 0, -1, -1, 1, -1, 1};
const int N = (int)2e5 + 5;
const int M = (int)1e9 + 7;
const double pi = 2 * acos(0.0);
const double eps = 1e-9;
std::set<int> contain[N];
bool vis[N];
set<int> unused;
int c;
void dfs(int u) {
  unused.erase(u);
  vis[u] = true;
  set<int>::iterator it = unused.begin();
  c++;
  std::vector<int> v;
  while (it != unused.end()) {
    if (contain[u].count(*it) == 0) {
      v.push_back(*it);
    }
    ++it;
  }
  for (auto x : v) {
    unused.erase(x);
  }
  for (auto x : v) {
    dfs(x);
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  int t = 1, te = 0;
  while (t--) {
    int n, m;
    cin >> n >> m;
    for (int i = 1; i <= m; i++) {
      int u, v;
      cin >> u >> v;
      contain[u].insert(v);
      contain[v].insert(u);
    }
    for (int i = 1; i <= n; i++) {
      unused.insert(i);
    }
    vector<int> v;
    for (int i = 1; i <= n; i++) {
      if (!vis[i]) {
        c = 0;
        dfs(i);
        v.push_back(c);
      }
    }
    cout << v.size() << '\n';
    ;
    sort(v.begin(), v.end());
    for (auto x : v) {
      cout << x << " ";
    }
  }
  return 0;
}
