import java.io.* ;
import java.util.* ;
import static java.
lang .
Double .
parseDouble ; import static java.
lang .
Integer .
parseInt ; import static java.
lang .
Long .
parseLong ; import static java.
lang .
System .
exit ;
public class Main {
static boolean isLocal = false ;
class Item {
int cost;
int value;
int id;
public Item
( String color,
int cost,
int value,
int id
) { this .color = color;
this .cost = cost;
this .value = value;
this .id = id;
}
}
int n, dp_1 = - 1000000 ;
int budget;
Item[ ] items;
boolean checkMax( int numW, int numBlue, int numR, int numBlack) {
return numW <= 1 && numBlue <= 5 && numR <= 5 && numBlack <= 3 ;
}
boolean checkMin( int numW, int numBlue, int numR, int numBlack) {
return numW == 1 && numBlue >= 3 && numR >= 3 && numBlack >= 1 ;
}
boolean canAddItem( Item item, int numW, int numBlue, int numR, int numBlack, int currSpent) {
if ( item.color .equals ( "W" ) ) numW++;
if ( item.color .equals ( "Blue" ) ) numBlue++;
if ( item.color .equals ( "R" ) ) numR++;
if ( item.color .equals ( "Black" ) ) numBlack++;
currSpent += item.cost ;
return checkMax( numW, numBlue, numR, numBlack) && currSpent <= budget && numW + numBlue + numR + numBlack <= 12 ;
}
int dp[ ] [ ] [ ] [ ] [ ] [ ] ;
int go( int i, int numW, int numBlue, int numR, int numBlack, int currSpent) {
if ( n - i + numW + numBlue + numR + numBlack < 12 ) return - 10000 ;
if ( i == n)
return ( checkMin( numW, numBlue, numR, numBlack) && numW + numBlue + numR + numBlack == 12 ) ? 0 : - 10000 ;
// if (dp[numW][numBlack][numR][numBlue][i][currSpent] != dp_1)
// return dp[numW][numBlack][numR][numBlue][i][currSpent];
int res = - 10000 ;
res = max( res, go( ( int ) ( i + 1 ) , numW, numBlue, numR, numBlack, currSpent) ) ;
if ( canAddItem( items[ i] , numW, numBlue, numR, numBlack, currSpent) ) {
if ( items[ i] .color .equals ( "W" ) ) numW++;
if ( items[ i] .color .equals ( "Blue" ) ) numBlue++;
if ( items[ i] .color .equals ( "R" ) ) numR++;
if ( items[ i] .color .equals ( "Black" ) ) numBlack++;
res = max( res, items[ i] .value + go( i + 1 , numW, numBlue, numR, numBlack, ( items[ i] .cost + currSpent) ) ) ;
}
return //dp[numW][numBlack][numR][numBlue][i][currSpent] =
res;
}
int ans;
n = nextInt( ) ;
budget = nextInt( ) ;
items = new Item[ n] ;
for ( int i = 0 ; i < n; i++ ) items[ i] = new Item( next( ) , nextInt( ) , nextInt( ) , nextInt( ) ) ;
dp = new int [ 2 ] [ 4 ] [ 6 ] [ 6 ] [ n] [ budget + 1 ] ;
for ( int a = 0 ; a <= 1 ; a++ )
for ( int i = 0 ; i <= 3 ; i++ )
for ( int j = 0 ; j <= 5 ; j++ )
for ( int k = 0 ; k <= 5 ; k++ )
for ( int l = 0 ; l < n; l++ )
for ( int m = 0 ; m <= budget; m++ )
dp[ a] [ i] [ j] [ k] [ l] [ m] = dp_1;
ans = go( 0 , 0 , 0 , 0 , 0 , 0 ) ;
out.println ( ans) ;
out.flush ( ) ;
}
int t = nextInt( ) ;
while ( t-- > 0 ) Case ( ) ;
}
private int gcd( int a, int b) {
while ( b > 0 ) {
int temp = b;
b = a % b;
a = temp;
}
return a;
}
int min( int x, int y) {
}
int max( int x, int y) {
}
long min( long x, long y) {
}
long max( long x, long y) {
}
int [ ] sort( int [ ] arr) {
sort( arr, 0 , arr.length - 1 ) ;
return arr;
}
void sort( int arr[ ] , int l, int r) {
if ( l < r) {
int m = ( l + r) / 2 ;
sort( arr, l, m) ;
sort( arr, m + 1 , r) ;
merge( arr, l, m, r) ;
}
}
void merge( int arr[ ] , int l, int m, int r) {
int n1 = m - l + 1 ;
int n2 = r - m;
int L[ ] = new int [ n1] ;
int R[ ] = new int [ n2] ;
for ( int i = 0 ; i < n1; ++ i)
L[ i] = arr[ l + i] ;
for ( int j = 0 ; j < n2; ++ j)
R[ j] = arr[ m + 1 + j] ;
int i = 0 , j = 0 ;
int k = l;
while ( i < n1 && j < n2) {
if ( L[ i] <= R[ j] ) {
arr[ k] = L[ i] ;
i++;
} else {
arr[ k] = R[ j] ;
j++;
}
k++;
}
while ( i < n1) {
arr[ k] = L[ i] ;
i++;
k++;
}
while ( j < n2) {
arr[ k] = R[ j] ;
j++;
k++;
}
}
class Seg implements Comparable< Seg> {
int st, end;
public Seg( int st, int end) {
this .st = st;
this .end = end;
}
@Override
public boolean equals
( Object o
) { if ( this == o) return true ;
if ( o == null || getClass( ) != o.getClass ( ) ) return false ;
Seg seg = ( Seg) o;
return st == seg.st &&
end == seg.end ;
}
@Override
public int hashCode( ) {
return Objects.hash ( st, end) ;
}
@Override
public int compareTo( Seg seg) {
return st
== seg.
st ? Integer .
compare ( end, seg.
end ) : Integer .
compare ( st, seg.
st ) ; }
}
int [ ] a = new int [ n] ;
for ( int i = 0 ; i < n; i++ ) a[ i] = nextInt( ) ;
return a;
}
long [ ] a = new long [ n] ;
for ( int i = 0 ; i < n; i++ ) a[ i] = nextLong( ) ;
return a;
}
return parseInt( next( ) ) ;
}
return parseLong( next( ) ) ;
}
return parseDouble( next( ) ) ;
}
while ( tok == null || ! tok.hasMoreTokens ( ) ) {
}
return tok.nextToken ( ) ;
}
try {
if ( isLocal) {
} else {
}
// long lStartTime = System.currentTimeMillis();
new Main( ) .solve ( ) ;
// long lEndTime = System.currentTimeMillis();
// out.println("Elapsed time in seconds: " + (double) (lEndTime - lStartTime) / 1000.0);
in.close ( ) ;
out.close ( ) ;
e.printStackTrace ( ) ;
exit( 1 ) ;
}
}
}
CmltcG9ydCBqYXZhLmlvLio7CmltcG9ydCBqYXZhLnV0aWwuKjsKCmltcG9ydCBzdGF0aWMgamF2YS5sYW5nLkRvdWJsZS5wYXJzZURvdWJsZTsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuSW50ZWdlci5wYXJzZUludDsKaW1wb3J0IHN0YXRpYyBqYXZhLmxhbmcuTG9uZy5wYXJzZUxvbmc7CmltcG9ydCBzdGF0aWMgamF2YS5sYW5nLlN5c3RlbS5leGl0OwoKCnB1YmxpYyBjbGFzcyBNYWluIHsKCiAgICBzdGF0aWMgQnVmZmVyZWRSZWFkZXIgaW47CiAgICBzdGF0aWMgUHJpbnRXcml0ZXIgb3V0OwogICAgc3RhdGljIFN0cmluZ1Rva2VuaXplciB0b2s7CiAgICBzdGF0aWMgYm9vbGVhbiBpc0xvY2FsID0gZmFsc2U7CgoKICAgIGNsYXNzIEl0ZW0gewogICAgICAgIFN0cmluZyBjb2xvcjsKICAgICAgICBpbnQgY29zdDsKICAgICAgICBpbnQgdmFsdWU7CiAgICAgICAgaW50IGlkOwoKICAgICAgICBwdWJsaWMgSXRlbShTdHJpbmcgY29sb3IsIGludCBjb3N0LCBpbnQgdmFsdWUsIGludCBpZCkgewogICAgICAgICAgICB0aGlzLmNvbG9yID0gY29sb3I7CiAgICAgICAgICAgIHRoaXMuY29zdCA9IGNvc3Q7CiAgICAgICAgICAgIHRoaXMudmFsdWUgPSB2YWx1ZTsKICAgICAgICAgICAgdGhpcy5pZCA9IGlkOwogICAgICAgIH0KICAgIH0KCiAgICBpbnQgbiwgZHBfMSA9IC0xMDAwMDAwOwogICAgaW50IGJ1ZGdldDsKICAgIEl0ZW1bXSBpdGVtczsKCiAgICBib29sZWFuIGNoZWNrTWF4KGludCBudW1XLCBpbnQgbnVtQmx1ZSwgaW50IG51bVIsIGludCBudW1CbGFjaykgewogICAgICAgIHJldHVybiBudW1XIDw9IDEgJiYgbnVtQmx1ZSA8PSA1ICYmIG51bVIgPD0gNSAmJiBudW1CbGFjayA8PSAzOwogICAgfQoKICAgIGJvb2xlYW4gY2hlY2tNaW4oaW50IG51bVcsIGludCBudW1CbHVlLCBpbnQgbnVtUiwgaW50IG51bUJsYWNrKSB7CiAgICAgICAgcmV0dXJuIG51bVcgPT0gMSAmJiBudW1CbHVlID49IDMgJiYgbnVtUiA+PSAzICYmIG51bUJsYWNrID49IDE7CiAgICB9CgogICAgYm9vbGVhbiBjYW5BZGRJdGVtKEl0ZW0gaXRlbSwgaW50IG51bVcsIGludCBudW1CbHVlLCBpbnQgbnVtUiwgaW50IG51bUJsYWNrLCBpbnQgY3VyclNwZW50KSB7CiAgICAgICAgaWYgKGl0ZW0uY29sb3IuZXF1YWxzKCJXIikpIG51bVcrKzsKICAgICAgICBpZiAoaXRlbS5jb2xvci5lcXVhbHMoIkJsdWUiKSkgbnVtQmx1ZSsrOwogICAgICAgIGlmIChpdGVtLmNvbG9yLmVxdWFscygiUiIpKSBudW1SKys7CiAgICAgICAgaWYgKGl0ZW0uY29sb3IuZXF1YWxzKCJCbGFjayIpKSBudW1CbGFjaysrOwogICAgICAgIGN1cnJTcGVudCArPSBpdGVtLmNvc3Q7CiAgICAgICAgcmV0dXJuIGNoZWNrTWF4KG51bVcsIG51bUJsdWUsIG51bVIsIG51bUJsYWNrKSAmJiBjdXJyU3BlbnQgPD0gYnVkZ2V0ICYmIG51bVcgKyBudW1CbHVlICsgbnVtUiArIG51bUJsYWNrIDw9IDEyOwogICAgfQoKICAgIGludCBkcFtdW11bXVtdW11bXTsKCiAgICBpbnQgZ28oaW50IGksIGludCBudW1XLCBpbnQgbnVtQmx1ZSwgaW50IG51bVIsIGludCBudW1CbGFjaywgaW50IGN1cnJTcGVudCkgewogICAgICAgIGlmIChuIC0gaSArIG51bVcgKyBudW1CbHVlICsgbnVtUiArIG51bUJsYWNrIDwgMTIpIHJldHVybiAtMTAwMDA7CiAgICAgICAgaWYgKGkgPT0gbikKICAgICAgICAgICAgcmV0dXJuIChjaGVja01pbihudW1XLCBudW1CbHVlLCBudW1SLCBudW1CbGFjaykgJiYgbnVtVyArIG51bUJsdWUgKyBudW1SICsgbnVtQmxhY2sgPT0gMTIpID8gMCA6IC0xMDAwMDsKLy8gICAgICAgIGlmIChkcFtudW1XXVtudW1CbGFja11bbnVtUl1bbnVtQmx1ZV1baV1bY3VyclNwZW50XSAhPSBkcF8xKQovLyAgICAgICAgICAgIHJldHVybiBkcFtudW1XXVtudW1CbGFja11bbnVtUl1bbnVtQmx1ZV1baV1bY3VyclNwZW50XTsKICAgICAgICBpbnQgcmVzID0gLTEwMDAwOwogICAgICAgIHJlcyA9IG1heChyZXMsIGdvKChpbnQpIChpICsgMSksIG51bVcsIG51bUJsdWUsIG51bVIsIG51bUJsYWNrLCBjdXJyU3BlbnQpKTsKICAgICAgICBpZiAoY2FuQWRkSXRlbShpdGVtc1tpXSwgbnVtVywgbnVtQmx1ZSwgbnVtUiwgbnVtQmxhY2ssIGN1cnJTcGVudCkpIHsKICAgICAgICAgICAgaWYgKGl0ZW1zW2ldLmNvbG9yLmVxdWFscygiVyIpKSBudW1XKys7CiAgICAgICAgICAgIGlmIChpdGVtc1tpXS5jb2xvci5lcXVhbHMoIkJsdWUiKSkgbnVtQmx1ZSsrOwogICAgICAgICAgICBpZiAoaXRlbXNbaV0uY29sb3IuZXF1YWxzKCJSIikpIG51bVIrKzsKICAgICAgICAgICAgaWYgKGl0ZW1zW2ldLmNvbG9yLmVxdWFscygiQmxhY2siKSkgbnVtQmxhY2srKzsKICAgICAgICAgICAgcmVzID0gbWF4KHJlcywgaXRlbXNbaV0udmFsdWUgKyBnbyggaSArIDEsIG51bVcsIG51bUJsdWUsIG51bVIsIG51bUJsYWNrLCAoaXRlbXNbaV0uY29zdCArIGN1cnJTcGVudCkpKTsKICAgICAgICB9CiAgICAgICAgcmV0dXJuIC8vZHBbbnVtV11bbnVtQmxhY2tdW251bVJdW251bUJsdWVdW2ldW2N1cnJTcGVudF0gPQogICAgICAgICAgICAgICAgcmVzOwogICAgfQoKICAgIGludCBhbnM7CgogICAgdm9pZCBDYXNlKCkgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBuID0gbmV4dEludCgpOwogICAgICAgIGJ1ZGdldCA9IG5leHRJbnQoKTsKICAgICAgICBpdGVtcyA9IG5ldyBJdGVtW25dOwogICAgICAgIGZvciAoaW50IGkgPSAwOyBpIDwgbjsgaSsrKSBpdGVtc1tpXSA9IG5ldyBJdGVtKG5leHQoKSwgbmV4dEludCgpLCBuZXh0SW50KCksIG5leHRJbnQoKSk7CiAgICAgICAgZHAgPSBuZXcgaW50WzJdWzRdWzZdWzZdW25dW2J1ZGdldCArIDFdOwogICAgICAgIGZvciAoaW50IGEgPSAwOyBhIDw9IDE7IGErKykKICAgICAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPD0gMzsgaSsrKQogICAgICAgICAgICAgICAgZm9yIChpbnQgaiA9IDA7IGogPD0gNTsgaisrKQogICAgICAgICAgICAgICAgICAgIGZvciAoaW50IGsgPSAwOyBrIDw9IDU7IGsrKykKICAgICAgICAgICAgICAgICAgICAgICAgZm9yIChpbnQgbCA9IDA7IGwgPCBuOyBsKyspCiAgICAgICAgICAgICAgICAgICAgICAgICAgICBmb3IgKGludCBtID0gMDsgbSA8PSBidWRnZXQ7IG0rKykKICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBkcFthXVtpXVtqXVtrXVtsXVttXSA9IGRwXzE7CiAgICAgICAgYW5zID0gZ28oIDAsICAwLCAgMCwgIDAsICAwLCAgMCk7CiAgICAgICAgb3V0LnByaW50bG4oYW5zKTsKICAgICAgICBvdXQuZmx1c2goKTsKICAgIH0KCgogICAgdm9pZCBzb2x2ZSgpIHRocm93cyBFeGNlcHRpb24gewogICAgICAgIGludCB0ID0gbmV4dEludCgpOwogICAgICAgIHdoaWxlICh0LS0gPiAwKSBDYXNlKCk7CiAgICB9CgogICAgcHJpdmF0ZSBpbnQgZ2NkKGludCBhLCBpbnQgYikgewogICAgICAgIHdoaWxlIChiID4gMCkgewogICAgICAgICAgICBpbnQgdGVtcCA9IGI7CiAgICAgICAgICAgIGIgPSBhICUgYjsKICAgICAgICAgICAgYSA9IHRlbXA7CiAgICAgICAgfQogICAgICAgIHJldHVybiBhOwogICAgfQoKICAgIGludCBtaW4oaW50IHgsIGludCB5KSB7CiAgICAgICAgcmV0dXJuIEludGVnZXIubWluKHgsIHkpOwogICAgfQoKICAgIGludCBtYXgoaW50IHgsIGludCB5KSB7CiAgICAgICAgcmV0dXJuIEludGVnZXIubWF4KHgsIHkpOwogICAgfQoKICAgIGxvbmcgbWluKGxvbmcgeCwgbG9uZyB5KSB7CiAgICAgICAgcmV0dXJuIExvbmcubWluKHgsIHkpOwogICAgfQoKICAgIGxvbmcgbWF4KGxvbmcgeCwgbG9uZyB5KSB7CiAgICAgICAgcmV0dXJuIExvbmcubWF4KHgsIHkpOwogICAgfQoKICAgIGludFtdIHNvcnQoaW50W10gYXJyKSB7CiAgICAgICAgc29ydChhcnIsIDAsIGFyci5sZW5ndGggLSAxKTsKICAgICAgICByZXR1cm4gYXJyOwogICAgfQoKICAgIHZvaWQgc29ydChpbnQgYXJyW10sIGludCBsLCBpbnQgcikgewogICAgICAgIGlmIChsIDwgcikgewogICAgICAgICAgICBpbnQgbSA9IChsICsgcikgLyAyOwogICAgICAgICAgICBzb3J0KGFyciwgbCwgbSk7CiAgICAgICAgICAgIHNvcnQoYXJyLCBtICsgMSwgcik7CiAgICAgICAgICAgIG1lcmdlKGFyciwgbCwgbSwgcik7CiAgICAgICAgfQogICAgfQoKICAgIHZvaWQgbWVyZ2UoaW50IGFycltdLCBpbnQgbCwgaW50IG0sIGludCByKSB7CiAgICAgICAgaW50IG4xID0gbSAtIGwgKyAxOwogICAgICAgIGludCBuMiA9IHIgLSBtOwogICAgICAgIGludCBMW10gPSBuZXcgaW50W24xXTsKICAgICAgICBpbnQgUltdID0gbmV3IGludFtuMl07CiAgICAgICAgZm9yIChpbnQgaSA9IDA7IGkgPCBuMTsgKytpKQogICAgICAgICAgICBMW2ldID0gYXJyW2wgKyBpXTsKICAgICAgICBmb3IgKGludCBqID0gMDsgaiA8IG4yOyArK2opCiAgICAgICAgICAgIFJbal0gPSBhcnJbbSArIDEgKyBqXTsKICAgICAgICBpbnQgaSA9IDAsIGogPSAwOwogICAgICAgIGludCBrID0gbDsKICAgICAgICB3aGlsZSAoaSA8IG4xICYmIGogPCBuMikgewogICAgICAgICAgICBpZiAoTFtpXSA8PSBSW2pdKSB7CiAgICAgICAgICAgICAgICBhcnJba10gPSBMW2ldOwogICAgICAgICAgICAgICAgaSsrOwogICAgICAgICAgICB9IGVsc2UgewogICAgICAgICAgICAgICAgYXJyW2tdID0gUltqXTsKICAgICAgICAgICAgICAgIGorKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBrKys7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChpIDwgbjEpIHsKICAgICAgICAgICAgYXJyW2tdID0gTFtpXTsKICAgICAgICAgICAgaSsrOwogICAgICAgICAgICBrKys7CiAgICAgICAgfQogICAgICAgIHdoaWxlIChqIDwgbjIpIHsKICAgICAgICAgICAgYXJyW2tdID0gUltqXTsKICAgICAgICAgICAgaisrOwogICAgICAgICAgICBrKys7CiAgICAgICAgfQogICAgfQoKICAgIGNsYXNzIFNlZyBpbXBsZW1lbnRzIENvbXBhcmFibGU8U2VnPiB7CiAgICAgICAgaW50IHN0LCBlbmQ7CgogICAgICAgIHB1YmxpYyBTZWcoaW50IHN0LCBpbnQgZW5kKSB7CiAgICAgICAgICAgIHRoaXMuc3QgPSBzdDsKICAgICAgICAgICAgdGhpcy5lbmQgPSBlbmQ7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgYm9vbGVhbiBlcXVhbHMoT2JqZWN0IG8pIHsKICAgICAgICAgICAgaWYgKHRoaXMgPT0gbykgcmV0dXJuIHRydWU7CiAgICAgICAgICAgIGlmIChvID09IG51bGwgfHwgZ2V0Q2xhc3MoKSAhPSBvLmdldENsYXNzKCkpIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgU2VnIHNlZyA9IChTZWcpIG87CiAgICAgICAgICAgIHJldHVybiBzdCA9PSBzZWcuc3QgJiYKICAgICAgICAgICAgICAgICAgICBlbmQgPT0gc2VnLmVuZDsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKSB7CiAgICAgICAgICAgIHJldHVybiBPYmplY3RzLmhhc2goc3QsIGVuZCk7CiAgICAgICAgfQoKICAgICAgICBAT3ZlcnJpZGUKICAgICAgICBwdWJsaWMgaW50IGNvbXBhcmVUbyhTZWcgc2VnKSB7CiAgICAgICAgICAgIHJldHVybiBzdCA9PSBzZWcuc3QgPyBJbnRlZ2VyLmNvbXBhcmUoZW5kLCBzZWcuZW5kKSA6IEludGVnZXIuY29tcGFyZShzdCwgc2VnLnN0KTsKICAgICAgICB9CiAgICB9CgogICAgcHJpdmF0ZSBpbnRbXSBuYShpbnQgbikgdGhyb3dzIElPRXhjZXB0aW9uIHsKICAgICAgICBpbnRbXSBhID0gbmV3IGludFtuXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgYVtpXSA9IG5leHRJbnQoKTsKICAgICAgICByZXR1cm4gYTsKICAgIH0KCiAgICBwcml2YXRlIGxvbmdbXSBuYWwoaW50IG4pIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgbG9uZ1tdIGEgPSBuZXcgbG9uZ1tuXTsKICAgICAgICBmb3IgKGludCBpID0gMDsgaSA8IG47IGkrKykgYVtpXSA9IG5leHRMb25nKCk7CiAgICAgICAgcmV0dXJuIGE7CiAgICB9CgogICAgaW50IG5leHRJbnQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBwYXJzZUludChuZXh0KCkpOwogICAgfQoKICAgIGxvbmcgbmV4dExvbmcoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHJldHVybiBwYXJzZUxvbmcobmV4dCgpKTsKICAgIH0KCiAgICBkb3VibGUgbmV4dERvdWJsZSgpIHRocm93cyBJT0V4Y2VwdGlvbiB7CiAgICAgICAgcmV0dXJuIHBhcnNlRG91YmxlKG5leHQoKSk7CiAgICB9CgogICAgU3RyaW5nIG5leHQoKSB0aHJvd3MgSU9FeGNlcHRpb24gewogICAgICAgIHdoaWxlICh0b2sgPT0gbnVsbCB8fCAhdG9rLmhhc01vcmVUb2tlbnMoKSkgewogICAgICAgICAgICB0b2sgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGluLnJlYWRMaW5lKCkpOwogICAgICAgIH0KICAgICAgICByZXR1cm4gdG9rLm5leHRUb2tlbigpOwogICAgfQoKICAgIHB1YmxpYyBzdGF0aWMgdm9pZCBtYWluKFN0cmluZ1tdIGFyZ3MpIHRocm93cyBFeGNlcHRpb24gewogICAgICAgIHRyeSB7CiAgICAgICAgICAgIGlmIChpc0xvY2FsKSB7CiAgICAgICAgICAgICAgICBpbiA9IG5ldyBCdWZmZXJlZFJlYWRlcihuZXcgRmlsZVJlYWRlcigic3JjL3Rlc3RzL3NvbC5pbiIpKTsKICAgICAgICAgICAgICAgIG91dCA9IG5ldyBQcmludFdyaXRlcihuZXcgQnVmZmVyZWRXcml0ZXIobmV3IEZpbGVXcml0ZXIoInNyYy90ZXN0cy9zb2wub3V0IikpKTsKICAgICAgICAgICAgfSBlbHNlIHsKICAgICAgICAgICAgICAgIGluID0gbmV3IEJ1ZmZlcmVkUmVhZGVyKG5ldyBJbnB1dFN0cmVhbVJlYWRlcihTeXN0ZW0uaW4pKTsKICAgICAgICAgICAgICAgIG91dCA9IG5ldyBQcmludFdyaXRlcihuZXcgT3V0cHV0U3RyZWFtV3JpdGVyKFN5c3RlbS5vdXQpKTsKICAgICAgICAgICAgfQovLyAgICAgICAgICAgIGxvbmcgbFN0YXJ0VGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwogICAgICAgICAgICBuZXcgTWFpbigpLnNvbHZlKCk7Ci8vICAgICAgICAgICAgbG9uZyBsRW5kVGltZSA9IFN5c3RlbS5jdXJyZW50VGltZU1pbGxpcygpOwovLyAgICAgICAgICAgIG91dC5wcmludGxuKCJFbGFwc2VkIHRpbWUgaW4gc2Vjb25kczogIiArIChkb3VibGUpIChsRW5kVGltZSAtIGxTdGFydFRpbWUpIC8gMTAwMC4wKTsKICAgICAgICAgICAgaW4uY2xvc2UoKTsKICAgICAgICAgICAgb3V0LmNsb3NlKCk7CiAgICAgICAgfSBjYXRjaCAoVGhyb3dhYmxlIGUpIHsKICAgICAgICAgICAgZS5wcmludFN0YWNrVHJhY2UoKTsKICAgICAgICAgICAgZXhpdCgxKTsKICAgICAgICB9CiAgICB9Cn0K