import java.io.* ;
import java.util.ArrayList ;
import java.util.Arrays ;
import java.util.Collections ;
import java.util.Comparator ;
import java.util.HashMap ;
import java.util.StringTokenizer ;
public class Main{
public static final int mod = 1000000007 ;
public static ArrayList< Integer> adj[ ] ;
public static int w[ ] ,a[ ] ,st[ ] ,et[ ] ,par[ ] [ ] ,depth[ ] ,occ[ ] ,cnt[ ] ,time,sum;
public static int N = 40011 ;
// TODO Auto-generated method stub
int n = in.nextInt ( ) ;
int m = in.nextInt ( ) ;
sum = time = 0 ;
w = new int [ N] ;
st = new int [ N] ;
et = new int [ N] ;
a = new int [ 2 * N] ;
par = new int [ N] [ 16 ] ;
depth = new int [ N] ;
int block
= ( int ) Math .
sqrt ( n
) ;
for ( int i= 0 ; i< N; i++ )
adj[ i] = new ArrayList< Integer> ( ) ;
int no = 0 ;
for ( int i= 1 ; i<= n; i++ )
{
int tmp = in.nextInt ( ) ;
if ( ! hash.containsKey ( tmp) )
{
hash.put ( tmp,++ no) ;
}
w[ i] = hash.get ( tmp) ;
}
for ( int i= 0 ; i< n- 1 ; i++ )
{
int u = in.nextInt ( ) ;
int v = in.nextInt ( ) ;
adj[ u] .add ( v) ;
adj[ v] .add ( u) ;
}
for ( int i= 0 ; i< 16 ; i++ )
for ( int j= 1 ; j<= n; j++ )
par[ j] [ i] = - 1 ;
depth[ 1 ] = 0 ;
dfs( 1 ,0 ) ;
for ( int i= 1 ; i< 16 ; i++ )
for ( int j= 1 ; j<= n; j++ )
{
if ( par[ j] [ i- 1 ] != - 1 )
par[ j] [ i] = par[ par[ j] [ i- 1 ] ] [ i- 1 ] ;
}
Query q[ ] = new Query[ m] ;
int ans[ ] = new int [ m] ;
for ( int i= 0 ; i< m; i++ )
{
int u = in.nextInt ( ) ;
int v = in.nextInt ( ) ;
if ( depth [ u] < depth[ v] )
{
int tmp = u;
u = v;
v = tmp;
}
int lc = lca( u, v) ;
if ( lc == v)
{
q[ i] = new Query( st[ v] ,st[ u] + 1 ,i,- 1 ) ;
}
else {
if ( st[ v] > et[ u] )
{
q[ i] = new Query( et[ u] ,st[ v] + 1 ,i,lc) ;
}
else
{
q[ i] = new Query( et[ v] ,st[ u] + 1 ,i,lc) ;
}
}
}
Arrays .
sort ( q,
new Comparator
< Query
> ( ) {
public int compare( Query q1,Query q2)
{
if ( q1.l / block < q2.l / block)
return - 1 ;
else if ( q1.l / block > q2.l / block)
return 1 ;
else
return q1.r - q2.r ;
}
} ) ;
occ = new int [ N] ;
cnt = new int [ N] ;
sum = 0 ;
int L = 0 , R = 0 ;
StringBuilder sb = new StringBuilder( "" ) ;
for ( int i= 0 ; i< m; i++ )
{
int nextL = q[ i] .l ;
int nextR = q[ i] .r ;
while ( L < nextL)
{
remove( a[ L] ) ;
L++;
}
while ( L > nextL)
{
add( a[ L- 1 ] ) ;
L--;
}
while ( R < nextR)
{
add( a[ R] ) ;
R++;
}
while ( R > nextR )
{
remove( a[ R- 1 ] ) ;
R--;
}
if ( q[ i] .lca != - 1 && cnt[ w[ q[ i] .lca ] ] == 0 )
{
ans[ q[ i] .i ] = sum+ 1 ;
}
else
{
ans[ q[ i] .i ] = sum;
}
}
for ( int i= 0 ; i< m; i++ )
sb.append ( ans[ i] + "\n " ) ;
System .
out .
println ( sb.
toString ( ) ) ;
}
static void remove( int x)
{
int wt = w[ x] ;
occ[ x] --;
if ( occ[ x] == 1 ) {
cnt[ wt] ++;
if ( cnt[ wt] == 1 )
sum++;
return ;
}
cnt[ wt] --;
if ( cnt[ wt] == 0 ) sum--;
}
static void add( int x)
{
occ[ x] ++;
cnt[ w[ x] ] ++;
if ( occ[ x] == 2 ) {
cnt[ w[ x] ] -= 2 ;
if ( cnt[ w[ x] ] == 0 )
sum--;
}
else if ( cnt[ w[ x] ] == 1 ) sum++;
}
static class Query{
int l,r,i,lca;
Query( int l,int r,int i,int lca)
{
this .lca = lca;
this .l = l;
this .r = r;
this .i = i;
}
}
static int lca( int u,int v)
{
int lg, i;
for ( lg = 0 ; ( 1 << lg) <= depth[ u] ; lg++ ) ;
lg--;
for ( i= lg; i>= 0 ; i-- )
if ( depth[ u] - ( 1 << i) >= depth[ v] )
u = par[ u] [ i] ;
if ( u == v)
return u;
for ( i = lg; i >= 0 ; i-- ) {
if ( par[ u] [ i] != - 1 && par[ u] [ i] != par[ v] [ i] )
{ u = par[ u] [ i] ; v = par[ v] [ i] ; }
}
return par[ u] [ 0 ] ;
}
static void dfs( int curr,int prev)
{
st[ curr] = ++ time;
a[ time] = curr;
for ( int i= 0 ; i< adj[ curr] .size ( ) ; i++ )
{
int next = adj[ curr] .get ( i) ;
if ( next != prev)
{
depth[ next] = depth[ curr] + 1 ;
par[ next] [ 0 ] = curr;
dfs( next,curr) ;
}
}
et[ curr] = ++ time;
a[ time] = curr;
}
static double dist( double x1,double y1,double x2,double y2)
{
return Math .
sqrt ( ( x1
- x2
) * ( x1
- x2
) + ( y1
- y2
) * ( y1
- y2
) ) ;
}
static long modpowIter( long a, long b, long c) {
long ans= 1 ;
while ( b != 0 ) {
if ( b% 2 == 1 )
ans= ( ans* a) % c;
a= ( a* a) % c;
b /= 2 ;
}
return ans;
}
static int gcd( int a,int b)
{
if ( b == 0 )
return a;
else return gcd( b,a% b) ;
}
static int lcm( int a, int b)
{
return ( a* b) / gcd( a,b) ;
}
{
final private int BUFFER_SIZE = 1 << 16 ;
private byte [ ] buffer;
private int bufferPointer, bytesRead;
{
buffer = new byte [ BUFFER_SIZE] ;
bufferPointer = bytesRead = 0 ;
}
{
buffer = new byte [ BUFFER_SIZE] ;
bufferPointer = bytesRead = 0 ;
}
{
byte [ ] buf = new byte [ 64 ] ; // line length
int cnt = 0 , c;
while ( ( c = read( ) ) != - 1 )
{
if ( c == '\n ' )
break ;
buf[ cnt++ ] = ( byte ) c;
}
return new String ( buf,
0 , cnt
) ; }
{
int ret = 0 ;
byte c = read( ) ;
while ( c <= ' ' )
c = read( ) ;
boolean neg = ( c == '-' ) ;
if ( neg)
c = read( ) ;
do
{
ret = ret * 10 + c - '0' ;
} while ( ( c = read( ) ) >= '0' && c <= '9' ) ;
if ( neg)
return - ret;
return ret;
}
{
long ret = 0 ;
byte c = read( ) ;
while ( c <= ' ' )
c = read( ) ;
boolean neg = ( c == '-' ) ;
if ( neg)
c = read( ) ;
do {
ret = ret * 10 + c - '0' ;
}
while ( ( c = read( ) ) >= '0' && c <= '9' ) ;
if ( neg)
return - ret;
return ret;
}
{
double ret = 0 , div = 1 ;
byte c = read( ) ;
while ( c <= ' ' )
c = read( ) ;
boolean neg = ( c == '-' ) ;
if ( neg)
c = read( ) ;
do {
ret = ret * 10 + c - '0' ;
}
while ( ( c = read( ) ) >= '0' && c <= '9' ) ;
if ( c == '.' )
{
while ( ( c = read( ) ) >= '0' && c <= '9' )
{
ret += ( c - '0' ) / ( div *= 10 ) ;
}
}
if ( neg)
return - ret;
return ret;
}
{
bytesRead = din.read ( buffer, bufferPointer = 0 , BUFFER_SIZE) ;
if ( bytesRead == - 1 )
buffer[ 0 ] = - 1 ;
}
{
if ( bufferPointer == bytesRead)
fillBuffer( ) ;
return buffer[ bufferPointer++ ] ;
}
{
if ( din == null )
return ;
din.close ( ) ;
}
}
}
aW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC5BcnJheUxpc3Q7CmltcG9ydCBqYXZhLnV0aWwuQXJyYXlzOwppbXBvcnQgamF2YS51dGlsLkNvbGxlY3Rpb25zOwppbXBvcnQgamF2YS51dGlsLkNvbXBhcmF0b3I7CmltcG9ydCBqYXZhLnV0aWwuSGFzaE1hcDsKaW1wb3J0IGphdmEudXRpbC5TdHJpbmdUb2tlbml6ZXI7CiAKIApwdWJsaWMgY2xhc3MgTWFpbnsKCXB1YmxpYyBzdGF0aWMgZmluYWwgaW50IG1vZCA9IDEwMDAwMDAwMDc7CglwdWJsaWMgc3RhdGljIEFycmF5TGlzdDxJbnRlZ2VyPiBhZGpbXTsKCXB1YmxpYyBzdGF0aWMgaW50IHdbXSxhW10sc3RbXSxldFtdLHBhcltdW10sZGVwdGhbXSxvY2NbXSxjbnRbXSx0aW1lLHN1bTsKCXB1YmxpYyBzdGF0aWMgaW50IE4gPSA0MDAxMTsKCXB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpdGhyb3dzIElPRXhjZXB0aW9uIHsKCQkvLyBUT0RPIEF1dG8tZ2VuZXJhdGVkIG1ldGhvZCBzdHViCgkJSW5wdXRTdHJlYW0gaW5wdXQgPSBTeXN0ZW0uaW47CgkJUmVhZGVyIGluICA9IG5ldyBSZWFkZXIoKTsKCQlCdWZmZXJlZFJlYWRlciBiciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoU3lzdGVtLmluKSk7CgkKCQlpbnQgbiA9IGluLm5leHRJbnQoKTsKCQlpbnQgbSA9IGluLm5leHRJbnQoKTsKCQkKCQlzdW0gPSB0aW1lID0gMDsKCQlhZGogPSBuZXcgQXJyYXlMaXN0W05dOwoJCXcgPSBuZXcgaW50W05dOwoJCXN0ID0gbmV3IGludFtOXTsKCQlldCA9IG5ldyBpbnRbTl07CgkJYSA9IG5ldyBpbnRbMipOXTsKCQlwYXIgPSBuZXcgaW50W05dWzE2XTsKCQlkZXB0aCA9IG5ldyBpbnRbTl07CgkJaW50IGJsb2NrID0gKGludClNYXRoLnNxcnQobik7CgkJCgkJSGFzaE1hcDxJbnRlZ2VyLEludGVnZXI+IGhhc2ggPSBuZXcgSGFzaE1hcDxJbnRlZ2VyLEludGVnZXI+KCk7CgkJCgkJZm9yKGludCBpPTA7IGk8TjsgaSsrKQoJCQlhZGpbaV0gPSBuZXcgQXJyYXlMaXN0PEludGVnZXI+KCk7CgkJCgkJaW50IG5vID0gMDsKCQlmb3IoaW50IGk9MTsgaTw9bjsgaSsrKQoJCQl7CgkJCQlpbnQgdG1wID0gaW4ubmV4dEludCgpOwoJCQkJaWYoIWhhc2guY29udGFpbnNLZXkodG1wKSkKCQkJCXsKCQkJCQloYXNoLnB1dCh0bXAsKytubyk7CgkJCQl9CgkJCQl3W2ldID0gaGFzaC5nZXQodG1wKTsKCQkJfQoJCQoJCWZvcihpbnQgaT0wOyBpPG4tMTsgaSsrKQoJCXsKCQkJaW50IHUgPSBpbi5uZXh0SW50KCk7CgkJCWludCB2ID0gaW4ubmV4dEludCgpOwoJCQlhZGpbdV0uYWRkKHYpOwoJCQlhZGpbdl0uYWRkKHUpOwoJCX0KCQkKCQlmb3IoaW50IGk9MDsgaTwxNjsgaSsrKQoJCQlmb3IoaW50IGo9MTsgajw9bjsgaisrKQoJCQkJcGFyW2pdW2ldID0gLTE7CgkJCgkJZGVwdGhbMV0gPSAwOwoJCWRmcygxLDApOwoJCQoJCWZvcihpbnQgaT0xOyBpPDE2OyBpKyspCgkJCWZvcihpbnQgaj0xOyBqPD1uOyBqKyspCgkJCQl7CgkJCQlpZihwYXJbal1baS0xXSAhPSAtMSkKCQkJCQlwYXJbal1baV0gPSBwYXJbcGFyW2pdW2ktMV1dW2ktMV07CgkJCQl9CgkJCgkJCgkJUXVlcnkgcVtdID0gbmV3IFF1ZXJ5W21dOwoJCWludCBhbnNbXSA9IG5ldyBpbnRbbV07CgkJCgkJZm9yKGludCBpPTA7IGk8bTsgaSsrKQoJCXsKCQkJaW50IHUgPSBpbi5uZXh0SW50KCk7CgkJCWludCB2ID0gaW4ubmV4dEludCgpOwoJCQkKCQkJaWYgKGRlcHRoIFt1XSA8IGRlcHRoW3ZdKQoJCQkJewoJCQkJCWludCB0bXAgPSB1OwoJCQkJCXUgPSB2OwoJCQkJCXYgPSB0bXA7CgkJCQl9CgkJCWludCBsYyA9IGxjYSh1LCB2KTsKCQkJaWYgKGxjID09IHYpCgkJCXsKCQkJCXFbaV0gPSBuZXcgUXVlcnkoc3Rbdl0sc3RbdV0rMSxpLC0xKTsKCQkJfQoJCQllbHNlewoJCQkJaWYgKHN0W3ZdID4gZXRbdV0pCgkJCQl7CQoJCQkJCXFbaV0gPSBuZXcgUXVlcnkoZXRbdV0sc3Rbdl0rMSxpLGxjKTsKCQkJCX0KCQkJCWVsc2UKCQkJCXsKCQkJCQlxW2ldID0gbmV3IFF1ZXJ5KGV0W3ZdLHN0W3VdKzEsaSxsYyk7CgkJCQl9CgkJCX0KCQkJCgkJfQoJCQoJCQoJCQoJCUFycmF5cy5zb3J0KHEsbmV3IENvbXBhcmF0b3I8UXVlcnk+KCl7CgkJCQoJCQlwdWJsaWMgaW50IGNvbXBhcmUoUXVlcnkgcTEsUXVlcnkgcTIpCgkJCXsKCQkJCWlmKHExLmwvYmxvY2sgPCBxMi5sL2Jsb2NrKQoJCQkJCXJldHVybiAtMTsKCQkJCWVsc2UgaWYocTEubC9ibG9jayA+IHEyLmwvYmxvY2spCgkJCQkJcmV0dXJuIDE7CgkJCQllbHNlCgkJCQkJcmV0dXJuIHExLnItcTIucjsKCQkJfQoJCQkKCQl9KTsKCQkKCQlvY2MgPSBuZXcgaW50W05dOwoJCWNudCA9IG5ldyBpbnRbTl07CgkJc3VtID0gMDsKCgkJaW50IEwgPSAwLCBSID0gMDsKCQlTdHJpbmdCdWlsZGVyIHNiID0gbmV3IFN0cmluZ0J1aWxkZXIoIiIpOwoJCWZvcihpbnQgaT0wOyBpPG07IGkrKykKCQl7CgkJCQoJCQlpbnQgbmV4dEwgPSBxW2ldLmw7CgkJCWludCBuZXh0UiA9IHFbaV0ucjsKCQkJCgkJCXdoaWxlKEwgPCBuZXh0TCkKCQkJewoJCQkJcmVtb3ZlKGFbTF0pOwoJCQkJTCsrOwoJCQl9CgkJCQoJCQl3aGlsZShMID4gbmV4dEwpCgkJCXsKCQkJCWFkZChhW0wtMV0pOwoJCQkJTC0tOwoJCQl9CgkJCQoJCQkKCQkJd2hpbGUoUiA8IG5leHRSKQoJCQl7CgkJCQlhZGQoYVtSXSk7CgkJCQlSKys7CQoJCQl9CgkJCQoJCQl3aGlsZShSID4gbmV4dFIgKQoJCQl7CgkJCQlyZW1vdmUoYVtSLTFdKTsKCQkJCVItLTsKCQkJfQoJCQkKCQkKCQkJaWYocVtpXS5sY2EgIT0gLTEgJiYgY250W3dbcVtpXS5sY2FdXSA9PSAwKQoJCQl7CgkJCQlhbnNbcVtpXS5pXSA9IHN1bSsxOwoJCQl9CgkJCWVsc2UKCQkJewoJCQkJYW5zW3FbaV0uaV0gPSBzdW07CgkJCX0KCQkJCgkJfQoJCWZvcihpbnQgaT0wOyBpPG07IGkrKykKCQkJc2IuYXBwZW5kKGFuc1tpXSsiXG4iKTsKCQkKCQlTeXN0ZW0ub3V0LnByaW50bG4oc2IudG9TdHJpbmcoKSk7CgkJCgl9CglzdGF0aWMgdm9pZCByZW1vdmUoaW50IHgpCgl7CQoJCQoJCWludCB3dCA9IHdbeF07CgkJb2NjW3hdLS07CgkJCgkJaWYgKG9jY1t4XSA9PSAxKXsKCQkJY250W3d0XSsrOwoJCQlpZiAoY250W3d0XSA9PSAxKQoJCQkJc3VtKys7CgkJCXJldHVybjsKCQl9CgkJY250W3d0XS0tOwoJCWlmIChjbnRbd3RdID09IDApIHN1bS0tOwoJCQoJfQoJc3RhdGljIHZvaWQgYWRkKGludCB4KQoJewkKCQkKCQlvY2NbeF0rKzsKCQljbnRbd1t4XV0rKzsKCQlpZiAob2NjW3hdID09IDIpewoJCQljbnRbd1t4XV0gLT0gMjsKCQkJaWYgKGNudFt3W3hdXSA9PSAwKQoJCQkJc3VtLS07CgkJfQoJCWVsc2UgaWYgKGNudFt3W3hdXSA9PSAxKSBzdW0rKzsKCQkKCQoJfQoJCglzdGF0aWMgY2xhc3MgUXVlcnl7CgkJaW50IGwscixpLGxjYTsKCQkKCQlRdWVyeShpbnQgbCxpbnQgcixpbnQgaSxpbnQgbGNhKQoJCXsKCQkJdGhpcy5sY2EgPSBsY2E7CgkJCXRoaXMubCA9IGw7CgkJCXRoaXMuciA9IHI7CgkJCXRoaXMuaSA9IGk7CgkJfQoJfQoJCglzdGF0aWMgaW50IGxjYShpbnQgdSxpbnQgdikKCXsKCQlpbnQgbGcsIGk7CgkJZm9yIChsZyA9IDA7ICgxPDxsZykgPD0gZGVwdGhbdV07IGxnKyspOwoJCWxnLS07CgkJZm9yKGk9bGc7IGk+PTA7IGktLSkKCQkJaWYgKCBkZXB0aFt1XSAtICgxPDxpKSA+PSBkZXB0aFt2XSkKCQkJCXUgPSBwYXJbdV1baV07CgkJaWYgKHUgPT0gdikKCQkJcmV0dXJuIHU7CgkJZm9yKGkgPSBsZzsgaSA+PSAwOyBpLS0pewoJCQlpZiAocGFyW3VdW2ldICE9IC0xICYmIHBhclt1XVtpXSAhPSBwYXJbdl1baV0pCgkJCXsJdSA9IHBhclt1XVtpXTsgdiA9IHBhclt2XVtpXTt9CgkJfQoJCXJldHVybiBwYXJbdV1bMF07Cgl9CgkKCXN0YXRpYyB2b2lkIGRmcyhpbnQgY3VycixpbnQgcHJldikKCXsKCQlzdFtjdXJyXSA9ICsrdGltZTsKCQlhW3RpbWVdID0gY3VycjsKCQkKCQkKCQkKCQlmb3IoaW50IGk9MDsgaTxhZGpbY3Vycl0uc2l6ZSgpOyBpKyspCgkJewoJCQlpbnQgbmV4dCA9IGFkaltjdXJyXS5nZXQoaSk7CgkJCWlmKG5leHQgIT0gcHJldikKCQkJCXsKCQkJCWRlcHRoW25leHRdID0gZGVwdGhbY3Vycl0rMTsKCQkJCXBhcltuZXh0XVswXSA9IGN1cnI7CgkJCQlkZnMobmV4dCxjdXJyKTsKCQkJCX0KCQl9CgkJCgkJZXRbY3Vycl0gPSArK3RpbWU7CgkJYVt0aW1lXSA9IGN1cnI7CgkJCgl9CgkKCQoJc3RhdGljIGRvdWJsZSBkaXN0KGRvdWJsZSB4MSxkb3VibGUgeTEsZG91YmxlIHgyLGRvdWJsZSB5MikKCXsKCQlyZXR1cm4gTWF0aC5zcXJ0KCh4MS14MikqKHgxLXgyKSArICh5MS15MikqKHkxLXkyKSk7CgkJCgl9CglzdGF0aWMgbG9uZyBtb2Rwb3dJdGVyKGxvbmcgYSwgbG9uZyBiLCBsb25nIGMpIHsKICAgICAgICBsb25nIGFucz0xOwogICAgICAgIHdoaWxlKGIgIT0gMCkgewogICAgICAgICAgICAgICAgaWYoYiUyID09IDEpCiAgICAgICAgICAgICAgICAgICAgICAgIGFucz0oYW5zKmEpJWM7CiAKICAgICAgICAgICAgICAgIGE9KGEqYSklYzsKICAgICAgICAgICAgICAgIGIgLz0gMjsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIGFuczsKfQogCnN0YXRpYyBpbnQgZ2NkKGludCBhLGludCBiKQp7CglpZihiID09IDApCgkJcmV0dXJuIGE7CgllbHNlIHJldHVybiBnY2QoYixhJWIpOwp9CnN0YXRpYyBpbnQgbGNtKGludCBhLCBpbnQgYikKewoJCglyZXR1cm4gKGEqYikvZ2NkKGEsYik7Cn0KCSBzdGF0aWMgY2xhc3MgUmVhZGVyCgkgICAgewoJICAgICAgICBmaW5hbCBwcml2YXRlIGludCBCVUZGRVJfU0laRSA9IDEgPDwgMTY7CgkgICAgICAgIHByaXZhdGUgRGF0YUlucHV0U3RyZWFtIGRpbjsKCSAgICAgICAgcHJpdmF0ZSBieXRlW10gYnVmZmVyOwoJICAgICAgICBwcml2YXRlIGludCBidWZmZXJQb2ludGVyLCBieXRlc1JlYWQ7CgkgCgkgICAgICAgIHB1YmxpYyBSZWFkZXIoKQoJICAgICAgICB7CgkgICAgICAgICAgICBkaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKFN5c3RlbS5pbik7CgkgICAgICAgICAgICBidWZmZXIgPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CgkgICAgICAgICAgICBidWZmZXJQb2ludGVyID0gYnl0ZXNSZWFkID0gMDsKCSAgICAgICAgfQoJIAoJICAgICAgICBwdWJsaWMgUmVhZGVyKFN0cmluZyBmaWxlX25hbWUpIHRocm93cyBJT0V4Y2VwdGlvbgoJICAgICAgICB7CgkgICAgICAgICAgICBkaW4gPSBuZXcgRGF0YUlucHV0U3RyZWFtKG5ldyBGaWxlSW5wdXRTdHJlYW0oZmlsZV9uYW1lKSk7CgkgICAgICAgICAgICBidWZmZXIgPSBuZXcgYnl0ZVtCVUZGRVJfU0laRV07CgkgICAgICAgICAgICBidWZmZXJQb2ludGVyID0gYnl0ZXNSZWFkID0gMDsKCSAgICAgICAgfQoJIAoJICAgICAgICBwdWJsaWMgU3RyaW5nIHJlYWRMaW5lKCkgdGhyb3dzIElPRXhjZXB0aW9uCgkgICAgICAgIHsKCSAgICAgICAgICAgIGJ5dGVbXSBidWYgPSBuZXcgYnl0ZVs2NF07IC8vIGxpbmUgbGVuZ3RoCgkgICAgICAgICAgICBpbnQgY250ID0gMCwgYzsKCSAgICAgICAgICAgIHdoaWxlICgoYyA9IHJlYWQoKSkgIT0gLTEpCgkgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgaWYgKGMgPT0gJ1xuJykKCSAgICAgICAgICAgICAgICAgICAgYnJlYWs7CgkgICAgICAgICAgICAgICAgYnVmW2NudCsrXSA9IChieXRlKSBjOwoJICAgICAgICAgICAgfQoJICAgICAgICAgICAgcmV0dXJuIG5ldyBTdHJpbmcoYnVmLCAwLCBjbnQpOwoJICAgICAgICB9CgkgCgkgICAgICAgIHB1YmxpYyBpbnQgbmV4dEludCgpIHRocm93cyBJT0V4Y2VwdGlvbgoJICAgICAgICB7CgkgICAgICAgICAgICBpbnQgcmV0ID0gMDsKCSAgICAgICAgICAgIGJ5dGUgYyA9IHJlYWQoKTsKCSAgICAgICAgICAgIHdoaWxlIChjIDw9ICcgJykKCSAgICAgICAgICAgICAgICBjID0gcmVhZCgpOwoJICAgICAgICAgICAgYm9vbGVhbiBuZWcgPSAoYyA9PSAnLScpOwoJICAgICAgICAgICAgaWYgKG5lZykKCSAgICAgICAgICAgICAgICBjID0gcmVhZCgpOwoJICAgICAgICAgICAgZG8KCSAgICAgICAgICAgIHsKCSAgICAgICAgICAgICAgICByZXQgPSByZXQgKiAxMCArIGMgLSAnMCc7CgkgICAgICAgICAgICB9ICB3aGlsZSAoKGMgPSByZWFkKCkpID49ICcwJyAmJiBjIDw9ICc5Jyk7CgkgCgkgICAgICAgICAgICBpZiAobmVnKQoJICAgICAgICAgICAgICAgIHJldHVybiAtcmV0OwoJICAgICAgICAgICAgcmV0dXJuIHJldDsKCSAgICAgICAgfQoJIAoJICAgICAgICBwdWJsaWMgbG9uZyBuZXh0TG9uZygpIHRocm93cyBJT0V4Y2VwdGlvbgoJICAgICAgICB7CgkgICAgICAgICAgICBsb25nIHJldCA9IDA7CgkgICAgICAgICAgICBieXRlIGMgPSByZWFkKCk7CgkgICAgICAgICAgICB3aGlsZSAoYyA8PSAnICcpCgkgICAgICAgICAgICAgICAgYyA9IHJlYWQoKTsKCSAgICAgICAgICAgIGJvb2xlYW4gbmVnID0gKGMgPT0gJy0nKTsKCSAgICAgICAgICAgIGlmIChuZWcpCgkgICAgICAgICAgICAgICAgYyA9IHJlYWQoKTsKCSAgICAgICAgICAgIGRvIHsKCSAgICAgICAgICAgICAgICByZXQgPSByZXQgKiAxMCArIGMgLSAnMCc7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB3aGlsZSAoKGMgPSByZWFkKCkpID49ICcwJyAmJiBjIDw9ICc5Jyk7CgkgICAgICAgICAgICBpZiAobmVnKQoJICAgICAgICAgICAgICAgIHJldHVybiAtcmV0OwoJICAgICAgICAgICAgcmV0dXJuIHJldDsKCSAgICAgICAgfQoJIAoJICAgICAgICBwdWJsaWMgZG91YmxlIG5leHREb3VibGUoKSB0aHJvd3MgSU9FeGNlcHRpb24KCSAgICAgICAgewoJICAgICAgICAgICAgZG91YmxlIHJldCA9IDAsIGRpdiA9IDE7CgkgICAgICAgICAgICBieXRlIGMgPSByZWFkKCk7CgkgICAgICAgICAgICB3aGlsZSAoYyA8PSAnICcpCgkgICAgICAgICAgICAgICAgYyA9IHJlYWQoKTsKCSAgICAgICAgICAgIGJvb2xlYW4gbmVnID0gKGMgPT0gJy0nKTsKCSAgICAgICAgICAgIGlmIChuZWcpCgkgICAgICAgICAgICAgICAgYyA9IHJlYWQoKTsKCSAKCSAgICAgICAgICAgIGRvIHsKCSAgICAgICAgICAgICAgICByZXQgPSByZXQgKiAxMCArIGMgLSAnMCc7CgkgICAgICAgICAgICB9CgkgICAgICAgICAgICB3aGlsZSAoKGMgPSByZWFkKCkpID49ICcwJyAmJiBjIDw9ICc5Jyk7CgkgCgkgICAgICAgICAgICBpZiAoYyA9PSAnLicpCgkgICAgICAgICAgICB7CgkgICAgICAgICAgICAgICAgd2hpbGUgKChjID0gcmVhZCgpKSA+PSAnMCcgJiYgYyA8PSAnOScpCgkgICAgICAgICAgICAgICAgewoJICAgICAgICAgICAgICAgICAgICByZXQgKz0gKGMgLSAnMCcpIC8gKGRpdiAqPSAxMCk7CgkgICAgICAgICAgICAgICAgfQoJICAgICAgICAgICAgfQoJIAoJICAgICAgICAgICAgaWYgKG5lZykKCSAgICAgICAgICAgICAgICByZXR1cm4gLXJldDsKCSAgICAgICAgICAgIHJldHVybiByZXQ7CgkgICAgICAgIH0KCSAKCSAgICAgICAgcHJpdmF0ZSB2b2lkIGZpbGxCdWZmZXIoKSB0aHJvd3MgSU9FeGNlcHRpb24KCSAgICAgICAgewoJICAgICAgICAgICAgYnl0ZXNSZWFkID0gZGluLnJlYWQoYnVmZmVyLCBidWZmZXJQb2ludGVyID0gMCwgQlVGRkVSX1NJWkUpOwoJICAgICAgICAgICAgaWYgKGJ5dGVzUmVhZCA9PSAtMSkKCSAgICAgICAgICAgICAgICBidWZmZXJbMF0gPSAtMTsKCSAgICAgICAgfQoJIAoJICAgICAgICBwcml2YXRlIGJ5dGUgcmVhZCgpIHRocm93cyBJT0V4Y2VwdGlvbgoJICAgICAgICB7CgkgICAgICAgICAgICBpZiAoYnVmZmVyUG9pbnRlciA9PSBieXRlc1JlYWQpCgkgICAgICAgICAgICAgICAgZmlsbEJ1ZmZlcigpOwoJICAgICAgICAgICAgcmV0dXJuIGJ1ZmZlcltidWZmZXJQb2ludGVyKytdOwoJICAgICAgICB9CgkgCgkgICAgICAgIHB1YmxpYyB2b2lkIGNsb3NlKCkgdGhyb3dzIElPRXhjZXB0aW9uCgkgICAgICAgIHsKCSAgICAgICAgICAgIGlmIChkaW4gPT0gbnVsbCkKCSAgICAgICAgICAgICAgICByZXR1cm47CgkgICAgICAgICAgICBkaW4uY2xvc2UoKTsKCSAgICAgICAgfQoJICAgIH0KfSAgICAgICAgICAg