![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
#include<bits/stdc++.h> using namespace std; //input by bxd #define rep(i,a,b) for(int i=(a);i<=(b);i++) #define repp(i,a,b) for(int i=(a);i>=(b);--i) #define RI(n) scanf("%d",&(n)) #define RII(n,m) scanf("%d%d",&n,&m) #define RIII(n,m,k) scanf("%d%d%d",&n,&m,&k) #define RS(s) scanf("%s",s); #define ll long long #define pb push_back #define REP(i,N) for(int i=0;i<(N);i++) #define CLR(A,v) memset(A,v,sizeof A) ////////////////////////////////// #define inf 0x3f3f3f3f const int N=1e7+5; const int M=1e8; int head[M],pos; struct Edge { int to,v,nex; }edge[M]; void add(int a,int b) { edge[++pos].nex=head[a]; head[a]=pos; edge[pos].to=b; } int sta[N],tot,vis[N],belong[N],cnt,dfn[N],low[N],ind; void init() { CLR(vis,0);CLR(dfn,0);CLR(low,0); tot=cnt=ind=0; } void tarjan(int u) { dfn[u]=low[u]=++tot; vis[u]=1; sta[++ind]=u; for(int i=head[u];i;i=edge[i].nex) { int v=edge[i].to; if(!dfn[v]) tarjan(v),low[u]=min(low[u],low[v]); else if(vis[v])low[u]=min(low[u],low[v]); } if(dfn[u]==low[u]) { cnt++;int v; do { v=sta[ind--]; vis[v]=0; belong[v]=cnt; } while(v!=u); } } int n,m; int main() { RII(n,m); rep(i,1,m) { int a,va,b,vb;RII(a,va);RII(b,vb); if (va && vb) { // a, b 都真,-a -> b, -b -> a add(a+n,b); add(b+n,a); } else if (!va && vb) { // a 假 b 真,a -> b, -b -> -a add(a,b); add(b+n,a+n); } else if (va && !vb) { // a 真 b 假,-a -> -b, b -> a add(a+n,b+n); add(b,a); } else if (!va && !vb) { // a, b 都假,a -> -b, b -> -a add(a,b+n); add(b,a+n); } } rep(i,1,2*n) if(!dfn[i])tarjan(i); rep(i,1,n) if(belong[i]==belong[i+n]) { cout<<"IMPOSSIBLE"<<endl; return 0; } cout<<"POSSIBLE"<<endl; rep(i,1,n) cout<< (belong[i]<belong[i+n])<<" "; cout<<endl; return 0; }