一、LCA
struct LCAns {
struct edge {int to, nxt;} e[N << 1];
int head[N], eid;
inline void add_edge (int u, int v) {e[eid] = {v, head[u]}; head[u] = eid ++;}
int dp[N][26], d[N], lg[N];
int n, root;
inline void dfs (int u) {
for (int i = head[u]; ~i ; i = e[i].nxt) {
int v = e[i].to;
if (v == dp[u][0]) continue;
dp[v][0] = u; d[v] = d[u] + 1; dfs (v);
}
}
inline int LCA (int u, int v) {
if (d[u] < d[v]) swap (u, v);
for (int j = lg[d[u] - d[v]];j >= 0; -- j) {if (d[dp[u][j]] >= d[v]) u = dp[u][j];}
if (u == v) return u;
for (int j = lg[d[u]];j >= 0; -- j) {if (dp[u][j] != dp[v][j]) {u = dp[u][j], v = dp[v][j];}}
return dp[u][0];
}
inline void perf () {
memset (head, -1, sizeof head);
}
inline void pre () {
lg[0] = -1;
for (int i = 1;i <= n; ++ i) lg[i] = lg[i / 2] + 1;
d[root] = 1; dfs (root);
for (int j = 1; (1 << j) < n; ++ j) for (int i = 1;i <= n; ++ i) {
dp[i][j] = dp[dp[i][j - 1]][j - 1];
}
}
} tr;
二、哈希
template < class T, T base, int N >
struct Hash_table {
T mod[2] = {1610612741, 805306457};
T hashp[2][N], n, pw[2][N];
char s[N];
inline T query (T u, T l, T r) {
ll ans = (hashp[u][r] - hashp[u][l - 1] * 1ll * pw[u][r - l + 1] % mod[u] + mod[u]) % mod[u];
return ans;
}
inline T f (char c) {return (T) (c);}
inline void init () {
for (T i = 0;i < 2; ++ i) {
for (T j = 1;j <= n; ++ j) hashp[i][j] = (hashp[i][j - 1] * base * 1ll + f (s[j])) % mod[i];
pw[i][0] = 1;
for (T j = 1;j <= n; ++ j) pw[i][j] = pw[i][j - 1] * base % mod[i];
}
}
};
三、2-SAT
const int N = 2e6 + 5;
vector < int > G[N];
int n, m, dfn[N], low[N], isin[N], time_click, scc[N], cnt;
vector < int > sccs[N];
stack < int > stk;
inline void tarjan (int u) {
low[u] = dfn[u] = ++ time_click;
isin[u] = 1;
stk.push (u);
for (int v : G[u]) {
if (!dfn[v]) {tarjan (v), low[u] = min (low[u], low[v]);}
else {if (isin[v]) low[u] = min (low[u], dfn[v]);}
}
if (dfn[u] == low[u]) {
cnt ++;
while (true) {
int v = stk.top (); scc[v] = cnt, isin[v] = 0, stk.pop ();
if (u == v) break;
}
}
}
inline void add_edge (int u, int v) {
G[u].push_back (v);
}
bool Memory_Ends;
signed main () {
fprintf (stderr, "%.3lf MB\n", (&Memory_Begins - &Memory_Ends) / 1048576.0);
read (n), read (m);
for (int _ = 1;_ <= m; ++ _) {
int i, a, j, b;
read (i), read (a), read (j), read (b);
add_edge (i + (a ^ 1) * n, j + b * n);
add_edge (j + (b ^ 1) * n, i + a * n);
}
for (int i = 1;i <= 2 * n; ++ i) {
if (!dfn[i]) tarjan (i);
}
for (int i = 1;i <= n; ++ i) {
if (scc[i] == scc[i + n]) {
printf ("IMPOSSIBLE\n");
return 0;
}
}
printf ("POSSIBLE\n");
for (int i = 1;i <= n; ++ i) {
if (scc[i] > scc[i + n]) printf ("1 ");
else printf ("0 ");
}
printf ("\n");
fprintf (stderr, "%.3lf ms\n", 1e3 * clock () / CLOCKS_PER_SEC);
return 0;
}