import java.io.*;
import java.util.*;
class CLSHDN{
static long INF
= Long.
MAX_VALUE>>2;
static class Edge{
int fr, to, wt;
Edge(int a, int b, int c){
fr = a; to = b; wt = c;
}
@Override
public int hashCode(){
int hc = 31*fr;
hc = hc*31 + to;
return hc;
}
@Override
public boolean equals
(Object o
){ if(o==null || !(o instanceof Edge))
return false;
Edge e = (Edge)o;
return fr==e.fr && to==e.to;
}
}
static class Vertex{
ArrayList<Edge> edges, sptEdges; int ilnd;
Vertex(){
edges = new ArrayList<>(); sptEdges = new ArrayList<>(); ilnd = -1;
}
}
static class KempeTree{
long t[];
int N;
KempeTree(int n){
t = new long[N+n];
}
void rangeUpdate(int i, int j, long v){
for(i+=N, j+=N; i<=j; i=(i+1)/2, j=(j-1)/2){
if(i%2==1)
t
[i
] = Math.
min(t
[i
], v
); if(j%2==0)
t
[j
] = Math.
min(t
[j
], v
); }
}
long query(int i){
long v = INF;
for(int j=i+N; j>0; j/=2)
return v;
}
}
static int n, m, s, t, q;
static Vertex g[];
static Edge el[];
static long ds[], dt[];
static KempeTree kt;
static HashSet<Edge> bridges;
int T = re.nextInt();
while(T-->0){
n = re.nextInt();
m = re.nextInt();
g = new Vertex[n];
el = new Edge[m*2];
for(int i=0; i<n; i++)
g[i] = new Vertex();
for(int i=0; i<m; i++){
int u = re.nextInt();
int v = re.nextInt();
int w = re.nextInt();
el[2*i] = new Edge(u, v, w);
el[2*i+1] = new Edge(v, u, w);
g[u].edges.add(el[2*i]);
g[v].edges.add(el[2*i+1]);
}
s = re.nextInt();
t = re.nextInt();
work();
q = re.nextInt();
while(q-->0){
int u = re.nextInt();
int v = re.nextInt();
if(ds[v]<ds[u]){
int t = v; v = u; u = t;
}
if(bridges.contains(new Edge(u, v, 0))){
long out = kt.query(g[u].ilnd);
System.
out.
println(out
>=INF
?"Infinity":out
); }
else
}
}
}
static void work(){
// COMPUTE DS AND DT
Edge prev[] = new Edge[n];
dt = dijkstra(g, t, s, prev);
ds = dijkstra(g, s, t, prev);
// FIND ALL BRIDGES
ArrayList<Edge> opt = new ArrayList<>();
bridges = new HashSet<>();
int nb = findBridges(opt);
//IDENTIFY ISLANDS
identifyIslands(prev);
//GET BYPASS VALUES
kt = new KempeTree(nb);
fillBypass();
}
static int findBridges(ArrayList<Edge> opt){
for(int i=0; i<el.length; i++){
Edge e = el[i];
if(ds[e.fr]+e.wt+dt[e.to]==ds[t]){
opt.add(e);
el[i] = null;
}
}
public int compare(Edge e1, Edge e2){
if(ds[e1.fr]==ds[e2.fr])
return ds[e1.to]==ds[e2.to] ? 0 : ds[e1.to]<ds[e2.to]? -1 : 1;
else
return ds[e1.fr]<ds[e2.fr] ? -1 : 1;
}
});
int nb = 0;
if(opt.size()==1){
bridges.add(opt.get(0)); nb++;
}
else{
if(ds[opt.get(0).to]<=ds[opt.get(1).fr]){
bridges.add(opt.get(0)); nb++;
}
Edge e = opt.get(opt.size()-1);
if(ds[e.fr]>=ds[opt.get(opt.size()-2).to] && !bridges.contains(e)){
bridges.add(e); nb++;
}
for(int i=1; i<opt.size()-1; i++){
e = opt.get(i);
if(ds[e.fr]>=ds[opt.get(i-1).to] && ds[e.to]<=ds[opt.get(i+1).fr]){
bridges.add(e); nb++;
}
}
}
return nb;
}
static void identifyIslands(Edge prev[]){
for(Edge e : prev)
if(e!=null)
g[e.fr].sptEdges.add(e);
class State{
int v, currIlnd;
State(int v1, int ci){
v = v1; currIlnd = ci;
}
}
Deque<State> stack = new LinkedList<>();
stack.push(new State(s, 0));
while(!stack.isEmpty()){
State st = stack.pop();
g[st.v].ilnd = st.currIlnd;
for(Edge e : g[st.v].sptEdges){
if(bridges.contains(e))
stack.push(new State(e.to, st.currIlnd+1));
else
stack.push(new State(e.to, st.currIlnd));
}
}
}
static void fillBypass(){
for(Edge e : el)
if(e!=null)
kt.rangeUpdate(g[e.fr].ilnd, g[e.to].ilnd-1, ds[e.fr]+e.wt+dt[e.to]);
}
static long[] dijkstra(Vertex g[], int s, int t, Edge prev[]){
long dist[] = new long[g.length];
dist[s] = 0;
prev[s] = null;
PriorityQueue<Integer> pq = new PriorityQueue<>(new Comparator<Integer>(){
return dist[u]==dist[v] ? 0 : dist[u]<dist[v] ? -1 : 1;
}
});
pq.add(s);
while(!pq.isEmpty()){
int curr = pq.poll();
if(curr==t)
continue;
if(dist[curr]>=INF)
break;
Vertex v = g[curr];
for(Edge e : v.edges){
if(dist[curr]+e.wt < dist[e.to]){
pq.remove(e.to);
dist[e.to] = dist[curr]+e.wt;
prev[e.to] = e;
pq.add(e.to);
}
}
}
return dist;
}
}
}
while(!st.hasMoreTokens())
return st.nextToken();
}
}
return Double.
parseDouble(next
()); }
}
aW1wb3J0IGphdmEuaW8uKjsKaW1wb3J0IGphdmEudXRpbC4qOwpjbGFzcyBDTFNIRE57CiAgICBzdGF0aWMgbG9uZyBJTkYgPSBMb25nLk1BWF9WQUxVRT4+MjsKICAgIAogICAgc3RhdGljIGNsYXNzIEVkZ2V7CiAgICAgICAgaW50IGZyLCB0bywgd3Q7CiAgICAgICAgRWRnZShpbnQgYSwgaW50IGIsIGludCBjKXsKICAgICAgICAgICAgZnIgPSBhOyB0byA9IGI7IHd0ID0gYzsKICAgICAgICB9CgogICAgICAgIEBPdmVycmlkZQogICAgICAgIHB1YmxpYyBpbnQgaGFzaENvZGUoKXsKICAgICAgICAgICAgaW50IGhjID0gMzEqZnI7CiAgICAgICAgICAgIGhjID0gaGMqMzEgKyB0bzsKICAgICAgICAgICAgcmV0dXJuIGhjOwogICAgICAgIH0KCiAgICAgICAgQE92ZXJyaWRlCiAgICAgICAgcHVibGljIGJvb2xlYW4gZXF1YWxzKE9iamVjdCBvKXsKICAgICAgICAgICAgaWYobz09bnVsbCB8fCAhKG8gaW5zdGFuY2VvZiBFZGdlKSkKICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTsKICAgICAgICAgICAgRWRnZSBlID0gKEVkZ2UpbzsKICAgICAgICAgICAgcmV0dXJuIGZyPT1lLmZyICYmIHRvPT1lLnRvOwogICAgICAgIH0KICAgICAgICAKICAgIH0KCiAgICBzdGF0aWMgY2xhc3MgVmVydGV4ewogICAgICAgIEFycmF5TGlzdDxFZGdlPiBlZGdlcywgc3B0RWRnZXM7IGludCBpbG5kOwogICAgICAgIFZlcnRleCgpewogICAgICAgICAgICBlZGdlcyA9IG5ldyBBcnJheUxpc3Q8PigpOyBzcHRFZGdlcyA9IG5ldyBBcnJheUxpc3Q8PigpOyBpbG5kID0gLTE7CiAgICAgICAgfQogICAgfQogICAgCiAgICBzdGF0aWMgY2xhc3MgS2VtcGVUcmVlewogICAgICAgIGxvbmcgdFtdOwogICAgICAgIGludCBOOwogICAgICAgIEtlbXBlVHJlZShpbnQgbil7CiAgICAgICAgICAgIE4gPSAoaW50KU1hdGgucG93KDIsIE1hdGguY2VpbChNYXRoLmxvZyhuKS9NYXRoLmxvZygyKSkpOwogICAgICAgICAgICB0ID0gbmV3IGxvbmdbTituXTsKICAgICAgICAgICAgQXJyYXlzLmZpbGwodCwgSU5GKTsKICAgICAgICB9CiAgICAgICAgCiAgICAgICAgdm9pZCByYW5nZVVwZGF0ZShpbnQgaSwgaW50IGosIGxvbmcgdil7CiAgICAgICAgICAgIGZvcihpKz1OLCBqKz1OOyBpPD1qOyBpPShpKzEpLzIsIGo9KGotMSkvMil7CiAgICAgICAgICAgICAgICBpZihpJTI9PTEpCiAgICAgICAgICAgICAgICAgICAgdFtpXSA9IE1hdGgubWluKHRbaV0sIHYpOwogICAgICAgICAgICAgICAgaWYoaiUyPT0wKQogICAgICAgICAgICAgICAgICAgIHRbal0gPSBNYXRoLm1pbih0W2pdLCB2KTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICAKICAgICAgICBsb25nIHF1ZXJ5KGludCBpKXsKICAgICAgICAgICAgbG9uZyB2ID0gSU5GOwogICAgICAgICAgICBmb3IoaW50IGo9aStOOyBqPjA7IGovPTIpCiAgICAgICAgICAgICAgICB2ID0gTWF0aC5taW4odFtqXSwgdik7CiAgICAgICAgICAgIHJldHVybiB2OwogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgaW50IG4sIG0sIHMsIHQsIHE7CiAgICBzdGF0aWMgVmVydGV4IGdbXTsKICAgIHN0YXRpYyBFZGdlIGVsW107CiAgICBzdGF0aWMgbG9uZyBkc1tdLCBkdFtdOwogICAgc3RhdGljIEtlbXBlVHJlZSBrdDsKICAgIHN0YXRpYyBIYXNoU2V0PEVkZ2U+IGJyaWRnZXM7CiAgICBwdWJsaWMgc3RhdGljIHZvaWQgbWFpbihTdHJpbmcgYXJnc1tdKXRocm93cyBFeGNlcHRpb257CiAgICAgICAgUmVhZGVyIHJlID0gbmV3IFJlYWRlcihTeXN0ZW0uaW4pOwogICAgICAgIGludCBUID0gcmUubmV4dEludCgpOwogICAgICAgIHdoaWxlKFQtLT4wKXsKICAgICAgICAgICAgbiA9IHJlLm5leHRJbnQoKTsKICAgICAgICAgICAgbSA9IHJlLm5leHRJbnQoKTsKICAgICAgICAgICAgZyA9IG5ldyBWZXJ0ZXhbbl07CiAgICAgICAgICAgIGVsID0gbmV3IEVkZ2VbbSoyXTsKICAgICAgICAgICAgZm9yKGludCBpPTA7IGk8bjsgaSsrKQogICAgICAgICAgICAgICAgZ1tpXSA9IG5ldyBWZXJ0ZXgoKTsKICAgICAgICAgICAgZm9yKGludCBpPTA7IGk8bTsgaSsrKXsKICAgICAgICAgICAgICAgIGludCB1ID0gcmUubmV4dEludCgpOwogICAgICAgICAgICAgICAgaW50IHYgPSByZS5uZXh0SW50KCk7CiAgICAgICAgICAgICAgICBpbnQgdyA9IHJlLm5leHRJbnQoKTsKICAgICAgICAgICAgICAgIGVsWzIqaV0gPSBuZXcgRWRnZSh1LCB2LCB3KTsKICAgICAgICAgICAgICAgIGVsWzIqaSsxXSA9IG5ldyBFZGdlKHYsIHUsIHcpOwogICAgICAgICAgICAgICAgZ1t1XS5lZGdlcy5hZGQoZWxbMippXSk7CiAgICAgICAgICAgICAgICBnW3ZdLmVkZ2VzLmFkZChlbFsyKmkrMV0pOwogICAgICAgICAgICB9CiAgICAgICAgICAgIHMgPSByZS5uZXh0SW50KCk7CiAgICAgICAgICAgIHQgPSByZS5uZXh0SW50KCk7CiAgICAgICAgICAgIHdvcmsoKTsKICAgICAgICAgICAgcSA9IHJlLm5leHRJbnQoKTsKICAgICAgICAgICAgd2hpbGUocS0tPjApewogICAgICAgICAgICAgICAgaW50IHUgPSByZS5uZXh0SW50KCk7CiAgICAgICAgICAgICAgICBpbnQgdiA9IHJlLm5leHRJbnQoKTsKICAgICAgICAgICAgICAgIGlmKGRzW3ZdPGRzW3VdKXsKICAgICAgICAgICAgICAgICAgICBpbnQgdCA9IHY7IHYgPSB1OyB1ID0gdDsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGlmKGJyaWRnZXMuY29udGFpbnMobmV3IEVkZ2UodSwgdiwgMCkpKXsKICAgICAgICAgICAgICAgICAgICBsb25nIG91dCA9IGt0LnF1ZXJ5KGdbdV0uaWxuZCk7CiAgICAgICAgICAgICAgICAgICAgU3lzdGVtLm91dC5wcmludGxuKG91dD49SU5GPyJJbmZpbml0eSI6b3V0KTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICBTeXN0ZW0ub3V0LnByaW50bG4oZHNbdF0pOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgfQoKICAgIHN0YXRpYyB2b2lkIHdvcmsoKXsKICAgICAgICAvLyBDT01QVVRFIERTIEFORCBEVAogICAgICAgIEVkZ2UgcHJldltdID0gbmV3IEVkZ2Vbbl07CiAgICAgICAgZHQgPSBkaWprc3RyYShnLCB0LCBzLCBwcmV2KTsKICAgICAgICBkcyA9IGRpamtzdHJhKGcsIHMsIHQsIHByZXYpOwoKICAgICAgICAvLyBGSU5EIEFMTCBCUklER0VTCiAgICAgICAgQXJyYXlMaXN0PEVkZ2U+IG9wdCA9IG5ldyBBcnJheUxpc3Q8PigpOwogICAgICAgIGJyaWRnZXMgPSBuZXcgSGFzaFNldDw+KCk7CiAgICAgICAgaW50IG5iID0gZmluZEJyaWRnZXMob3B0KTsKCiAgICAgICAgLy9JREVOVElGWSBJU0xBTkRTCiAgICAgICAgaWRlbnRpZnlJc2xhbmRzKHByZXYpOwoKICAgICAgICAvL0dFVCBCWVBBU1MgVkFMVUVTCiAgICAgICAga3QgPSBuZXcgS2VtcGVUcmVlKG5iKTsKICAgICAgICBmaWxsQnlwYXNzKCk7CiAgICB9CgogICAgc3RhdGljIGludCBmaW5kQnJpZGdlcyhBcnJheUxpc3Q8RWRnZT4gb3B0KXsKICAgICAgICBmb3IoaW50IGk9MDsgaTxlbC5sZW5ndGg7IGkrKyl7CiAgICAgICAgICAgIEVkZ2UgZSA9IGVsW2ldOwogICAgICAgICAgICBpZihkc1tlLmZyXStlLnd0K2R0W2UudG9dPT1kc1t0XSl7CiAgICAgICAgICAgICAgICBvcHQuYWRkKGUpOwogICAgICAgICAgICAgICAgZWxbaV0gPSBudWxsOwogICAgICAgICAgICB9CiAgICAgICAgfQogICAgICAgIENvbGxlY3Rpb25zLnNvcnQob3B0LCBuZXcgQ29tcGFyYXRvcjxFZGdlPigpewogICAgICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKEVkZ2UgZTEsIEVkZ2UgZTIpewogICAgICAgICAgICAgICAgICAgIGlmKGRzW2UxLmZyXT09ZHNbZTIuZnJdKQogICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZHNbZTEudG9dPT1kc1tlMi50b10gPyAwIDogZHNbZTEudG9dPGRzW2UyLnRvXT8gLTEgOiAxOwogICAgICAgICAgICAgICAgICAgIGVsc2UKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRzW2UxLmZyXTxkc1tlMi5mcl0gPyAtMSA6IDE7CiAgICAgICAgICAgICAgICB9CiAgICAgICAgICAgIH0pOwogICAgICAgIGludCBuYiA9IDA7CiAgICAgICAgaWYob3B0LnNpemUoKT09MSl7CiAgICAgICAgICAgIGJyaWRnZXMuYWRkKG9wdC5nZXQoMCkpOyBuYisrOwogICAgICAgIH0KICAgICAgICBlbHNlewogICAgICAgICAgICBpZihkc1tvcHQuZ2V0KDApLnRvXTw9ZHNbb3B0LmdldCgxKS5mcl0pewogICAgICAgICAgICAgICAgYnJpZGdlcy5hZGQob3B0LmdldCgwKSk7IG5iKys7CiAgICAgICAgICAgIH0KICAgICAgICAgICAgRWRnZSBlID0gb3B0LmdldChvcHQuc2l6ZSgpLTEpOwogICAgICAgICAgICBpZihkc1tlLmZyXT49ZHNbb3B0LmdldChvcHQuc2l6ZSgpLTIpLnRvXSAmJiAhYnJpZGdlcy5jb250YWlucyhlKSl7CiAgICAgICAgICAgICAgICBicmlkZ2VzLmFkZChlKTsgbmIrKzsKICAgICAgICAgICAgfQogICAgICAgICAgICBmb3IoaW50IGk9MTsgaTxvcHQuc2l6ZSgpLTE7IGkrKyl7CiAgICAgICAgICAgICAgICBlID0gb3B0LmdldChpKTsKICAgICAgICAgICAgICAgIGlmKGRzW2UuZnJdPj1kc1tvcHQuZ2V0KGktMSkudG9dICYmIGRzW2UudG9dPD1kc1tvcHQuZ2V0KGkrMSkuZnJdKXsKICAgICAgICAgICAgICAgICAgICBicmlkZ2VzLmFkZChlKTsgbmIrKzsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gbmI7CiAgICB9CgogICAgc3RhdGljIHZvaWQgaWRlbnRpZnlJc2xhbmRzKEVkZ2UgcHJldltdKXsKICAgICAgICBmb3IoRWRnZSBlIDogcHJldikKICAgICAgICAgICAgaWYoZSE9bnVsbCkKICAgICAgICAgICAgICAgIGdbZS5mcl0uc3B0RWRnZXMuYWRkKGUpOwogICAgICAgIGNsYXNzIFN0YXRlewogICAgICAgICAgICBpbnQgdiwgY3VycklsbmQ7CiAgICAgICAgICAgIFN0YXRlKGludCB2MSwgaW50IGNpKXsKICAgICAgICAgICAgICAgIHYgPSB2MTsgY3VycklsbmQgPSBjaTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICBEZXF1ZTxTdGF0ZT4gc3RhY2sgPSBuZXcgTGlua2VkTGlzdDw+KCk7CiAgICAgICAgc3RhY2sucHVzaChuZXcgU3RhdGUocywgMCkpOwogICAgICAgIHdoaWxlKCFzdGFjay5pc0VtcHR5KCkpewogICAgICAgICAgICBTdGF0ZSBzdCA9IHN0YWNrLnBvcCgpOwogICAgICAgICAgICBnW3N0LnZdLmlsbmQgPSBzdC5jdXJySWxuZDsKICAgICAgICAgICAgZm9yKEVkZ2UgZSA6IGdbc3Qudl0uc3B0RWRnZXMpewogICAgICAgICAgICAgICAgaWYoYnJpZGdlcy5jb250YWlucyhlKSkKICAgICAgICAgICAgICAgICAgICBzdGFjay5wdXNoKG5ldyBTdGF0ZShlLnRvLCBzdC5jdXJySWxuZCsxKSk7CiAgICAgICAgICAgICAgICBlbHNlCiAgICAgICAgICAgICAgICAgICAgc3RhY2sucHVzaChuZXcgU3RhdGUoZS50bywgc3QuY3VycklsbmQpKTsKICAgICAgICAgICAgfQogICAgICAgIH0KICAgIH0KCiAgICBzdGF0aWMgdm9pZCBmaWxsQnlwYXNzKCl7CiAgICAgICAgZm9yKEVkZ2UgZSA6IGVsKQogICAgICAgICAgICBpZihlIT1udWxsKQogICAgICAgICAgICAgICAga3QucmFuZ2VVcGRhdGUoZ1tlLmZyXS5pbG5kLCBnW2UudG9dLmlsbmQtMSwgZHNbZS5mcl0rZS53dCtkdFtlLnRvXSk7CiAgICB9CgogICAgc3RhdGljIGxvbmdbXSBkaWprc3RyYShWZXJ0ZXggZ1tdLCBpbnQgcywgaW50IHQsIEVkZ2UgcHJldltdKXsKICAgICAgICBsb25nIGRpc3RbXSA9IG5ldyBsb25nW2cubGVuZ3RoXTsKICAgICAgICBBcnJheXMuZmlsbChkaXN0LCBJTkYpOwogICAgICAgIGRpc3Rbc10gPSAwOwogICAgICAgIHByZXZbc10gPSBudWxsOwogICAgICAgIFByaW9yaXR5UXVldWU8SW50ZWdlcj4gcHEgPSBuZXcgUHJpb3JpdHlRdWV1ZTw+KG5ldyBDb21wYXJhdG9yPEludGVnZXI+KCl7CiAgICAgICAgICAgICAgICAgICAgcHVibGljIGludCBjb21wYXJlKEludGVnZXIgdSwgSW50ZWdlciB2KXsKICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuIGRpc3RbdV09PWRpc3Rbdl0gPyAwIDogZGlzdFt1XTxkaXN0W3ZdID8gLTEgOiAxOwogICAgICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgICAgIH0pOwogICAgICAgIHBxLmFkZChzKTsKCiAgICAgICAgd2hpbGUoIXBxLmlzRW1wdHkoKSl7CiAgICAgICAgICAgIGludCBjdXJyID0gcHEucG9sbCgpOwogICAgICAgICAgICBpZihjdXJyPT10KQogICAgICAgICAgICAgICAgY29udGludWU7CiAgICAgICAgICAgIGlmKGRpc3RbY3Vycl0+PUlORikKICAgICAgICAgICAgICAgIGJyZWFrOwogICAgICAgICAgICBWZXJ0ZXggdiA9IGdbY3Vycl07CiAgICAgICAgICAgIGZvcihFZGdlIGUgOiB2LmVkZ2VzKXsKICAgICAgICAgICAgICAgIGlmKGRpc3RbY3Vycl0rZS53dCA8IGRpc3RbZS50b10pewogICAgICAgICAgICAgICAgICAgIHBxLnJlbW92ZShlLnRvKTsKICAgICAgICAgICAgICAgICAgICBkaXN0W2UudG9dID0gZGlzdFtjdXJyXStlLnd0OwogICAgICAgICAgICAgICAgICAgIHByZXZbZS50b10gPSBlOwogICAgICAgICAgICAgICAgICAgIHBxLmFkZChlLnRvKTsKICAgICAgICAgICAgICAgIH0KICAgICAgICAgICAgfQogICAgICAgIH0KICAgICAgICByZXR1cm4gZGlzdDsKICAgIH0KfQoKY2xhc3MgUmVhZGVyewogICAgQnVmZmVyZWRSZWFkZXIgYnI7CiAgICBTdHJpbmdUb2tlbml6ZXIgc3Q7CiAgICBSZWFkZXIoSW5wdXRTdHJlYW0gaW4pIHRocm93cyBFeGNlcHRpb257CiAgICAgICAgYnIgPSBuZXcgQnVmZmVyZWRSZWFkZXIobmV3IElucHV0U3RyZWFtUmVhZGVyKGluKSk7CiAgICAgICAgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKCIiKTsKICAgIH0KCiAgICBTdHJpbmcgbmV4dCgpIHRocm93cyBFeGNlcHRpb257CiAgICAgICAgd2hpbGUoIXN0Lmhhc01vcmVUb2tlbnMoKSkKICAgICAgICAgICAgc3QgPSBuZXcgU3RyaW5nVG9rZW5pemVyKGJyLnJlYWRMaW5lKCkpOwogICAgICAgIHJldHVybiBzdC5uZXh0VG9rZW4oKTsKICAgIH0KCiAgICBpbnQgbmV4dEludCgpIHRocm93cyBFeGNlcHRpb257CiAgICAgICAgcmV0dXJuIEludGVnZXIucGFyc2VJbnQobmV4dCgpKTsKICAgIH0KCiAgICBkb3VibGUgbmV4dERvdWJsZSgpIHRocm93cyBFeGNlcHRpb257CiAgICAgICAgcmV0dXJuIERvdWJsZS5wYXJzZURvdWJsZShuZXh0KCkpOwogICAgfQp9