class LinkCutTree{
public:
class LCT_Splay{
public:
int val[maxn];
int fa[maxn], son[maxn][2], st[maxn], tot, totp;
bool rev[maxn];
inline void pushup(int x) {val[x] = val[son[x][0]] ^ val[son[x][1]] ^ a[x];}
inline void rever(int x) {
int tmp = son[x][0];
son[x][0] = son[x][1];
son[x][1] = tmp;
rev[x] ^= 1;
}
inline void pushdown(int x){
if(rev[x]){
rever(son[x][0]); rever(son[x][1]);
rev[x] = 0;
}
}
inline bool notroot(int x) {return (son[fa[x]][0] == x) || (son[fa[x]][1] == x);}
inline void rotate(int x){
int y = fa[x], z = fa[y]; bool zson = (son[z][0] ^ y), yson = (son[y][0] ^ x);
int bo = (son[x][!yson]);
if(notroot(y)) son[z][zson] = x;
son[x][!yson] = y; son[y][yson] = bo;
if(bo) fa[bo] = y;
fa[y] = x; fa[x] = z;
pushup(y);
}
inline void splay(int x){
int y = x, top = 0; st[++top] = y;
// cout << "ho" << endl;
while(notroot(y)) st[++top] = y = fa[y];
// cout << "ho bo" << endl;
while(top) pushdown(st[top--]);
// cout << "stttt" << endl;
while(notroot(x)){
y = fa[x], top = fa[y];
if(notroot(y)) rotate(((son[y][0]^x) ^ (son[top][0]^y)) ? x : y);
rotate(x);
}
pushup(x);
}
}LCT_Splay;
private:
inline void access(int x){
for(int y = 0; x; x = LCT_Splay.fa[y=x]){
LCT_Splay.splay(x);
LCT_Splay.son[x][1] = y;
LCT_Splay.pushup(x);
}
}
inline void changeroot(int x){
access(x); LCT_Splay.splay(x);
LCT_Splay.rever(x);
}
inline int findroot(int x){
access(x); LCT_Splay.splay(x);
while(LCT_Splay.son[x][0]) LCT_Splay.pushdown(x), x = LCT_Splay.son[x][0];
LCT_Splay.splay(x);
return x;
}
public:
inline void split(int x, int y){
changeroot(x);
access(y); LCT_Splay.splay(y);
}
inline void connect(int x, int y){
changeroot(x);
if(findroot(y) ^ x) LCT_Splay.fa[x] = y;
}
inline void disconnect(int x, int y){
changeroot(x);
if(findroot(y) == x && LCT_Splay.fa[y] == x && !LCT_Splay.son[y][0]){
LCT_Splay.fa[y] = LCT_Splay.son[x][1] = 0;
LCT_Splay.pushup(x);
}
}
inline int getval(int x){return LCT_Splay.val[x];}
inline void toroot(int x){LCT_Splay.splay(x);}
}LCT;