7 20
4 6
6 7
4 5
1 2
2 4
1 7
3 5
2 1
6 2
6 1
7 3
3 2
3 6
3 1
3 4
2 5
1 6
7 4
6 3
7 5
 8 23
1 2
1 4
1 6
1 8
2 3
2 4
2 5
2 6
2 7
2 8
3 4
3 5
3 6
3 7
3 8
4 5
4 6
4 7
5 6
5 7
5 8
6 8
7 8
 4 4
2 1
3 1
1 4
3 2
 8 18
1 4
1 6
1 7
2 3
2 4
2 5
2 6
2 7
2 8
3 4
3 8
4 7
5 6
5 7
5 8
6 7
6 8
7 8
 10 34
7 10
2 3
2 4
2 5
9 10
2 7
2 8
2 10
4 5
4 6
4 7
4 8
4 9
6 7
6 8
6 9
6 10
1 2
1 3
1 5
8 9
1 6
1 7
1 8
1 9
1 10
3 4
3 5
3 6
3 8
3 10
5 6
5 9
5 10
 5 7
1 2
2 3
3 4
1 5
2 5
3 5
4 5
 2 0
 8 23
2 7
7 5
8 6
8 2
6 3
3 5
8 1
8 4
8 3
3 4
1 2
2 6
5 2
6 4
7 6
6 5
7 8
7 1
5 4
3 7
1 4
3 1
3 2
 2 1
1 2
 6 9
1 2
1 4
1 5
2 3
2 5
2 6
3 5
4 6
5 6
 12 56
9 5
2 6
9 8
5 4
1 11
1 6
4 1
1 10
10 3
8 4
5 1
9 1
5 10
2 7
11 5
6 11
5 8
7 6
3 2
12 7
8 6
12 3
1 2
8 1
2 11
10 12
4 6
5 12
2 4
10 2
7 3
12 11
7 10
7 1
9 2
11 9
9 10
8 7
11 3
7 9
5 7
4 12
3 5
12 2
4 10
9 12
5 2
9 4
11 8
8 2
3 6
4 11
8 10
6 10
3 9
3 4
 12 58
1 2
1 3
1 4
1 5
1 6
1 7
1 8
1 10
1 11
1 12
2 3
2 4
2 5
2 6
2 7
2 8
2 9
2 10
2 11
2 12
3 4
3 5
3 6
3 7
3 8
3 9
3 10
3 11
3 12
4 5
4 6
4 8
4 11
4 12
5 6
5 7
5 8
5 9
5 10
5 11
6 7
6 8
6 9
6 10
6 11
6 12
7 8
7 9
7 10
7 11
7 12
8 9
8 10
8 11
9 10
9 11
9 12
10 12
 4 3
2 1
3 1
4 2
 3 1
2 3
 6 10
1 2
1 3
1 4
1 6
2 3
2 4
2 5
3 5
3 6
4 6
 11 49
10 3
6 4
11 3
7 6
10 6
6 1
4 3
10 2
4 5
9 2
10 1
5 7
1 5
9 7
2 11
8 6
3 9
2 5
9 5
6 5
1 4
11 9
1 7
8 10
3 6
3 7
11 5
6 9
4 10
8 7
4 9
8 2
4 2
8 11
7 4
9 10
8 1
10 7
3 2
5 8
8 9
1 3
2 7
10 11
5 3
10 5
4 11
1 11
8 3
 5 4
1 4
2 3
4 3
4 2
 4 3
1 2
3 1
4 3
 4 3
1 3
1 4
2 3
 10 36
7 8
7 9
2 3
2 4
2 5
9 10
2 7
2 8
2 9
2 10
4 5
4 6
4 7
4 8
4 10
6 7
6 9
6 10
1 2
1 3
1 4
8 9
1 5
8 10
1 7
1 8
1 9
1 10
3 4
3 6
3 7
3 9
5 6
5 7
5 9
5 10
 8 15
2 1
4 5
2 4
3 4
2 5
3 5
2 6
3 6
5 6
4 6
2 7
3 8
2 8
3 7
6 7

3
1 2 4 
 3
1 2 5 
 2
1 3 
 1
8 
 1
10 
 2
1 4 
 1
2 
 3
1 3 4 
 2
1 1 
 1
6 
 3
1 4 7 
 4
1 1 1 9 
 1
4 
 1
3 
 1
6 
 5
1 1 1 2 6 
 1
5 
 1
4 
 1
4 
 2
2 8 
 1
8 

#include <bits/stdc++.h>
using namespace std;
int degree[200001];
struct MNode {
  int x;
  int y;
  MNode() {}
  MNode(int a, int b) : x(a), y(b) {}
  bool operator==(MNode &b) const { return x == b.x && y == b.y; }
  bool operator<(MNode b) const { return x < b.x || (x == b.x && y < b.y); }
};
bool cmp1(MNode &a, MNode &b) {
  return (a.x < b.x || (a.x == b.x && a.y < b.y));
}
bool cmp2(const MNode &a, const MNode &b) {
  return (a.y < b.y || (a.y == b.y && a.x < b.x));
}
int n, m;
multiset<int> result;
set<MNode> M;
void star(int i, const set<int> &u, set<int> &ai, set<int> &mi) {
  ai = u;
  mi.clear();
  for (set<MNode>::iterator it = M.lower_bound(MNode(i, 0));
       it != M.upper_bound(MNode(i + 1, 0)); it++) {
    if (it->x == i && u.find(it->y) != u.end()) {
      mi.insert(it->y);
      ai.erase(it->y);
    }
  }
}
int CountM(const set<int> &u) {
  int c = 0;
  for (set<MNode>::iterator it = M.begin(); it != M.end(); it++) {
    if (u.find(it->x) != u.end() && u.find(it->y) != u.end()) c++;
  }
  c /= 2;
}
void UpdateDegree(const set<int> &u, int &dmin, int &dmax) {
  for (int i = 1; i <= n; i++) degree[i] = (i - 1);
  for (set<MNode>::iterator it = M.begin(); it != M.end(); it++) {
    if (u.find(it->x) != u.end()) degree[it->x]--;
  }
  dmin = 0x7fffffff;
  dmax = 0;
  for (int i = 1; i <= n; i++) {
    if (degree[i] < dmin) dmin = degree[i];
    if (degree[i] > dmax) dmax = degree[i];
  }
}
void UpdateMNode(const set<int> &u) {
  for (set<MNode>::iterator it = M.begin(); it != M.end();) {
    if (u.find(it->x) == u.end() || u.find(it->y) == u.end())
      M.erase(it++);
    else
      it++;
  }
}
int parent[200001], coun[200001];
void InitUF() {
  for (int i = 1; i <= n; i++) {
    parent[i] = i;
    coun[i] = 1;
  }
}
int Find(int x) { return (parent[x] == x) ? x : (parent[x] = Find(parent[x])); }
void Union(int x, int y) {
  int i = Find(x);
  int j = Find(y);
  if (i != j) {
    if (coun[i] < coun[j]) {
      parent[i] = j;
      coun[j] += coun[i];
    } else {
      parent[j] = i;
      coun[i] += coun[j];
    }
  }
}
void DSU(set<int> &u) {
  int a[700][700];
  int i, j, ii[700];
  map<int, int> mp;
  i = 1;
  for (set<int>::iterator it = u.begin(); it != u.end(); it++) {
    mp.insert(pair<int, int>(*it, i));
    ii[i++] = *it;
  }
  memset(a, 0, sizeof(a));
  for (set<MNode>::iterator it = M.begin(); it != M.end(); it++) {
    if (it->x < it->y && u.find(it->x) != u.end() && u.find(it->y) != u.end()) {
      map<int, int>::iterator itm;
      i = mp.find(it->x)->second;
      j = mp.find(it->y)->second;
      a[i][j] = a[j][i] = 1;
    }
  }
  InitUF();
  for (int i = 1; i <= u.size(); i++) {
    int x = ii[i];
    for (int j = i + 1; j <= u.size(); j++) {
      int y = ii[j];
      if (a[i][j] == 0) Union(x, y);
    }
  }
  for (set<int>::iterator it = u.begin(); it != u.end(); it++)
    if (parent[*it] == *it) result.insert(coun[*it]);
}
int main() {
  int a, b;
  set<int> u, s, t, r, tmp;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < m; i++) {
    scanf("%d%d", &a, &b);
    if (a != b) {
      M.insert(MNode(a, b));
      M.insert(MNode(b, a));
    }
  }
  m = M.size() / 2;
  int dmin, dmax;
  for (int i = 1; i <= n; i++) u.insert(i);
  do {
    UpdateMNode(u);
    UpdateDegree(u, dmin, dmax);
    if (u.size() < 700) {
      DSU(u);
      break;
    }
    set<int>::iterator it, it0 = u.begin();
    for (it = u.begin(); it != u.end(); it++) {
      if (degree[*it] > degree[*it0]) it0 = it;
    }
    star(*it0, u, s, r);
    bool update;
    do {
      update = false;
      for (set<int>::iterator it = r.begin(); it != r.end(); it++) {
        set<int> r1;
        star(*it, u, t, r1);
        if (s.find(*it) != s.end())
          set_union(s.begin(), s.end(), t.begin(), t.end(),
                    inserter(s, s.begin()));
        else {
          tmp.clear();
          set_intersection(s.begin(), s.end(), t.begin(), t.end(),
                           inserter(tmp, tmp.begin()));
          if (!tmp.empty()) {
            update = true;
            set_union(s.begin(), s.end(), t.begin(), t.end(),
                      inserter(s, s.begin()));
          }
        }
      }
      if (update) {
        r.clear();
        set_difference(u.begin(), u.end(), s.begin(), s.end(),
                       inserter(r, r.begin()));
      }
    } while (update);
    result.insert(s.size());
    if (r.empty()) break;
    u = r;
  } while (1);
  printf("%d\n", result.size());
  for (multiset<int>::iterator it = result.begin(); it != result.end(); it++)
    printf("%d ", *it);
  printf("\n");
  return 0;
}
