import java.io.* ;
import java.util.* ;
public class TaskE {
private final InputReader reader;
private final OutputWriter writer;
public TaskE( InputReader reader, OutputWriter writer) {
this .reader = reader;
this .writer = writer;
}
public static void main
( String [ ] args
) { InputReader reader
= new InputReader
( System .
in ) ; OutputWriter writer
= new OutputWriter
( System .
out ) ; new TaskE( reader, writer) .run ( ) ;
writer.writer .flush ( ) ;
}
int [ ] F;
class Edge implements Comparable< Edge> {
int a, b, l;
Edge( int a, int b, int l) {
this .a = a;
this .b = b;
this .l = l;
}
@Override
public int compareTo( Edge other) {
return - Integer .
compare ( this .
l , other.
l ) ; }
}
List< Integer> [ ] E;
class Node {
int l, r, sum;
boolean whole;
Node( int v) {
if ( v == 0 ) {
l = r = sum = 0 ;
whole = false ;
} else {
l = r = 1 ;
sum = 0 ;
whole = true ;
}
}
Node( int l, int r, int sum, boolean whole) {
this .l = l;
this .r = r;
this .sum = sum;
this .whole = whole;
}
Node reverse( ) {
return new Node( r, l, sum, whole) ;
}
int value( ) {
if ( whole)
return F[ l] ; //!
else
return F[ l] + F[ r] + sum;
}
}
Node combine( Node a, Node b) {
if ( a == null )
return b;
if ( b == null )
return a;
if ( a.whole && b.whole )
return new Node( a.l + b.l , a.r + b.r , a.sum + b.sum , true ) ;
if ( a.whole && ! b.whole )
return new Node( a.l + b.l , b.r , a.sum + b.sum , false ) ;
if ( ! a.whole && b.whole )
return new Node( a.l , a.r + b.r , a.sum + b.sum , false ) ;
return new Node( a.l , b.r , a.sum + b.sum + F[ a.r + b.l ] , false ) ;
}
class SegmentTree {
int N;
Node[ ] T;
SegmentTree( int n) {
N = 1 ;
while ( N < n)
N <<= 1 ;
T = new Node[ 2 * N] ;
for ( int i = N + n - 1 ; i >= N; i-- )
T[ i] = new Node( 0 ) ;
for ( int i = N - 1 ; i > 0 ; i-- )
T[ i] = combine( T[ 2 * i] , T[ 2 * i + 1 ] ) ;
}
void set( int x, int i) {
x += N;
T[ x] = new Node( i) ;
for ( x >>= 1 ; x > 0 ; x >>= 1 )
T[ x] = combine( T[ 2 * x] , T[ 2 * x + 1 ] ) ;
}
Node get( int l, int r) {
Node resl = null , resr = null ;
l += N;
r += N;
while ( l <= r) {
if ( ( l & 1 ) == 1 )
resl = combine( resl, T[ l] ) ;
if ( ( r & 1 ) == 0 )
resr = combine( T[ r] , resr) ;
l = ( l + 1 ) >> 1 ;
r = ( r - 1 ) >> 1 ;
}
return combine( resl, resr) ;
}
}
int lgn;
int [ ] [ ] up;
int [ ] S;
int [ ] to;
int [ ] D;
void DFS1( int x, int p) {
up[ 0 ] [ x] = p;
for ( int d = 1 ; d < lgn; d++ )
up[ d] [ x] = up[ d - 1 ] [ up[ d - 1 ] [ x] ] ;
S[ x] = 1 ;
to[ x] = - 1 ;
for ( int i = 0 ; i < E[ x] .size ( ) ; i++ ) {
int y = E[ x] .get ( i) ;
if ( y == p) {
E[ x] .set ( i, E[ x] .get ( E[ x] .size ( ) - 1 ) ) ;
E[ x] .remove ( E[ x] .size ( ) - 1 ) ;
-- i;
continue ;
}
D[ y] = D[ x] + 1 ;
DFS1( y, x) ;
S[ x] += y;
}
int mxs = - 1 ;
for ( int i = 0 ; i < E[ x] .size ( ) ; i++ ) {
int y = E[ x] .get ( i) ;
if ( mxs == - 1 || S[ mxs] < S[ y] )
mxs = y;
}
to[ x] = mxs;
}
SegmentTree[ ] ST;
int [ ] ind;
int [ ] top;
void DFS2( int x) {
if ( to[ x] == - 1 ) {
ST[ x] = new SegmentTree( ind[ x] + 1 ) ;
} else {
ind[ to[ x] ] = ind[ x] + 1 ;
top[ to[ x] ] = top[ x] ;
}
for ( int y : E[ x] ) {
if ( y != to[ x] )
top[ y] = y;
}
for ( int y : E[ x] ) {
DFS2( y) ;
}
if ( to[ x] != - 1 ) {
ST[ x] = ST[ to[ x] ] ;
}
}
int lca( int a, int b) {
if ( D[ a] > D[ b] ) {
int t = a;
a = b;
b = t;
}
for ( int d = lgn - 1 ; d >= 0 ; d-- ) {
if ( D[ b] - ( 1 << d) >= D[ a] )
b = up[ d] [ b] ;
}
if ( a == b)
return a;
for ( int d = lgn - 1 ; d >= 0 ; d-- ) {
if ( up[ d] [ a] != up[ d] [ b] ) {
a = up[ d] [ a] ;
b = up[ d] [ b] ;
}
}
if ( a == b)
throw new AssertionError( ) ;
if ( up[ 0 ] [ a] != up[ 0 ] [ b] )
throw new AssertionError( ) ;
return up[ 0 ] [ a] ;
}
class Query implements Comparable< Query> {
int a, b, x;
int id;
Query( int a, int b, int x, int id) {
this .a = a;
this .b = b;
this .x = x;
this .id = id;
}
@Override
public int compareTo( Query other) {
return - Integer .
compare ( this .
x , other.
x ) ; }
}
Node get( int x, int y) {
Node res = null ;
while ( true ) {
if ( D[ x] < D[ y] )
throw new AssertionError( ) ;
if ( ST[ x] == ST[ y] ) {
res = combine( ST[ x] .get ( ind[ y] + 1 , ind[ x] ) , res) ;
break ;
} else {
res = combine( ST[ x] .get ( 0 , ind[ x] ) , res) ;
x = up[ 0 ] [ top[ x] ] ;
}
}
return res;
}
public void run( ) {
int n = reader.nextInt ( ) ;
int q = reader.nextInt ( ) ;
F = new int [ n] ;
for ( int i = 1 ; i < n; i++ ) {
F[ i] = reader.nextInt ( ) ;
}
Edge[ ] edges = new Edge[ n - 1 ] ;
for ( int i = 0 ; i < n - 1 ; i++ ) {
int a = reader.nextInt ( ) - 1 ;
int b = reader.nextInt ( ) - 1 ;
int l = reader.nextInt ( ) ;
edges[ i] = new Edge( a, b, l) ;
}
for ( int i = 0 ; i < n; i++ )
E[ i] = new ArrayList< Integer> ( 1 ) ;
for ( Edge e : edges) {
E[ e.a ] .add ( e.b ) ;
E[ e.b ] .add ( e.a ) ;
}
while ( ( 1 << lgn) < n + 1 )
++ lgn;
up = new int [ lgn] [ n] ;
S = new int [ n] ;
to = new int [ n] ;
D = new int [ n] ;
DFS1( 0 , 0 ) ;
ST = new SegmentTree[ n] ;
ind = new int [ n] ;
top = new int [ n] ;
DFS2( 0 ) ;
Query[ ] Q = new Query[ q] ;
for ( int i = 0 ; i < q; i++ ) {
int a = reader.nextInt ( ) - 1 ;
int b = reader.nextInt ( ) - 1 ;
int l = reader.nextInt ( ) ;
Q[ i] = new Query( a, b, l, i) ;
}
int pte = 0 ;
int [ ] Ans = new int [ q] ;
for ( Query query : Q) {
while ( pte != edges.length && edges[ pte] .l >= query.x ) {
int a = edges[ pte] .a ;
int b = edges[ pte] .b ;
if ( up[ 0 ] [ b] == a) {
int t = b;
b = a;
a = t;
} else if ( up[ 0 ] [ a] != b)
throw new AssertionError( ) ;
ST[ a] .set ( ind[ a] , 1 ) ;
pte++;
}
int a = query.a ;
int b = query.b ;
int l = lca( a, b) ;
Node u = get( a, l) ;
Node v = get( b, l) ;
if ( v != null )
v = v.reverse ( ) ;
Node res = combine( v, u) ;
int ans = ( res == null ) ? 0 : res.value ( ) ; //!
Ans[ query.id ] = ans;
}
for ( int a : Ans)
writer.printf ( "%d\n " , a) ;
}
static class InputReader {
tokenizer = null ;
}
while ( tokenizer == null || ! tokenizer.hasMoreTokens ( ) ) {
try {
}
}
return tokenizer.nextToken ( ) ;
}
public int nextInt( ) {
}
public double nextDouble( ) {
return Double .
parseDouble ( next
( ) ) ; }
public long nextLong( ) {
return Long .
parseLong ( next
( ) ) ; }
}
static class OutputWriter {
}
}
}
}
aW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC4qOwoKcHVibGljIGNsYXNzIFRhc2tFIHsKICAgIHByaXZhdGUgZmluYWwgSW5wdXRSZWFkZXIgcmVhZGVyOwogICAgcHJpdmF0ZSBmaW5hbCBPdXRwdXRXcml0ZXIgd3JpdGVyOwoKICAgIHB1YmxpYyBUYXNrRShJbnB1dFJlYWRlciByZWFkZXIsIE91dHB1dFdyaXRlciB3cml0ZXIpIHsKICAgICAgICB0aGlzLnJlYWRlciA9IHJlYWRlcjsKICAgICAgICB0aGlzLndyaXRlciA9IHdyaXRlcjsKICAgIH0KCiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmdbXSBhcmdzKSB7CiAgICAgICAgSW5wdXRSZWFkZXIgcmVhZGVyID0gbmV3IElucHV0UmVhZGVyKFN5c3RlbS5pbik7CiAgICAgICAgT3V0cHV0V3JpdGVyIHdyaXRlciA9IG5ldyBPdXRwdXRXcml0ZXIoU3lzdGVtLm91dCk7CiAgICAgICAgbmV3IFRhc2tFKHJlYWRlciwgd3JpdGVyKS5ydW4oKTsKICAgICAgICB3cml0ZXIud3JpdGVyLmZsdXNoKCk7CiAgICB9CgogICAgaW50W10gRjsKICAgIGNsYXNzIEVkZ2UgaW1wbGVtZW50cyBDb21wYXJhYmxlPEVkZ2U+IHsKICAgICAgICBpbnQgYSwgYiwgbDsKICAgICAgICBFZGdlKGludCBhLCBpbnQgYiwgaW50IGwpIHsKICAgICAgICAgICAgdGhpcy5hID0gYTsKICAgICAgICAgICAgdGhpcy5iID0gYjsKICAgICAgICAgICAgdGhpcy5sID0gbDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oRWRnZSBvdGhlcikgewogICAgICAgICAgICByZXR1cm4gLUludGVnZXIuY29tcGFyZSh0aGlzLmwsIG90aGVyLmwpOwogICAgICAgIH0KICAgIH0KCiAgICBMaXN0PEludGVnZXI+W10gRTsKCiAgICBjbGFzcyBOb2RlIHsKICAgICAgICBpbnQgbCwgciwgc3VtOwogICAgICAgIGJvb2xlYW4gd2hvbGU7CiAgICAgICAgTm9kZShpbnQgdikgewogICAgICAgICAgICBpZiAodiA9PSAwKSB7CiAgICAgICAgICAgICAgICBsID0gciA9IHN1bSA9IDA7CiAgICAgICAgICAgICAgICB3aG9sZSA9IGZhbHNlOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgbCA9IHIgPSAxOwogICAgICAgICAgICAgICAgc3VtID0gMDsKICAgICAgICAgICAgICAgIHdob2xlID0gdHJ1ZTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBOb2RlKGludCBsLCBpbnQgciwgaW50IHN1bSwgYm9vbGVhbiB3aG9sZSkgewogICAgICAgICAgICB0aGlzLmwgPSBsOwogICAgICAgICAgICB0aGlzLnIgPSByOwogICAgICAgICAgICB0aGlzLnN1bSA9IHN1bTsKICAgICAgICAgICAgdGhpcy53aG9sZSA9IHdob2xlOwogICAgICAgIH0KICAgICAgICBOb2RlIHJldmVyc2UoKSB7CiAgICAgICAgICAgIHJldHVybiBuZXcgTm9kZShyLCBsLCBzdW0sIHdob2xlKTsKICAgICAgICB9CiAgICAgICAgaW50IHZhbHVlKCkgewogICAgICAgICAgICBpZiAod2hvbGUpCiAgICAgICAgICAgICAgICByZXR1cm4gRltsXTsgLy8hCiAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgIHJldHVybiBGW2xdICsgRltyXSArIHN1bTsKICAgICAgICB9CiAgICB9CgogICAgTm9kZSBjb21iaW5lKE5vZGUgYSwgTm9kZSBiKSB7CiAgICAgICAgaWYgKGEgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGI7CiAgICAgICAgaWYgKGIgPT0gbnVsbCkKICAgICAgICAgICAgcmV0dXJuIGE7CiAgICAgICAgaWYgKGEud2hvbGUgJiYgYi53aG9sZSkKICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlKGEubCArIGIubCwgYS5yICsgYi5yLCBhLnN1bSArIGIuc3VtLCB0cnVlKTsKICAgICAgICBpZiAoYS53aG9sZSAmJiAhYi53aG9sZSkKICAgICAgICAgICAgcmV0dXJuIG5ldyBOb2RlKGEubCArIGIubCwgYi5yLCBhLnN1bSArIGIuc3VtLCBmYWxzZSk7CiAgICAgICAgaWYgKCFhLndob2xlICYmIGIud2hvbGUpCiAgICAgICAgICAgIHJldHVybiBuZXcgTm9kZShhLmwsIGEuciArIGIuciwgYS5zdW0gKyBiLnN1bSwgZmFsc2UpOwogICAgICAgIHJldHVybiBuZXcgTm9kZShhLmwsIGIuciwgYS5zdW0gKyBiLnN1bSArIEZbYS5yICsgYi5sXSwgZmFsc2UpOwogICAgfQoKICAgIGNsYXNzIFNlZ21lbnRUcmVlIHsKICAgICAgICBpbnQgTjsKICAgICAgICBOb2RlW10gVDsKICAgICAgICBTZWdtZW50VHJlZShpbnQgbikgewogICAgICAgICAgICBOID0gMTsKICAgICAgICAgICAgd2hpbGUgKE4gPCBuKQogICAgICAgICAgICAgICAgIE4gPDw9IDE7CiAgICAgICAgICAgIFQgPSBuZXcgTm9kZVsyICogTl07CiAgICAgICAgICAgIGZvciAoaW50IGkgPSBOICsgbiAtIDE7IGkgPj0gTjsgaS0tKQogICAgICAgICAgICAgICAgVFtpXSA9IG5ldyBOb2RlKDApOwogICAgICAgICAgICBmb3IgKGludCBpID0gTiAtIDE7IGkgPiAwOyBpLS0pCiAgICAgICAgICAgICAgICBUW2ldID0gY29tYmluZShUWzIgKiBpXSwgVFsyICogaSArIDFdKTsKICAgICAgICB9CiAgICAgICAgdm9pZCBzZXQoaW50IHgsIGludCBpKSB7CiAgICAgICAgICAgIHggKz0gTjsKICAgICAgICAgICAgVFt4XSA9IG5ldyBOb2RlKGkpOwogICAgICAgICAgICBmb3IgKHggPj49IDE7IHggPiAwOyB4ID4+PSAxKQogICAgICAgICAgICAgICAgVFt4XSA9IGNvbWJpbmUoVFsyICogeF0sIFRbMiAqIHggKyAxXSk7CiAgICAgICAgfQogICAgICAgIE5vZGUgZ2V0KGludCBsLCBpbnQgcikgewogICAgICAgICAgICBOb2RlIHJlc2wgPSBudWxsLCByZXNyID0gbnVsbDsKICAgICAgICAgICAgbCArPSBOOwogICAgICAgICAgICByICs9IE47CiAgICAgICAgICAgIHdoaWxlIChsIDw9IHIpIHsKICAgICAgICAgICAgICAgIGlmICgobCAmIDEpID09IDEpCiAgICAgICAgICAgICAgICAgICAgcmVzbCA9IGNvbWJpbmUocmVzbCwgVFtsXSk7CiAgICAgICAgICAgICAgICBpZiAoKHIgJiAxKSA9PSAwKQogICAgICAgICAgICAgICAgICAgIHJlc3IgPSBjb21iaW5lKFRbcl0sIHJlc3IpOwogICAgICAgICAgICAgICAgbCA9IChsICsgMSkgPj4gMTsKICAgICAgICAgICAgICAgIHIgPSAociAtIDEpID4+IDE7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIGNvbWJpbmUocmVzbCwgcmVzcik7CiAgICAgICAgfQogICAgfQoKICAgIGludCBsZ247CiAgICBpbnRbXVtdIHVwOwogICAgaW50W10gUzsKICAgIGludFtdIHRvOwogICAgaW50W10gRDsKICAgIHZvaWQgREZTMShpbnQgeCwgaW50IHApIHsKICAgICAgICB1cFswXVt4XSA9IHA7CiAgICAgICAgZm9yIChpbnQgZCA9IDE7IGQgPCBsZ247IGQrKykKICAgICAgICAgICAgdXBbZF1beF0gPSB1cFtkIC0gMV1bdXBbZCAtIDFdW3hdXTsKICAgICAgICBTW3hdID0gMTsKICAgICAgICB0b1t4XSA9IC0xOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRVt4XS5zaXplKCk7IGkrKykgewogICAgICAgICAgICBpbnQgeSA9IEVbeF0uZ2V0KGkpOwogICAgICAgICAgICBpZiAoeSA9PSBwKSB7CiAgICAgICAgICAgICAgICBFW3hdLnNldChpLCBFW3hdLmdldChFW3hdLnNpemUoKSAtIDEpKTsKICAgICAgICAgICAgICAgIEVbeF0ucmVtb3ZlKEVbeF0uc2l6ZSgpIC0gMSk7CiAgICAgICAgICAgICAgICAtLWk7CiAgICAgICAgICAgICAgICBjb250aW51ZTsKICAgICAgICAgICAgfQogICAgICAgICAgICBEW3ldID0gRFt4XSArIDE7CiAgICAgICAgICAgIERGUzEoeSwgeCk7CiAgICAgICAgICAgIFNbeF0gKz0geTsKICAgICAgICB9CiAgICAgICAgaW50IG14cyA9IC0xOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgRVt4XS5zaXplKCk7IGkrKykgewogICAgICAgICAgICBpbnQgeSA9IEVbeF0uZ2V0KGkpOwogICAgICAgICAgICBpZiAobXhzID09IC0xIHx8IFNbbXhzXSA8IFNbeV0pCiAgICAgICAgICAgICAgICBteHMgPSB5OwogICAgICAgIH0KICAgICAgICB0b1t4XSA9IG14czsKICAgIH0KCiAgICBTZWdtZW50VHJlZVtdIFNUOwogICAgaW50W10gaW5kOwogICAgaW50W10gdG9wOwogICAgdm9pZCBERlMyKGludCB4KSB7CiAgICAgICAgaWYgKHRvW3hdID09IC0xKSB7CiAgICAgICAgICAgIFNUW3hdID0gbmV3IFNlZ21lbnRUcmVlKGluZFt4XSArIDEpOwogICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgIGluZFt0b1t4XV0gPSBpbmRbeF0gKyAxOwogICAgICAgICAgICB0b3BbdG9beF1dID0gdG9wW3hdOwogICAgICAgIH0KICAgICAgICBmb3IgKGludCB5IDogRVt4XSkgewogICAgICAgICAgICBpZiAoeSAhPSB0b1t4XSkKICAgICAgICAgICAgICAgIHRvcFt5XSA9IHk7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IHkgOiBFW3hdKSB7CiAgICAgICAgICAgIERGUzIoeSk7CiAgICAgICAgfQogICAgICAgIGlmICh0b1t4XSAhPSAtMSkgewogICAgICAgICAgICBTVFt4XSA9IFNUW3RvW3hdXTsKICAgICAgICB9CiAgICB9CgogICAgaW50IGxjYShpbnQgYSwgaW50IGIpIHsKICAgICAgICBpZiAoRFthXSA+IERbYl0pIHsKICAgICAgICAgICAgaW50IHQgPSBhOwogICAgICAgICAgICBhID0gYjsKICAgICAgICAgICAgYiA9IHQ7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGQgPSBsZ24gLSAxOyBkID49IDA7IGQtLSkgewogICAgICAgICAgICBpZiAoRFtiXSAtICgxIDw8IGQpID49IERbYV0pCiAgICAgICAgICAgICAgICBiID0gdXBbZF1bYl07CiAgICAgICAgfQogICAgICAgIGlmIChhID09IGIpCiAgICAgICAgICAgIHJldHVybiBhOwogICAgICAgIGZvciAoaW50IGQgPSBsZ24gLSAxOyBkID49IDA7IGQtLSkgewogICAgICAgICAgICBpZiAodXBbZF1bYV0gIT0gdXBbZF1bYl0pIHsKICAgICAgICAgICAgICAgIGEgPSB1cFtkXVthXTsKICAgICAgICAgICAgICAgIGIgPSB1cFtkXVtiXTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBpZiAoYSA9PSBiKQogICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgICAgICBpZiAodXBbMF1bYV0gIT0gdXBbMF1bYl0pCiAgICAgICAgICAgIHRocm93IG5ldyBBc3NlcnRpb25FcnJvcigpOwogICAgICAgIHJldHVybiB1cFswXVthXTsKICAgIH0KCiAgICBjbGFzcyBRdWVyeSBpbXBsZW1lbnRzIENvbXBhcmFibGU8UXVlcnk+IHsKICAgICAgICBpbnQgYSwgYiwgeDsKICAgICAgICBpbnQgaWQ7CiAgICAgICAgUXVlcnkoaW50IGEsIGludCBiLCBpbnQgeCwgaW50IGlkKSB7CiAgICAgICAgICAgIHRoaXMuYSA9IGE7CiAgICAgICAgICAgIHRoaXMuYiA9IGI7CiAgICAgICAgICAgIHRoaXMueCA9IHg7CiAgICAgICAgICAgIHRoaXMuaWQgPSBpZDsKICAgICAgICB9CiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGludCBjb21wYXJlVG8oUXVlcnkgb3RoZXIpIHsKICAgICAgICAgICAgcmV0dXJuIC1JbnRlZ2VyLmNvbXBhcmUodGhpcy54LCBvdGhlci54KTsKICAgICAgICB9CiAgICB9CgogICAgTm9kZSBnZXQoaW50IHgsIGludCB5KSB7CiAgICAgICAgTm9kZSByZXMgPSBudWxsOwogICAgICAgIHdoaWxlICh0cnVlKSB7CiAgICAgICAgICAgIGlmIChEW3hdIDwgRFt5XSkKCiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgICAgICAgICAgaWYgKFNUW3hdID09IFNUW3ldKSB7CiAgICAgICAgICAgICAgICByZXMgPSBjb21iaW5lKFNUW3hdLmdldChpbmRbeV0gKyAxLCBpbmRbeF0pLCByZXMpOwogICAgICAgICAgICAgICAgYnJlYWs7CiAgICAgICAgICAgIH0gZWxzZSB7CiAgICAgICAgICAgICAgICByZXMgPSBjb21iaW5lKFNUW3hdLmdldCgwLCBpbmRbeF0pLCByZXMpOwogICAgICAgICAgICAgICAgeCA9IHVwWzBdW3RvcFt4XV07CiAgICAgICAgICAgIH0KICAgICAgICB9CiAgICAgICAgcmV0dXJuIHJlczsKICAgIH0KCiAgICBwdWJsaWMgdm9pZCBydW4oKSB7CiAgICAgICAgaW50IG4gPSByZWFkZXIubmV4dEludCgpOwogICAgICAgIGludCBxID0gcmVhZGVyLm5leHRJbnQoKTsKICAgICAgICBGID0gbmV3IGludFtuXTsKICAgICAgICBmb3IgKGludCBpID0gMTsgaSA8IG47IGkrKykgewogICAgICAgICAgICBGW2ldID0gcmVhZGVyLm5leHRJbnQoKTsKICAgICAgICB9CiAgICAgICAgRWRnZVtdIGVkZ2VzID0gbmV3IEVkZ2VbbiAtIDFdOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbiAtIDE7IGkrKykgewogICAgICAgICAgICBpbnQgYSA9IHJlYWRlci5uZXh0SW50KCkgLSAxOwogICAgICAgICAgICBpbnQgYiA9IHJlYWRlci5uZXh0SW50KCkgLSAxOwogICAgICAgICAgICBpbnQgbCA9IHJlYWRlci5uZXh0SW50KCk7CiAgICAgICAgICAgIGVkZ2VzW2ldID0gbmV3IEVkZ2UoYSwgYiwgbCk7CiAgICAgICAgfQogICAgICAgIEUgPSBuZXcgTGlzdFtuXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykKICAgICAgICAgICAgRVtpXSA9IG5ldyBBcnJheUxpc3Q8SW50ZWdlcj4oMSk7CiAgICAgICAgZm9yIChFZGdlIGUgOiBlZGdlcykgewogICAgICAgICAgICBFW2UuYV0uYWRkKGUuYik7CiAgICAgICAgICAgIEVbZS5iXS5hZGQoZS5hKTsKICAgICAgICB9CiAgICAgICAgd2hpbGUgKCgxIDw8IGxnbikgPCBuICsgMSkKICAgICAgICAgICAgKytsZ247CiAgICAgICAgdXAgPSBuZXcgaW50W2xnbl1bbl07CiAgICAgICAgUyA9IG5ldyBpbnRbbl07CiAgICAgICAgdG8gPSBuZXcgaW50W25dOwogICAgICAgIEQgPSBuZXcgaW50W25dOwogICAgICAgIERGUzEoMCwgMCk7CiAgICAgICAgU1QgPSBuZXcgU2VnbWVudFRyZWVbbl07CiAgICAgICAgaW5kID0gbmV3IGludFtuXTsKICAgICAgICB0b3AgPSBuZXcgaW50W25dOwogICAgICAgIERGUzIoMCk7CiAgICAgICAgUXVlcnlbXSBRID0gbmV3IFF1ZXJ5W3FdOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgcTsgaSsrKSB7CiAgICAgICAgICAgIGludCBhID0gcmVhZGVyLm5leHRJbnQoKSAtIDE7CiAgICAgICAgICAgIGludCBiID0gcmVhZGVyLm5leHRJbnQoKSAtIDE7CiAgICAgICAgICAgIGludCBsID0gcmVhZGVyLm5leHRJbnQoKTsKICAgICAgICAgICAgUVtpXSA9IG5ldyBRdWVyeShhLCBiLCBsLCBpKTsKICAgICAgICB9CiAgICAgICAgQXJyYXlzLnNvcnQoZWRnZXMpOwogICAgICAgIEFycmF5cy5zb3J0KFEpOwogICAgICAgIGludCBwdGUgPSAwOwogICAgICAgIGludFtdIEFucyA9IG5ldyBpbnRbcV07CiAgICAgICAgZm9yIChRdWVyeSBxdWVyeSA6IFEpIHsKICAgICAgICAgICAgd2hpbGUgKHB0ZSAhPSBlZGdlcy5sZW5ndGggJiYgZWRnZXNbcHRlXS5sID49IHF1ZXJ5LngpIHsKICAgICAgICAgICAgICAgIGludCBhID0gZWRnZXNbcHRlXS5hOwogICAgICAgICAgICAgICAgaW50IGIgPSBlZGdlc1twdGVdLmI7CiAgICAgICAgICAgICAgICBpZiAodXBbMF1bYl0gPT0gYSkgewogICAgICAgICAgICAgICAgICAgIGludCB0ID0gYjsKICAgICAgICAgICAgICAgICAgICBiID0gYTsKICAgICAgICAgICAgICAgICAgICBhID0gdDsKICAgICAgICAgICAgICAgIH0gZWxzZSBpZiAodXBbMF1bYV0gIT0gYikKICAgICAgICAgICAgICAgICAgICB0aHJvdyBuZXcgQXNzZXJ0aW9uRXJyb3IoKTsKICAgICAgICAgICAgICAgIFNUW2FdLnNldChpbmRbYV0sIDEpOwogICAgICAgICAgICAgICAgcHRlKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgaW50IGEgPSBxdWVyeS5hOwogICAgICAgICAgICBpbnQgYiA9IHF1ZXJ5LmI7CiAgICAgICAgICAgIGludCBsID0gbGNhKGEsIGIpOwogICAgICAgICAgICBOb2RlIHUgPSBnZXQoYSwgbCk7CiAgICAgICAgICAgIE5vZGUgdiA9IGdldChiLCBsKTsKICAgICAgICAgICAgaWYgKHYgIT0gbnVsbCkKICAgICAgICAgICAgICAgIHYgPSB2LnJldmVyc2UoKTsKICAgICAgICAgICAgTm9kZSByZXMgPSBjb21iaW5lKHYsIHUpOwogICAgICAgICAgICBpbnQgYW5zID0gKHJlcyA9PSBudWxsKSA/IDAgOiByZXMudmFsdWUoKTsgLy8hCiAgICAgICAgICAgIEFuc1txdWVyeS5pZF0gPSBhbnM7CiAgICAgICAgfQogICAgICAgIGZvciAoaW50IGEgOiBBbnMpCiAgICAgICAgICAgIHdyaXRlci5wcmludGYoIiVkXG4iLCBhKTsKICAgIH0KCgogICAgc3RhdGljIGNsYXNzIElucHV0UmVhZGVyIHsKICAgICAgICBwdWJsaWMgQnVmZmVyZWRSZWFkZXIgcmVhZGVyOwogICAgICAgIHB1YmxpYyBTdHJpbmdUb2tlbml6ZXIgdG9rZW5pemVyOwoKICAgICAgICBwdWJsaWMgSW5wdXRSZWFkZXIoSW5wdXRTdHJlYW0gc3RyZWFtKSB7CiAgICAgICAgICAgIHJlYWRlciA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgSW5wdXRTdHJlYW1SZWFkZXIoc3RyZWFtKSwgMzI3NjgpOwogICAgICAgICAgICB0b2tlbml6ZXIgPSBudWxsOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIFN0cmluZyBuZXh0KCkgewogICAgICAgICAgICB3aGlsZSAodG9rZW5pemVyID09IG51bGwgfHwgIXRva2VuaXplci5oYXNNb3JlVG9rZW5zKCkpIHsKICAgICAgICAgICAgICAgIHRyeSB7CiAgICAgICAgICAgICAgICAgICAgdG9rZW5pemVyID0gbmV3IFN0cmluZ1Rva2VuaXplcihyZWFkZXIucmVhZExpbmUoKSk7CiAgICAgICAgICAgICAgICB9IGNhdGNoIChJT0V4Y2VwdGlvbiBlKSB7CiAgICAgICAgICAgICAgICAgICAgdGhyb3cgbmV3IFJ1bnRpbWVFeGNlcHRpb24oZSk7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0KICAgICAgICAgICAgcmV0dXJuIHRva2VuaXplci5uZXh0VG9rZW4oKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBpbnQgbmV4dEludCgpIHsKICAgICAgICAgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQobmV4dCgpKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyBkb3VibGUgbmV4dERvdWJsZSgpIHsKICAgICAgICAgICAgcmV0dXJuIERvdWJsZS5wYXJzZURvdWJsZShuZXh0KCkpOwogICAgICAgIH0KCiAgICAgICAgcHVibGljIGxvbmcgbmV4dExvbmcoKSB7CiAgICAgICAgICAgIHJldHVybiBMb25nLnBhcnNlTG9uZyhuZXh0KCkpOwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgT3V0cHV0V3JpdGVyIHsKICAgICAgICBwdWJsaWMgUHJpbnRXcml0ZXIgd3JpdGVyOwoKICAgICAgICBPdXRwdXRXcml0ZXIoT3V0cHV0U3RyZWFtIHN0cmVhbSkgewogICAgICAgICAgICB3cml0ZXIgPSBuZXcgUHJpbnRXcml0ZXIoc3RyZWFtKTsKICAgICAgICB9CgogICAgICAgIHB1YmxpYyB2b2lkIHByaW50ZihTdHJpbmcgZm9ybWF0LCBPYmplY3QuLi4gYXJncykgewogICAgICAgICAgICB3cml0ZXIucHJpbnQoU3RyaW5nLmZvcm1hdChMb2NhbGUuRU5HTElTSCwgZm9ybWF0LCBhcmdzKSk7CiAgICAgICAgfQogICAgfQp9Cg==