2-SAT 板子。
const int N = 2e6 + 10;
int n, m;
struct edge
{
int to, nxt;
}e[N << 1];
int head[N], tot;
void add (int u, int v)
{
e[++tot] = (edge){v, head[u]}, head[u] = tot;
}
int dfn[N], low[N], cnt;
int col[N], colcnt;
int stk[N], top;
bool vis[N];
void Tarjan(int u)
{
dfn[u] = low[u] = ++cnt;
stk[++top] = u;
vis[u] = 1;
for (int i = head[u]; i; i = e[i].nxt)
{
int v = e[i].to;
if (!dfn[v])
{
Tarjan(v);
low[u] = min(low[u], low[v]);
}
else if (vis[v]) low[u] = min(low[u], dfn[v]);
}
if (dfn[u] == low[u])
{
colcnt++;
while(stk[top] != u)
{
col[stk[top]] = colcnt;
vis[stk[top]] = 0;
top --;
}
col[stk[top]] = colcnt;
vis[stk[top]] = 0;
top --;
}
}
int main()
{
scanf ("%d%d", &n, &m);
for (int i = 1; i <= m; i++)
{
int a, x, b, y;
scanf ("%d%d%d%d", &a, &x, &b, &y);
if (!x && !y) add(a, b + n), add(b, a + n);
if (!x && y) add(a, b), add(b + n, a + n);
if (x && !y) add(a + n, b + n), add(b, a);
if (x && y) add(a + n, b), add(b + n, a);
}
for (int i = 1; i <= 2 * n; i++)
if (!dfn[i]) Tarjan(i);
for (int i = 1; i <= n; i++)
if (col[i] == col[i + n])
{
puts("IMPOSSIBLE");
return 0;
}
puts("POSSIBLE");
for (int i = 1; i <= n; i++)
printf ("%d ", col[i] < col[i + n]);
return 0;
}
EOF