#include <cstdio>
#include <vector>
#include <set>
using namespace std;
#define S second
#define F first
#define NMAX 9000
pair < int , pair < int , int > > T[4*NMAX];
int Gi[NMAX],Ge[NMAX];
set < pair < int , int > > w;
vector < int > :: iterator u;
vector < int > G[2][NMAX];
int i,N,M,X,Y,left;
pair < bool , bool > marked[NMAX];
void Build(int node,int left,int right,int where,pair < int , pair < int , int > > e)
{
if (!(left<=where && where<=right))
return ;
if (left==where && where==right)
{
T[node]=e;
return ;
}
int mid=(left+right)>>1;
Build(2*node,left,mid,where,e);
Build(2*node+1,mid+1,right,where,e);
if (max(T[2*node].S.F,T[2*node].S.S)>max(T[2*node+1].S.F,T[2*node+1].S.S))
T[node]=T[2*node];
else T[node]=T[2*node+1];
}
void Update(int node,int left,int right,int where,bool flag)
{
if (!(left<=where && where<=right))
return ;
if (left==where && where==right)
{
(!flag) ? --T[node].S.F : --T[node].S.S;
return ;
}
int mid=(left+right)>>1;
Update(2*node,left,mid,where,flag);
Update(2*node+1,mid+1,right,where,flag);
if (max(T[2*node].S.F,T[2*node].S.S)>max(T[2*node+1].S.F,T[2*node+1].S.S))
T[node]=T[2*node];
else T[node]=T[2*node+1];
}
void Update_all(int node,int left,int right,int where,bool flag)
{
if (!(left<=where && where<=right))
return ;
if (left==where && where==right)
{
(!flag) ? T[node].S.F=0 : T[node].S.S=0;
return ;
}
int mid=(left+right)>>1;
Update(2*node,left,mid,where,flag);
Update(2*node+1,mid+1,right,where,flag);
if (max(T[2*node].S.F,T[2*node].S.S)>max(T[2*node+1].S.F,T[2*node+1].S.S))
T[node]=T[2*node];
else T[node]=T[2*node+1];
}
int main()
{
freopen("felinare.in","r",stdin);
freopen("felinare.out","w",stdout);
for (i=1,scanf("%d%d",&N,&M);i<=M;++i)
{
scanf("%d%d",&X,&Y);
++Ge[X];
++Gi[Y];
G[0][X].push_back(Y);
G[1][Y].push_back(X);
w.insert(make_pair(X,Y));
}
for (i=1;i<=N;++i)
{
marked[i]=make_pair(true,true);
Build(1,1,N,i,make_pair(i,make_pair(Ge[i],Gi[i])));
}
while (!w.empty())
{
if (T[1].S.F>=T[1].S.S)
{
for (u=G[0][T[1].F].begin();u!=G[0][T[1].F].end();++u)
{
if (w.find(make_pair(T[1].F,*u))!=w.end())
w.erase(w.find(make_pair(T[1].F,*u)));
Update(1,1,N,*u,true);
}
marked[T[1].F].F=false;
Update_all(1,1,N,T[1].F,false);
continue;
}
for (u=G[1][T[1].F].begin();u!=G[1][T[1].F].end();++u)
{
if (w.find(make_pair(*u,T[1].F))!=w.end())
w.erase(w.find(make_pair(*u,T[1].F)));
Update(1,1,N,*u,true);
}
marked[T[1].F].S=false;
Update_all(1,1,N,T[1].F,true);
}
for (i=1;i<=N;++i)
left+=(!marked[i].F+!marked[i].S);
for (i=1,printf("%d\n",2*N-left);i<=N;++i)
{
if (marked[i].F && marked[i].S)
printf("3\n");
if (!marked[i].F && marked[i].S)
printf("2\n");
if (marked[i].F && !marked[i].S)
printf("1\n");
if (!marked[i].F && !marked[i].S)
printf("0\n");
}
return 0;
}