import java.io.* ;
import java.util.* ;
public class FearOfTheDark
implements Runnable {
try {
while ( ! st.hasMoreTokens ( ) ) {
if ( s == null )
return null ;
}
return st.nextToken ( ) ;
return null ;
}
}
new Thread ( null ,
new FearOfTheDark
( ) ,
"Main" ,
1 << 28 ) .
run ( ) ; }
public void run( ) {
int N
= Integer .
parseInt ( next
( ) ) ; for ( int k = 0 ; k < N; k++ ) g[ k] = new ArrayList< Integer> ( ) ;
for ( int k = 1 ; k < N; k++ ) {
int a
= Integer .
parseInt ( next
( ) ) - 1 ; int b
= Integer .
parseInt ( next
( ) ) - 1 ;
g[ a] .add ( b) ;
g[ b] .add ( a) ;
}
HLD h = new HLD( g) ;
// h.print(out);
int M
= Integer .
parseInt ( next
( ) ) ; while ( M-- > 0 ) {
int q
= Integer .
parseInt ( next
( ) ) ; int a
= Integer .
parseInt ( next
( ) ) - 1 ; int b
= Integer .
parseInt ( next
( ) ) - 1 ;
if ( q == 2 ) {
out.println ( h.query ( a, b) ) ;
} else {
h.update ( a, b) ;
}
}
//
out.flush ( ) ;
}
}
class HLD {
private int root;
private List< Integer> [ ] g;
LCA lca;
LazyBinarySegmentTree stree;
HLD( List< Integer> [ ] g) {
this .g = g;
int N = g.length ;
size = new int [ N] ;
parent = new int [ N] ;
root = 0 ;
dfs( root, - 1 ) ;
numberOfChains = currentIndex = 0 ;
chainHead = new int [ N] ;
chainIndex = new int [ N] ;
nodeIndex = new int [ N] ;
decompose( root) ;
lca = new LCA( g, root) ;
stree = new LazyBinarySegmentTree( N) ;
}
public void update( int a, int b) {
int ancestor = lca.getLCA ( a, b) ;
mupdate( ancestor, a) ;
// System.out.println("...");
mupdate( ancestor, b) ;
// System.out.println();
stree.flip ( nodeIndex[ ancestor] , nodeIndex[ ancestor] ) ;
}
private void mupdate( int ancestor, int node) {
while ( chainIndex[ ancestor] != chainIndex[ node] ) {
int head = chains[ chainIndex[ node] ] .get ( 0 ) ;
// System.out.printf("updating(%d, %d)\n", nodeIndex[head], nodeIndex[node] );
stree.flip ( nodeIndex[ head] , nodeIndex[ node] ) ;
node = parent[ node] ;
}
// System.out.printf("updating(%d, %d)\n", nodeIndex[ancestor], nodeIndex[node] );
stree.flip ( nodeIndex[ ancestor] , nodeIndex[ node] ) ;
}
public int query( int a, int b) {
int ancestor = lca.getLCA ( a, b) ;
int ans = internalQuery( ancestor, a) ;
// System.out.println("...");
ans += internalQuery( ancestor, b) ;
// System.out.println();
ans += stree.getFlipped ( nodeIndex[ ancestor] , nodeIndex[ ancestor] ) ;
return ans;
}
private int internalQuery( int ancestor, int node) {
int ans = 0 ;
while ( chainIndex[ ancestor] != chainIndex[ node] ) {
int head = chains[ chainIndex[ node] ] .get ( 0 ) ;
// System.out.printf("query(%d, %d)\n", nodeIndex[head], nodeIndex[node] );
ans += stree.getFlipped ( nodeIndex[ head] , nodeIndex[ node] ) ;
node = parent[ node] ;
}
// System.out.printf("query(%d, %d)\n", nodeIndex[ancestor], nodeIndex[node] );
ans += stree.getFlipped ( nodeIndex[ ancestor] , nodeIndex[ node] ) ;
return ans;
}
out.
println ( "size: " + Arrays .
toString ( size
) ) ; out.println ( "chains:" ) ;
for ( int k = 0 ; k <= numberOfChains; k++ )
out.println ( " " + k + ": " + chains[ k] ) ;
out.
println ( "chainIndex: " + Arrays .
toString ( chainIndex
) ) ; out.
println ( "nodeIndex: " + Arrays .
toString ( nodeIndex
) ) ; }
private int numberOfChains;
private int currentIndex;
private List< Integer> [ ] chains; // chains[k] = the list of nodes in the chain k
private int [ ] chainHead; // chainHead[k] = the head note at chain k
private int [ ] chainIndex; // chainindex[k] = the chain index where node k belongs
private int [ ] nodeIndex; // nodeindex[k] = the index assigned to node k after decomposition
// apply decomposition to a node
private void decompose( int node) {
if ( chains[ numberOfChains] == null ) {
// this is a new chain
chains[ numberOfChains] = new LinkedList< Integer> ( ) ;
chainHead[ numberOfChains] = node;
}
chains[ numberOfChains] .add ( node) ;
chainIndex[ node] = numberOfChains;
nodeIndex[ node] = currentIndex++;
// System.out.println("decompose " + node);
// find the heaviest child
int heavyChild = - 1 ;
for ( int to : g[ node] ) if ( to != parent[ node] ) {
if ( heavyChild == - 1 || size[ heavyChild] < size[ to] ) {
heavyChild = to;
}
}
// System.out.println(" heavy child " + heavyChild);
if ( heavyChild == - 1 ) {
return ; // this node is a leaf
}
decompose( heavyChild) ;
for ( int to : g[ node] ) if ( to != parent[ node] && to != heavyChild) {
// decompose this child into a new chain
numberOfChains++;
decompose( to) ;
}
}
private int [ ] size; // size[k] = size of the subtree rooted at k
private int [ ] parent; // parent[k] = parent of node k
private void dfs( int node, int dad) {
parent[ node] = dad;
size[ node] = 1 ;
for ( int to : g[ node] ) if ( dad != to) {
dfs( to, node) ;
size[ node] += size[ to] ;
}
}
}
class LazyBinarySegmentTree {
int [ ] ones, twos, flip;
int size;
public LazyBinarySegmentTree( int size) {
size++;
int N = 1 ;
while ( ( N <<= 1 ) < size) ;
N <<= 1 ;
ones = new int [ N] ;
twos = new int [ N] ;
flip = new int [ N] ;
this .size = size;
}
// x and y sould start in 1
void flip( int x, int y) {
x++; y++;
update( 1 , size, x, y, 1 ) ;
// System.out.printf("update(%d, %d)\n", x, y );
}
int getFlipped( int x, int y) {
x++; y++;
// lasta parameter is for the initial status of each element in array (0, 1)
// System.out.printf("query(%d, %d) = %d\n", x, y, query( 1, size, x, y, 1, 1 ) );
return query( 1 , size, x, y, 1 , 1 ) ;
}
private void update( int lo, int hi, int x, int y, int i) {
if ( x > hi || y < lo)
return ;
int mid;
if ( x <= lo && y >= hi) {
ones[ i] = ( hi - lo + 1 ) - ones[ i] ;
flip[ i] += 1 ;
if ( flip[ i] > 1 )
flip[ i] -= 2 ;
return ;
}
mid = ( lo + hi) >> 1 ;
update( lo, mid, x, y, 2 * i) ;
update( mid + 1 , hi, x, y, 2 * i + 1 ) ;
ones[ i] = ones[ 2 * i] + ones[ 2 * i + 1 ] ;
if ( flip[ i] == 1 ) {
ones[ i] = ( hi - lo + 1 ) - ones[ i] ;
}
}
private int query( int lo, int hi, int x, int y, int i, int flag) {
if ( x > hi || y < lo)
return 0 ;
if ( x <= lo && y >= hi) {
if ( flag == 1 )
return ones[ i] ;
return ( hi - lo + 1 ) - ones[ i] ;
}
int mid = ( lo + hi) >> 1 , nflag = ( flag + flip[ i] ) ;
if ( nflag > 1 )
nflag -= 2 ;
return query( lo, mid, x, y, 2 * i, nflag) +
query( mid + 1 , hi, x, y, 2 * i + 1 , nflag) ;
}
}
class LCA {
int N;
int logN;
int [ ] dep;
int [ ] [ ] go;
List< Integer> [ ] g;
// 1 based index
LCA( List< Integer> g[ ] , int root) {
this .g = g;
N = g.length ;
logN = 1 ;
while ( ( 1 << logN) <= N)
logN++;
// System.out.println(N + " " + logN);
dep = new int [ N] ;
go = new int [ N] [ logN] ;
dfs( root, 0 , 0 ) ;
// Prepare for LCA queries.
for ( int k = 1 ; k < logN; ++ k) {
for ( int i = 1 ; i < N; ++ i) {
go[ i] [ k] = go[ go[ i] [ k - 1 ] ] [ k - 1 ] ;
}
}
}
private void dfs( int id, int depth, int dad) {
go[ id] [ 0 ] = dad;
dep[ id] = depth;
for ( int to : g[ id] ) {
if ( to != dad )
dfs( to, depth + 1 , id) ;
}
}
int getLCA( int u, int v) {
if ( dep[ u] < dep[ v] ) {
int aux = u;
u = v;
v = aux;
}
int diff = dep[ u] - dep[ v] ;
for ( int i = 0 ; diff != 0 ; ++ i, diff >>= 1 ) {
if ( ( diff & 1 ) != 0 ) {
u = go[ u] [ i] ;
}
}
if ( u == v)
return u;
for ( int i = logN - 1 ; i >= 0 ; -- i) {
if ( go[ u] [ i] != go[ v] [ i] ) {
u = go[ u] [ i] ;
v = go[ v] [ i] ;
}
}
return go[ u] [ 0 ] ;
}
}
CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuKjsKCnB1YmxpYyBjbGFzcyBGZWFyT2ZUaGVEYXJrIGltcGxlbWVudHMgUnVubmFibGUgewoKCXN0YXRpYyBCdWZmZXJlZFJlYWRlciBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSk7CglzdGF0aWMgUHJpbnRXcml0ZXIgb3V0ID0gbmV3IFByaW50V3JpdGVyKG5ldyBCdWZmZXJlZE91dHB1dFN0cmVhbShTeXN0ZW0ub3V0KSk7CglzdGF0aWMgU3RyaW5nVG9rZW5pemVyIHN0ID0gbmV3IFN0cmluZ1Rva2VuaXplcigiIik7CgoJcHVibGljIHN0YXRpYyBTdHJpbmcgbmV4dCgpIHsKCQl0cnkJewoJCXdoaWxlICghc3QuaGFzTW9yZVRva2VucygpKSB7CgkJCVN0cmluZyBzID0gYnIucmVhZExpbmUoKTsKCQkJaWYgKHMgPT0gbnVsbCkKCQkJCXJldHVybiBudWxsOwoJCQlzdCA9IG5ldyBTdHJpbmdUb2tlbml6ZXIocyk7CgkJfQoJCXJldHVybiBzdC5uZXh0VG9rZW4oKTsKCQl9CWNhdGNoKEV4Y2VwdGlvbiBlKQl7CgkJCXJldHVybgludWxsOwoJCX0KCX0KCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFzZGEpIHRocm93cyBFeGNlcHRpb24gewoJCW5ldyBUaHJlYWQobnVsbCwgbmV3IEZlYXJPZlRoZURhcmsoKSwgIk1haW4iLCAxPDwyOCkucnVuKCk7Cgl9CglwdWJsaWMgdm9pZCBydW4oKSB7CgkJaW50IE4gPSBJbnRlZ2VyLnBhcnNlSW50KCBuZXh0KCkgKTsKCQlBcnJheUxpc3Q8SW50ZWdlcj4gW10gZyA9IG5ldyBBcnJheUxpc3QgW05dOwoJCWZvciAoaW50IGsgPSAwOyBrIDwgTjsgaysrKQlnW2tdID0gbmV3IEFycmF5TGlzdDxJbnRlZ2VyPigpOwoJCWZvciAoaW50IGsgPSAxOyBrIDwgTjsgaysrKQl7CgkJCWludCBhID0gSW50ZWdlci5wYXJzZUludCggbmV4dCgpICkgLSAxOwoJCQlpbnQgYiA9IEludGVnZXIucGFyc2VJbnQoIG5leHQoKSApIC0gMTsKCgkJCWdbYV0uYWRkKGIpOwoJCQlnW2JdLmFkZChhKTsKCQl9CgoJCUhMRCBoID0gbmV3IEhMRChnKTsKCS8vCWgucHJpbnQob3V0KTsKCgkJaW50IE0gPSBJbnRlZ2VyLnBhcnNlSW50KCBuZXh0KCkgKTsKCQl3aGlsZQkoTS0tID4gMCkJewoJCQlpbnQgcSA9IEludGVnZXIucGFyc2VJbnQoIG5leHQoKSApOwoJCQlpbnQgYSA9IEludGVnZXIucGFyc2VJbnQoIG5leHQoKSApIC0gMTsKCQkJaW50IGIgPSBJbnRlZ2VyLnBhcnNlSW50KCBuZXh0KCkgKSAtIDE7CgoJCQlpZiAocSA9PSAyKSB7CgkJCQlvdXQucHJpbnRsbiggaC5xdWVyeShhLCBiKSApOwoJCQl9CWVsc2UJewoJCQkJaC51cGRhdGUoYSwgYik7CgkJCX0KCQl9CiAgICAgICAgLy8KICAgICAgICBvdXQuZmx1c2goKTsKICAgICAgICBTeXN0ZW0uZXhpdCgwKTsKICAgIH0KCQp9CgpjbGFzcyBITEQgewoJcHJpdmF0ZSBpbnQgcm9vdDsKCXByaXZhdGUgTGlzdDxJbnRlZ2VyPiBbXSBnOwoKCUxDQSBsY2E7CglMYXp5QmluYXJ5U2VnbWVudFRyZWUgc3RyZWU7CgoJSExEKExpc3Q8SW50ZWdlcj4gW10gZykJewoJCXRoaXMuZyA9IGc7CgkJaW50IE4gPSBnLmxlbmd0aDsKCgkJc2l6ZSA9IG5ldyBpbnQgW05dOwoJCXBhcmVudCA9IG5ldyBpbnQgW05dOwoJCXJvb3QgPSAwOwoJCWRmcyhyb290LCAtMSk7CgoJCW51bWJlck9mQ2hhaW5zID0gY3VycmVudEluZGV4ID0gMDsKCQljaGFpbnMgPSBuZXcgTGlua2VkTGlzdCBbTl07CgkJY2hhaW5IZWFkID0gbmV3IGludCBbTl07CgkJY2hhaW5JbmRleCA9IG5ldyBpbnQgW05dOwoJCW5vZGVJbmRleCA9IG5ldyBpbnQgW05dOwoJCWRlY29tcG9zZShyb290KTsKCgkJbGNhID0gbmV3IExDQShnLCByb290KTsKCQlzdHJlZSA9IG5ldyBMYXp5QmluYXJ5U2VnbWVudFRyZWUoTik7Cgl9CgoJcHVibGljIHZvaWQgdXBkYXRlKGludCBhLCBpbnQgYikJewoJCWludCBhbmNlc3RvciA9IGxjYS5nZXRMQ0EoYSwgYik7CgoJCW11cGRhdGUoYW5jZXN0b3IsIGEpOwoJLy8JU3lzdGVtLm91dC5wcmludGxuKCIuLi4iKTsKCgkJbXVwZGF0ZShhbmNlc3RvciwgYik7CgkvLwlTeXN0ZW0ub3V0LnByaW50bG4oKTsKCgkJc3RyZWUuZmxpcCggbm9kZUluZGV4W2FuY2VzdG9yXSwgbm9kZUluZGV4W2FuY2VzdG9yXSApOwoJfQoKCXByaXZhdGUgdm9pZCBtdXBkYXRlKGludCBhbmNlc3RvciwgaW50IG5vZGUpCXsKCQl3aGlsZQkoIGNoYWluSW5kZXhbYW5jZXN0b3JdICE9IGNoYWluSW5kZXhbbm9kZV0gKQl7CgkJCWludCBoZWFkID0gY2hhaW5zWyBjaGFpbkluZGV4W25vZGVdIF0uZ2V0KDApOwoKCS8vCQlTeXN0ZW0ub3V0LnByaW50ZigidXBkYXRpbmcoJWQsICVkKVxuIiwgbm9kZUluZGV4W2hlYWRdLCBub2RlSW5kZXhbbm9kZV0gKTsKCQkJc3RyZWUuZmxpcChub2RlSW5kZXhbaGVhZF0sIG5vZGVJbmRleFtub2RlXSk7CgkJCW5vZGUgPSBwYXJlbnRbbm9kZV07CgkJfQoKCS8vCVN5c3RlbS5vdXQucHJpbnRmKCJ1cGRhdGluZyglZCwgJWQpXG4iLCBub2RlSW5kZXhbYW5jZXN0b3JdLCBub2RlSW5kZXhbbm9kZV0gKTsKCQlzdHJlZS5mbGlwKCBub2RlSW5kZXhbYW5jZXN0b3JdLCBub2RlSW5kZXhbbm9kZV0gKTsKCX0KCglwdWJsaWMgaW50IHF1ZXJ5KGludCBhLCBpbnQgYikJewoJCWludCBhbmNlc3RvciA9IGxjYS5nZXRMQ0EoYSwgYik7CgoJCWludCBhbnMgPSBpbnRlcm5hbFF1ZXJ5KGFuY2VzdG9yLCBhKTsKCS8vCVN5c3RlbS5vdXQucHJpbnRsbigiLi4uIik7CgoJCWFucyArPSBpbnRlcm5hbFF1ZXJ5KGFuY2VzdG9yLCBiKTsKCS8vCVN5c3RlbS5vdXQucHJpbnRsbigpOwoKCQlhbnMgKz0gc3RyZWUuZ2V0RmxpcHBlZCggbm9kZUluZGV4W2FuY2VzdG9yXSwgbm9kZUluZGV4W2FuY2VzdG9yXSApOwoKCQlyZXR1cm4gYW5zOwoJfQoKCXByaXZhdGUgaW50IGludGVybmFsUXVlcnkoaW50IGFuY2VzdG9yLCBpbnQgbm9kZSkJewoJCWludCBhbnMgPSAwOwoJCXdoaWxlCSggY2hhaW5JbmRleFthbmNlc3Rvcl0gIT0gY2hhaW5JbmRleFtub2RlXSApCXsKCQkJaW50IGhlYWQgPSBjaGFpbnNbIGNoYWluSW5kZXhbbm9kZV0gXS5nZXQoMCk7CgoJCS8vCVN5c3RlbS5vdXQucHJpbnRmKCJxdWVyeSglZCwgJWQpXG4iLCBub2RlSW5kZXhbaGVhZF0sIG5vZGVJbmRleFtub2RlXSApOwoJCQlhbnMgKz0gc3RyZWUuZ2V0RmxpcHBlZChub2RlSW5kZXhbaGVhZF0sIG5vZGVJbmRleFtub2RlXSk7CgkJCW5vZGUgPSBwYXJlbnRbbm9kZV07CgkJfQoKCS8vCVN5c3RlbS5vdXQucHJpbnRmKCJxdWVyeSglZCwgJWQpXG4iLCBub2RlSW5kZXhbYW5jZXN0b3JdLCBub2RlSW5kZXhbbm9kZV0gKTsKCQlhbnMgKz0gc3RyZWUuZ2V0RmxpcHBlZCggbm9kZUluZGV4W2FuY2VzdG9yXSwgbm9kZUluZGV4W25vZGVdICk7CgkJcmV0dXJuCWFuczsKCX0KCglwdWJsaWMgdm9pZCBwcmludChQcmludFdyaXRlciBvdXQpCXsKCQlvdXQucHJpbnRsbigic2l6ZTogIiArIEFycmF5cy50b1N0cmluZyhzaXplKSApOwoJCW91dC5wcmludGxuKCJjaGFpbnM6Iik7CgkJZm9yIChpbnQgayA9IDA7IGsgPD0gbnVtYmVyT2ZDaGFpbnM7IGsrKykKCQkJb3V0LnByaW50bG4oIiAiICsgayArICI6ICIgKyBjaGFpbnNba10gKTsKCgkJb3V0LnByaW50bG4oImNoYWluSW5kZXg6ICIgKyBBcnJheXMudG9TdHJpbmcoY2hhaW5JbmRleCkpOwoJCW91dC5wcmludGxuKCJub2RlSW5kZXg6ICIgKyBBcnJheXMudG9TdHJpbmcobm9kZUluZGV4KSk7Cgl9CgoJcHJpdmF0ZSBpbnQgbnVtYmVyT2ZDaGFpbnM7Cglwcml2YXRlIGludCBjdXJyZW50SW5kZXg7Cglwcml2YXRlIExpc3Q8SW50ZWdlcj4gW10gY2hhaW5zOwkvLyBjaGFpbnNba10gPSB0aGUgbGlzdCBvZiBub2RlcyBpbiB0aGUgY2hhaW4gawoJcHJpdmF0ZSBpbnQgW10gY2hhaW5IZWFkOwkJCS8vIGNoYWluSGVhZFtrXSA9IHRoZSBoZWFkIG5vdGUgYXQgY2hhaW4gawoJcHJpdmF0ZSBpbnQgW10gY2hhaW5JbmRleDsJCQkvLyBjaGFpbmluZGV4W2tdID0gdGhlIGNoYWluIGluZGV4IHdoZXJlIG5vZGUgayBiZWxvbmdzCglwcml2YXRlIGludCBbXSBub2RlSW5kZXg7CQkJLy8gbm9kZWluZGV4W2tdID0gdGhlIGluZGV4IGFzc2lnbmVkIHRvIG5vZGUgayBhZnRlciBkZWNvbXBvc2l0aW9uCgoJLy8gYXBwbHkgZGVjb21wb3NpdGlvbiB0byBhIG5vZGUKCXByaXZhdGUgdm9pZCBkZWNvbXBvc2UoaW50IG5vZGUpCXsKCQlpZiAoY2hhaW5zW251bWJlck9mQ2hhaW5zXSA9PSBudWxsKSB7CgkJCS8vIHRoaXMgaXMgYSBuZXcgY2hhaW4KCQkJY2hhaW5zW251bWJlck9mQ2hhaW5zXSA9IG5ldyBMaW5rZWRMaXN0PEludGVnZXI+KCk7CgkJCWNoYWluSGVhZFtudW1iZXJPZkNoYWluc10gPSBub2RlOwoJCX0KCQljaGFpbnNbbnVtYmVyT2ZDaGFpbnNdLmFkZChub2RlKTsKCQljaGFpbkluZGV4W25vZGVdID0gbnVtYmVyT2ZDaGFpbnM7CgkJbm9kZUluZGV4W25vZGVdID0gY3VycmVudEluZGV4Kys7CgoJLy8JU3lzdGVtLm91dC5wcmludGxuKCJkZWNvbXBvc2UgIiArIG5vZGUpOwoJCS8vIGZpbmQgdGhlIGhlYXZpZXN0IGNoaWxkCgkJaW50IGhlYXZ5Q2hpbGQgPSAtMTsKCQlmb3IgKGludCB0byA6IGdbbm9kZV0pCWlmICh0byAhPSBwYXJlbnRbbm9kZV0pIHsKCQkJaWYgKCBoZWF2eUNoaWxkID09IC0xIHx8IHNpemVbaGVhdnlDaGlsZF0gPCBzaXplW3RvXSApIHsKCQkJCWhlYXZ5Q2hpbGQgPSB0bzsKCQkJfQoJCX0KCgkvLwlTeXN0ZW0ub3V0LnByaW50bG4oIiBoZWF2eSBjaGlsZCAiICsgaGVhdnlDaGlsZCk7CgoJCWlmIChoZWF2eUNoaWxkID09IC0xKSB7CgkJCXJldHVybjsJLy8gdGhpcyBub2RlIGlzIGEgbGVhZgoJCX0KCgkJZGVjb21wb3NlKGhlYXZ5Q2hpbGQpOwoKCQlmb3IgKGludCB0byA6IGdbbm9kZV0pCWlmICh0byAhPSBwYXJlbnRbbm9kZV0gJiYgdG8gIT0gaGVhdnlDaGlsZCkgewoJCQkvLyBkZWNvbXBvc2UgdGhpcyBjaGlsZCBpbnRvIGEgbmV3IGNoYWluCgkJCW51bWJlck9mQ2hhaW5zKys7CgkJCWRlY29tcG9zZSh0byk7CgkJfQoJfQoKCXByaXZhdGUgaW50IFtdIHNpemU7CS8vIHNpemVba10gPSBzaXplIG9mIHRoZSBzdWJ0cmVlIHJvb3RlZCBhdCBrCglwcml2YXRlIGludCBbXSBwYXJlbnQ7CS8vIHBhcmVudFtrXSA9IHBhcmVudCBvZiBub2RlIGsKCXByaXZhdGUgdm9pZCBkZnMoaW50IG5vZGUsIGludCBkYWQpCXsKCQlwYXJlbnRbbm9kZV0gPSBkYWQ7CgkJc2l6ZVtub2RlXSA9IDE7CgkJZm9yIChpbnQgdG8gOiBnW25vZGVdKQlpZiAoZGFkICE9IHRvKSB7CgkJCWRmcyh0bywgbm9kZSk7CgkJCXNpemVbbm9kZV0gKz0gc2l6ZVt0b107CgkJfQoJfQp9CgpjbGFzcyBMYXp5QmluYXJ5U2VnbWVudFRyZWUgewoJaW50IFtdIG9uZXMsIHR3b3MsIGZsaXA7CglpbnQgc2l6ZTsKCQoJCglwdWJsaWMgTGF6eUJpbmFyeVNlZ21lbnRUcmVlKGludCBzaXplKSB7CgkJc2l6ZSsrOwoJCWludCBOID0gMTsKCQl3aGlsZSAoIChOIDw8PSAxKSA8IHNpemUpOwoJCU4gPDw9IDE7CgoJCW9uZXMgPSBuZXcgaW50W05dOwoJCXR3b3MgPSBuZXcgaW50W05dOwoJCWZsaXAgPSBuZXcgaW50W05dOwoJCQoJCXRoaXMuc2l6ZSA9IHNpemU7Cgl9CgkvLyB4IGFuZCB5IHNvdWxkIHN0YXJ0IGluIDEKCXZvaWQgZmxpcChpbnQgeCwgaW50IHkpCXsKCQl4Kys7IHkrKzsKCQl1cGRhdGUoIDEsIHNpemUsIHgsIHksIDEgKTsKCS8vCVN5c3RlbS5vdXQucHJpbnRmKCJ1cGRhdGUoJWQsICVkKVxuIiwgeCwgeSApOwoJfQoJCglpbnQgZ2V0RmxpcHBlZChpbnQgeCwgaW50IHkpCXsKCQl4Kys7IHkrKzsKCQkvLyBsYXN0YSBwYXJhbWV0ZXIgaXMgZm9yIHRoZSBpbml0aWFsIHN0YXR1cyBvZiBlYWNoIGVsZW1lbnQgaW4gYXJyYXkgKDAsIDEpCgkvLwlTeXN0ZW0ub3V0LnByaW50ZigicXVlcnkoJWQsICVkKSA9ICVkXG4iLCB4LCB5LCBxdWVyeSggMSwgc2l6ZSwgeCwgeSwgMSwgMSApICk7CgkJcmV0dXJuCXF1ZXJ5KCAxLCBzaXplLCB4LCB5LCAxLCAxICk7Cgl9CgkKCQoJcHJpdmF0ZSB2b2lkIHVwZGF0ZShpbnQgbG8sIGludCBoaSwgaW50IHgsIGludCB5LCBpbnQgaSkgewoJCWlmICh4ID4gaGkgfHwgeSA8IGxvKQoJCQlyZXR1cm47CgkJCgkJaW50IG1pZDsKCQlpZiAoeCA8PSBsbyAmJiB5ID49IGhpKSB7CgkJCW9uZXNbaV0gPSAoaGkgLSBsbyArIDEpIC0gb25lc1tpXTsKCQkJZmxpcFtpXSArPSAxOwoJCQlpZiAoZmxpcFtpXSA+IDEpCgkJCQlmbGlwW2ldIC09IDI7CgkJCXJldHVybjsKCQl9CgkJCgkJbWlkID0gKGxvICsgaGkpID4+IDE7CgkJdXBkYXRlKGxvLCBtaWQsIHgsIHksIDIgKiBpKTsKCQl1cGRhdGUobWlkICsgMSwgaGksIHgsIHksIDIgKiBpICsgMSk7CgkJCgkJb25lc1tpXSA9IG9uZXNbMiAqIGldICsgb25lc1syICogaSArIDFdOwoJCgkJaWYgKGZsaXBbaV0gPT0gMSkgewoJCQlvbmVzW2ldID0gKGhpIC0gbG8gKyAxKSAtIG9uZXNbaV07CgkJfQoJfQoJCgoJcHJpdmF0ZSBpbnQgcXVlcnkoaW50IGxvLCBpbnQgaGksIGludCB4LCBpbnQgeSwgaW50IGksIGludCBmbGFnKSB7CgkJaWYgKHggPiBoaSB8fCB5IDwgbG8pCgkJCXJldHVybiAwOwoJCQoJCWlmICh4IDw9IGxvICYmIHkgPj0gaGkpIHsKCQkJaWYgKGZsYWcgPT0gMSkKCQkJCXJldHVybiBvbmVzW2ldOwoJCQkKCQkJcmV0dXJuIChoaSAtIGxvICsgMSkgLSBvbmVzW2ldOwoJCX0KCQkKCQkKCQlpbnQgbWlkID0gKGxvICsgaGkpID4+IDEsIG5mbGFnID0gKGZsYWcgKyBmbGlwW2ldKTsKCQkKCQlpZiAobmZsYWcgPiAxKQoJCQluZmxhZyAtPSAyOwoJCQoJCXJldHVybglxdWVyeShsbywgbWlkLCB4LCB5LCAyICogaSwgbmZsYWcpCSsKCQkJCXF1ZXJ5KG1pZCArIDEsIGhpLCB4LCB5LCAyICogaSArIDEsIG5mbGFnKTsKCX0KCQp9CgoKY2xhc3MgTENBIHsKCWludCBOOwoJaW50IGxvZ047CglpbnRbXSBkZXA7CglpbnRbXVtdIGdvOwoJTGlzdDxJbnRlZ2VyPltdIGc7CgkvLyAxIGJhc2VkIGluZGV4CglMQ0EoTGlzdDxJbnRlZ2VyPiBnW10sIGludCByb290KSB7CgkJdGhpcy5nID0gZzsKCQlOID0gZy5sZW5ndGg7CgkJbG9nTiA9IDE7CgkJd2hpbGUgKCgxIDw8IGxvZ04pIDw9IE4pCgkJCWxvZ04rKzsKCgkvLwlTeXN0ZW0ub3V0LnByaW50bG4oTiArICIgIiArIGxvZ04pOwoJCWRlcCA9IG5ldyBpbnRbTl07CgkJZ28gPSBuZXcgaW50W05dW2xvZ05dOwoKCQlkZnMocm9vdCwgMCwgMCk7CgoJCS8vIFByZXBhcmUgZm9yIExDQSBxdWVyaWVzLgoJCWZvciAoaW50IGsgPSAxOyBrIDwgbG9nTjsgKytrKSB7CgkJCWZvciAoaW50IGkgPSAxOyBpIDwgTjsgKytpKSB7CgkJCQlnb1tpXVtrXSA9IGdvW2dvW2ldW2sgLSAxXV1bayAtIDFdOwoJCQl9CgkJfQoJfQoKCXByaXZhdGUgdm9pZCBkZnMoaW50IGlkLCBpbnQgZGVwdGgsIGludCBkYWQpIHsKCQlnb1tpZF1bMF0gPSBkYWQ7CgkJZGVwW2lkXSA9IGRlcHRoOwoKCQlmb3IgKGludCB0byA6IGdbaWRdKSB7CgkJCWlmICggdG8gIT0gZGFkICkKCQkJCWRmcyh0bywgZGVwdGggKyAxLCBpZCk7CgkJfQoJfQoKCWludCBnZXRMQ0EoaW50IHUsIGludCB2KSB7CgkJaWYgKGRlcFt1XSA8IGRlcFt2XSkgewoJCQlpbnQgYXV4ID0gdTsKCQkJdSA9IHY7CgkJCXYgPSBhdXg7CgkJfQoKCQlpbnQgZGlmZiA9IGRlcFt1XSAtIGRlcFt2XTsKCQlmb3IgKGludCBpID0gMDsgZGlmZiAhPSAwOyArK2ksIGRpZmYgPj49IDEpIHsKCQkJaWYgKCAoZGlmZiAmIDEpICE9IDAgKSB7CgkJCQl1ID0gZ29bdV1baV07CgkJCX0KCQl9CgoJCWlmICh1ID09IHYpCgkJCXJldHVybiB1OwoKCQlmb3IgKGludCBpID0gbG9nTiAtIDE7IGkgPj0gMDsgLS1pKSB7CgkJCWlmIChnb1t1XVtpXSAhPSBnb1t2XVtpXSkgewoJCQkJdSA9IGdvW3VdW2ldOwoJCQkJdiA9IGdvW3ZdW2ldOwoJCQl9CgkJfQoJCXJldHVybiBnb1t1XVswXTsKCX0KfQoKCg==