# BZOJ4025 二分图（线段树分治+并查集）

#include<iostream>
#include<cstdio>
#include<cmath>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#include<vector>
#include<stack>
using namespace std;
{
int x=0,f=1;char c=getchar();
while (c<'0'||c>'9') {if (c=='-') f=-1;c=getchar();}
while (c>='0'&&c<='9') x=(x<<1)+(x<<3)+(c^48),c=getchar();
return x*f;
}
#define N 100010
int n,m,T,L[N<<2],R[N<<2],fa[N],deep[N],dis[N],v[N];
struct edge{int x,y;};
struct data{int x,fa,deep,v;};
vector<edge> tree[N<<2];
stack<data> undo[N<<2];
bool ans[N];
void build(int k,int l,int r)
{
L[k]=l,R[k]=r;
if (l==r) return;
int mid=l+r>>1;
build(k<<1,l,mid);
build(k<<1|1,mid+1,r);
}
void add(int k,int l,int r,edge e)
{
if (L[k]==l&&R[k]==r) {tree[k].push_back(e);return;}
int mid=L[k]+R[k]>>1;
}
int find(int x)
{
if (fa[x]==x) return x;
int p=find(fa[x]);
dis[x]=dis[fa[x]]^v[x];
return p;
}
void merge(int k,int x,int y,int p)
{
if (deep[x]<deep[y]) swap(x,y);
data a;
a.x=y;a.fa=x;a.deep=deep[x];a.v=v[y];
undo[k].push(a);
fa[y]=x;v[y]=p;dis[y]=dis[x]^p;
if (deep[y]==deep[x]) deep[x]++;
}
void solve(int k)
{
int s=tree[k].size();
bool flag=0;
for (int i=0;i<s;i++)
{
if (tree[k][i].x==tree[k][i].y) {flag=1;break;}
int p=find(tree[k][i].x),q=find(tree[k][i].y);
if (p!=q) merge(k,p,q,dis[tree[k][i].x]^dis[tree[k][i].y]^1);
else if (dis[tree[k][i].x]^dis[tree[k][i].y]^1) {flag=1;break;}
}
if (L[k]<R[k]&&!flag) solve(k<<1),solve(k<<1|1);
else if (flag) for (int i=L[k];i<=R[k];i++) ans[i]=1;
while (!undo[k].empty())
{
data a=undo[k].top();
fa[a.x]=a.x;
deep[a.fa]=a.deep;
dis[a.x]=v[a.x]=a.v;
undo[k].pop();
}
}
int main()
{
freopen("bzoj4025.in","r",stdin);
freopen("bzoj4025.out","w",stdout);
build(1,1,T);
for (int i=1;i<=m;i++)
{
}