#include <fstream>
#include <vector>
using namespace std;
ifstream cin("felinare.in");
ofstream cout("felinare.out");
const int lim=8191+5;
vector<int> vec[lim];
bool sl[lim],sr[lim];
int l[lim],r[lim];
bool ok[lim];
bool path(int nod)
{
if(ok[nod])
return false;
ok[nod]=true;
for(int x:vec[nod])
if(!r[x] or path(r[x]))
{
l[nod]=x;
r[x]=nod;
return true;
}
return false;
}
void df(int nod)
{
ok[nod]=true;
sl[nod]=false;
for(int x:vec[nod])
if(!ok[r[x]])
{
sr[x]=true;
df(r[x]);
}
}
int main()
{
int n,m,a,b;
cin>>n>>m;
for(int i=1;i<=m;++i)
{
cin>>a>>b;
vec[a].push_back(b);
}
bool modif;
int cuplaj=0;
do
{
for(int i=1;i<=n;++i)
ok[i]=false;
modif=false;
for(int i=1;i<=n;++i)
if(!l[i] and path(i))
{
modif=true;
++cuplaj;
}
}while(modif);
for(int i=1;i<=n;++i)
if(l[i])
{
sl[i]=true;
ok[i]=false;
}
for(int i=1;i<=n;++i)
if(!l[i]) df(i);
cout<<2*n-cuplaj<<'\n';
for(int i=1;i<=n;++i)
if(sl[i]==true and sr[i]==true) cout<<0<<'\n';
else if(sl[i]==false and sr[i]==true) cout<<1<<'\n';
else if(sl[i]==true and sr[i]==false) cout<<2<<'\n';
else cout<<3<<'\n';
return 0;
}