#include<cstdio>
#include<algorithm>
using namespace std;
inline int read()
{
int s=0,w=1;
char ch=getchar();
while(ch<'0'||ch>'9'){if(ch=='-')w=-1;ch=getchar();}
while(ch>='0'&&ch<='9')s=s*10+(ch-'0'),ch=getchar();
return s*w;
}
inline void output(int x)
{
if(x>9) output(x/10);
putchar(x%10^48);
return;
}
const int MAXN=2e6+20;
int n,m;
struct E{int to,nxt;};
E edge[MAXN<<1];
int head[MAXN],tot;
int dfn[MAXN],low[MAXN],t;
int stack[MAXN],len;
int belong[MAXN],cnt;
bool instack[MAXN];
inline void add_edge(int u,int v)
{
edge[++tot].nxt=head[u];
head[u]=tot;
edge[tot].to=v;
return;
}
inline void dfs(int p)
{
dfn[p]=low[p]=++t;
stack[++len]=p;
instack[p]=true;
for(register int i=head[p];i;i=edge[i].nxt)
{
int v=edge[i].to;
if(!dfn[v]) dfs(v),low[p]=min(low[p],low[v]);
else if(instack[v]) low[p]=min(low[p],dfn[v]);
}
if(low[p]==dfn[p])
{
belong[p]=++cnt;
while(stack[len]!=p)
{
int now=stack[len];
belong[now]=cnt;
instack[now]=false;
--len;
}
--len;
instack[p]=false;
}
return;
}
inline void tarjan()
{
for(register int i=1;i<=n<<1;i++) if(!dfn[i])
dfs(i);
return;
}
int main()
{
n=read(),m=read();
while(m--)
{
bool x,y;
int u,v;
u=read();
read()==1?x=true:x=false;
v=read();
read()==1?y=true:y=false;
if((!x)&&(!y)) add_edge(u,v+n),add_edge(v,u+n);
else if(x&&(!y)) add_edge(u+n,v+n),add_edge(u,v);
else if((!x)&&y) add_edge(u+n,v+n),add_edge(u,v);
else if(x&&y) add_edge(u+n,v),add_edge(u,v+n);
}
tarjan();
for(register int i=1;i<=n;i++)
if(belong[i]==belong[i+n])
{
puts("IMPOSSIBLE");
return 0;
}
puts("POSSIBLE");
for(register int i=1;i<=n;i++)
{
belong[i]>belong[i+n]?putchar('1'):putchar('0');
putchar(' ');
}
return 0;
}