#include <stdio.h>

long ludzi,rozkazow, rozkazy[1001][3], got, pocz;
long Odp[41];
char tab[40];



int SPROBUJ(long nr_rozk)
{
if (nr_rozk==0) { Odp[got]++; return 0; }

// Sprawdzam, czy ten rozkaz "coś zrobi".
if (  ( tab[rozkazy[nr_rozk][1]] == 1 )  &&  ( tab[rozkazy[nr_rozk][2]] == 0 )  )
	{
	 // Tzn. że ten rozkaz blokuje - nic się nie da zrobić.
	 return 0;
	}
// W każdym innym przypadku ten rozstaw przechodzi dalej.
SPROBUJ(nr_rozk-1);

// Ale jeśli jest dokładnie na odwrót, to powstaje rozwidlenie:
if (  ( tab[rozkazy[nr_rozk][1]] == 0 )  &&  ( tab[rozkazy[nr_rozk][2]] == 1 )  )
	{
	 tab[rozkazy[nr_rozk][1]] = 1;   tab[rozkazy[nr_rozk][2]] = 0;
	 SPROBUJ(nr_rozk-1);
	 tab[rozkazy[nr_rozk][1]] = 0;   tab[rozkazy[nr_rozk][2]] = 1;
	}

return 0;
}




int main()
{
scanf("%ld",&ludzi);
scanf("%ld",&rozkazow);
for (int ii=1; ii<=rozkazow; ii++)
	{
	 scanf("%ld %ld",&rozkazy[ii][1],&rozkazy[ii][2]);
	}

for (int ii=1; ii<=40; ii++) Odp[ii]=0;
Odp[1]=ludzi;
Odp[ludzi]=1;

// A dla liczby Gotowych od 2 do ludzi-1 trzeba to dopiero policzyć...
for (got=2; got<ludzi; got++)
	{
	 // Spróbuję rekurencyjnie...
	 // Najpierw muszę każdą z opcji "końcowego stanu" ustawić
	 for (pocz=1; pocz <= ludzi-got+1; pocz++)
	 	{
		 for (int ii=1; ii<=ludzi; ii++) tab[ii]=0;
		 for (int ii=pocz; ii<=pocz+got-1; ii++) tab[ii]=1;
		 
		 // Tu mam gotowy rozstaw początkowy, teraz muszę sprawdzić kolejne rozkazy
		 SPROBUJ(rozkazow);
		 
	 	}
	}


//for (int ii=1; ii<=ludzi; ii++) printf("%ld ",Odp[ii]);
//printf("\n");

for (int ii=1; ii<=ludzi; ii++)
	{
	 if (Odp[ii]%2==0) printf("0 ");
	 else printf("1 ");
	}




return 0;
}




