#include <bits/stdc++.h>
using namespace std;
const int N = 5e5+100;
int f[N],tot,root;
struct vectorr
{
signed *p;
signed siz,maxsiz;
vectorr()
{
maxsiz=0;
}
inline void nnew()
{
signed *p1=p;
maxsiz*=1.1;
maxsiz++;
p=new signed[maxsiz];
memcpy(p,p1,siz<<2);
delete p1;
}
inline void push_back(signed x)
{
if(siz>=maxsiz-1)
{
nnew();
}
p[siz++]=x;
}
inline signed& operator[](signed x)
{
if(x>=siz)return siz;
return p[x];
}
inline signed* begin()
{
return p;
}
inline signed* end()
{
return p+siz;
}
inline void era()
{
if(siz==0)return;
siz--;
}
void ok()
{
signed *p1=p;
maxsiz=siz;
p=new signed[maxsiz];
memcpy(p,p1,siz<<2);
delete p1;
}
};
vectorr a[(int)1e5+100];
vectorr tmp;
int tr[N][2];
#define ll (tr[x][0])
#define rr (tr[x][1])
#define mid ((l+r)>>1)
inline void build(int l,int r,int x)
{
if(l==r)
{
ll=rr=l;
return;
}
ll=++tot;
rr=++tot;
build(l,mid,ll);
build(mid+1,r,rr);
}
int l1,r1,lss;
void add(int l,int r,int x)
{
if(l>=l1&&r<=r1)
{
a[lss].push_back(x);
return;
}
if(l1<=mid)add(l,mid,ll);
if(r1>mid)add(mid+1,r,rr);
}
#undef mid
int find(int x)
{
if(f[x]!=x)return f[x]=find(f[x]);
return f[x];
}
void dfs(int x)
{
if(x<root)
{
for(auto i:a[x])
{
if(find(i)==find(x))continue;
f[find(i)]=find(x);
dfs(i);
}
}
else
{
if(find(tr[x][0])!=find(x))
{
f[find(tr[x][0])]=find(x);
dfs(tr[x][0]);
}
if(find(tr[x][1])!=find(x))
{
f[find(tr[x][1])]=find(x);
dfs(tr[x][1]);
}
}
}
vectorr v;
signed main()
{
int n,m,x,y;
cin>>n>>m;
root=tot=n+1;
build(1,n,root);
for(int i=1;i<=tot;i++)f[i]=i;
vectorr *b=new vectorr[(int)1e5+100];
for(int i=1;i<=m;i++)
{
cin>>x>>y;
b[x].push_back(y);
b[y].push_back(x);
}
for(int i=1;i<=n;i++)sort(b[i].begin(),b[i].end());
int ls=1;
for(int i=1;i<=n;i++)
{
ls=1;
for(auto j:b[i])
{
if(ls<j)
{
l1=ls,r1=j-1,lss=i;
add(1,n,root);
}
ls=j+1;
}
}
delete b;
for(int i=1;i<=n;i++)
{
if(f[i]==i)
{
dfs(i);
}
}
int cnt[(int)1e5+100];
for(int i=1;i<=n;i++)
{
cnt[find(i)]++;
}
for(int i=1;i<=n;i++)
{
if(cnt[i])v.push_back(cnt[i]);
}
cout<<v.siz<<'\n';
sort(v.begin(),v.end());
for(auto i:v)cout<<i<<' ';
}