#include<bits/stdc++.h>
#include <unistd.h>
#include <sys/resource.h>
using namespace std;
#define sd(a) scanf("%d",&a)
#define ss(a) scanf("%s",a)
#define sl(a) scanf("%lld",&a)
#define clr(a) memset(a,0,sizeof(a))
#define debug(a) printf("check%d\n",a)
#define F first
#define S second
#define MP make_pair
#define PB push_back
#define ll long long
#define N 1000010
#define logn 20
vector<int> v[N], v1[N];
vector<int> tree[N],aux[N];
int a[N],cnt[N],var[N],val_var[N],var_cnt,result[N];
int lowest_prime[N], isprime[N];
int in[N], out[N], Time, p[N][logn], l[N], mark[N], in_to_id[N], comp[N], decomp[N];
int dummy_var[N];
int scc[N], scc_count;
vector<int> self_inverse[N];
vector<int> Out;
vector<int> order;
vector<int> List[N];
ll gcd(ll a,ll b)
{
ll t;
while(b!=0)
{
t=b;
b=a%b;
a=t;
}
return a;
}
int getphi(int n)
{
int result=0;
for(int i=1;i<=n;i++)
if(gcd(i,n)==1)
result++;
return result;
}
ll pow1(ll a,ll b,ll mod)
{
if(b==0) return 1%mod;
ll ret=pow1(a,b/2,mod);
ret=(ret*ret)%mod;
if(b&1) ret=(a*ret)%mod;
return ret;
}
int lca(int x,int y)
{
if(l[x]<l[y])
swap(x,y);
for(int i=logn-1;i>=0;--i)
if(l[p[x][i]]>=l[y])
x=p[x][i];
if(x==y)
return x;
for(int i=logn-1;i>=0;--i)
if(p[x][i]!=p[y][i])
{
x=p[x][i];
y=p[y][i];
}
return p[x][0];
}
void go(int cur, int par)
{
in[cur] = ++Time;
in_to_id[in[cur]] = cur;
p[cur][0] = par;
l[cur] = 1+l[par];
for(auto x:tree[cur])
if(x!=par)
go(x,cur);
out[cur] = Time;
}
int getNode(int var)
{
return abs(var)*2-(var>0);
}
int getVar(int node)
{
return (node+1)/2;
}
void add_edge(int x, int y)
{
v[x].PB(y);
v1[y].PB(x);
}
void insert_clause(int var1, int var2)
{
add_edge(getNode(-var1),getNode(var2));
add_edge(getNode(-var2),getNode(var1));
}
void scc_dfs1(int cur)
{
assert(cur>0);
mark[cur]=1;
for(auto x:v1[cur])
if(!mark[x])
scc_dfs1(x);
order.PB(cur);
}
void scc_dfs2(int cur)
{
assert(cur>0);
mark[cur]=1;
scc[cur] = scc_count;
if(result[getVar(cur)]==-1)
result[getVar(cur)] = (cur&1);
for(auto x:v[cur])
if(!mark[x])
scc_dfs2(x);
}
void clear_data(int LIM)
{
for(int i=0;i<=LIM;i++)
{
tree[i].clear();
v[i].clear();
v1[i].clear();
List[i].clear();
result[i] = -1;
self_inverse[i].clear();
cnt[i] = 0;
val_var[i] = 0;
var[i] = 0;
mark[i] = 0;
}
var_cnt=0;
Time = 0;
scc_count = 0;
order.clear();
Out.clear();
if(LIM > 100000)
cerr<<LIM<<'\n';
}
int main()
{
clear_data(N-1);
// freopen(inputfilenames[fno],"r",stdin);
// freopen(outputfilenames[fno],"w",stdout);
clock_t start = clock();
int t,i;
//******sieve*********
clr(isprime);
for(i=2;i<N;i++)
isprime[i]=1;
for(i=2;i<N;i++)
{
if(!isprime[i]) continue;
for(int j=i;j<N;j+=i)
{
if(!isprime[j]) continue;
isprime[j]=0;
lowest_prime[j]=i;
}
}
//********************
sd(t);
int n_sum = 0;
for(int tt=1;tt<=t;tt++)
{
int n;
sd(n);
n_sum += n;
assert(n>=2);
assert(n<=200000);
int PHI_N = getphi(n);
for(i=1;i<=n;i++)
{
sd(a[i]);
assert(a[i]>=1);
assert(a[i]<n);
cnt[a[i]]++;
}
for(i=1;i<=n;i++)
{
int inv = pow1(a[i],PHI_N-1,n);
if(gcd(a[i],n)!=1 || cnt[inv]==0) continue;
if(a[i] == inv)
self_inverse[a[i]].PB(i);
else
{
if(val_var[a[i]] == 0)
{
val_var[a[i]] = ++var_cnt;
val_var[inv] = -var_cnt;
}
var[i] = val_var[a[i]];
}
int x = a[i];
while(x>1)
{
int p = lowest_prime[x];
while(x%p==0)
x/=p;
List[p].PB(i);
}
}
int fail=0;
for(i=1;i<n;i++)
{
if((int)self_inverse[i].size()>2)
{
fail=1;
break;
}
if((int)self_inverse[i].size() == 2)
{
var[self_inverse[i][0]] = ++var_cnt;
var[self_inverse[i][1]] = -var_cnt;
}
}
for(i=0;i<n-1;i++)
{
int x,y;
sd(x);sd(y);
tree[x].PB(y);
tree[y].PB(x);
}
l[1] = -1;
go(1,1);
for(i=1;i<=n;i++)
assert(in[i]>=1);
if(fail)
{
printf("No\n");
clear_data(max(2*var_cnt,2*n));
continue;
}
for(int j=1;j<logn;j++)
for(i=1;i<=n;i++)
p[i][j] = p[p[i][j-1]][j-1];
for(i=2;i<n;i++)
{
if(List[i].size() < 2) continue;
vector<int> temp;
for(auto x:List[i])
{
mark[x] = 1;
temp.PB(in[x]);
}
sort(temp.begin(),temp.end());
for(int j=0;j+1<(int)List[i].size();j++)
temp.PB(in[lca(in_to_id[temp[j]],in_to_id[temp[j+1]])]);
set<int> sett(temp.begin(),temp.end());
stack<int> s;
for(int j=1;j<=(int)sett.size();++j)
aux[j].clear();
int comp_cnt=0;
bool f=0;
for(auto t:sett)
{
int x=in_to_id[t];
comp[x]=++comp_cnt;
decomp[comp_cnt]=x;
while(!s.empty())
{
int y=s.top();
if(in[x]>=in[y] && in[x]<=out[y])
break;
s.pop();
}
if(!s.empty())
aux[comp[s.top()]].PB(comp[x]);
s.push(x);
}
for(int j=1;j<=comp_cnt;j++)
dummy_var[j] = ++var_cnt;
for(int j=1;j<=comp_cnt;j++)
{
for(auto x:aux[j])
{
insert_clause(dummy_var[j],-dummy_var[x]);
if(mark[decomp[j]] && var[decomp[j]]!=0)
insert_clause(-var[decomp[j]],-dummy_var[x]);
}
if(mark[decomp[j]] && var[decomp[j]]!=0)
insert_clause(dummy_var[j],-var[decomp[j]]);
}
for(auto x:sett)
mark[in_to_id[x]]=0;
}
for(i=1;i<=2*var_cnt;i++)
{
if(mark[i]) continue;
scc_dfs1(i);
}
reverse(order.begin(),order.end());
clr(mark);
for(auto x:order)
{
if(mark[x]) continue;
++scc_count;
scc_dfs2(x);
}
for(i=1;i<=var_cnt;i++)
if(scc[getNode(i)] == scc[getNode(-i)])
fail=1;
for(i=1;i<=n;i++)
{
if(var[i] > 0 && result[var[i]])
Out.PB(i);
if(var[i] < 0 && !result[-var[i]])
Out.PB(i);
}
if(fail)
{
printf("No\n");
clear_data(max(2*var_cnt,2*n));
continue;
}
printf("Yes\n");
clear_data(max(2*var_cnt,2*n));
}
clock_t end = clock();
cerr <<"Time: " <<(double)(end-start)/CLOCKS_PER_SEC <<" seconds" <<endl;
assert(n_sum<=200000);
}
I2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI2luY2x1ZGUgPHVuaXN0ZC5oPgojaW5jbHVkZSA8c3lzL3Jlc291cmNlLmg+CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CgojZGVmaW5lIHNkKGEpIHNjYW5mKCIlZCIsJmEpCiNkZWZpbmUgc3MoYSkgc2NhbmYoIiVzIixhKQojZGVmaW5lIHNsKGEpIHNjYW5mKCIlbGxkIiwmYSkKI2RlZmluZSBjbHIoYSkgbWVtc2V0KGEsMCxzaXplb2YoYSkpCiNkZWZpbmUgZGVidWcoYSkgcHJpbnRmKCJjaGVjayVkXG4iLGEpCiNkZWZpbmUgRiBmaXJzdAojZGVmaW5lIFMgc2Vjb25kCiNkZWZpbmUgTVAgbWFrZV9wYWlyCiNkZWZpbmUgUEIgcHVzaF9iYWNrCiNkZWZpbmUgbGwgbG9uZyBsb25nCiNkZWZpbmUgTiAxMDAwMDEwCiNkZWZpbmUgbG9nbiAyMAp2ZWN0b3I8aW50PiB2W05dLCB2MVtOXTsKdmVjdG9yPGludD4gdHJlZVtOXSxhdXhbTl07CgppbnQgYVtOXSxjbnRbTl0sdmFyW05dLHZhbF92YXJbTl0sdmFyX2NudCxyZXN1bHRbTl07CmludCBsb3dlc3RfcHJpbWVbTl0sIGlzcHJpbWVbTl07CmludCBpbltOXSwgb3V0W05dLCBUaW1lLCBwW05dW2xvZ25dLCBsW05dLCBtYXJrW05dLCBpbl90b19pZFtOXSwgY29tcFtOXSwgZGVjb21wW05dOwppbnQgZHVtbXlfdmFyW05dOwppbnQgc2NjW05dLCBzY2NfY291bnQ7Cgp2ZWN0b3I8aW50PiBzZWxmX2ludmVyc2VbTl07CnZlY3RvcjxpbnQ+IE91dDsKdmVjdG9yPGludD4gb3JkZXI7CnZlY3RvcjxpbnQ+IExpc3RbTl07CgoKbGwgZ2NkKGxsIGEsbGwgYikKewoJbGwgdDsKCXdoaWxlKGIhPTApCgl7CgkJdD1iOwoJCWI9YSViOwoJCWE9dDsKCX0KCXJldHVybiBhOwp9CgppbnQgZ2V0cGhpKGludCBuKQp7CglpbnQgcmVzdWx0PTA7Cglmb3IoaW50IGk9MTtpPD1uO2krKykKCQlpZihnY2QoaSxuKT09MSkKCQkJcmVzdWx0Kys7CglyZXR1cm4gcmVzdWx0Owp9CgpsbCBwb3cxKGxsIGEsbGwgYixsbCBtb2QpCnsKCWlmKGI9PTApCXJldHVybiAxJW1vZDsKCWxsIHJldD1wb3cxKGEsYi8yLG1vZCk7CglyZXQ9KHJldCpyZXQpJW1vZDsKCWlmKGImMSkJcmV0PShhKnJldCklbW9kOwoJcmV0dXJuIHJldDsKfQoKaW50IGxjYShpbnQgeCxpbnQgeSkKewoJaWYobFt4XTxsW3ldKQoJCXN3YXAoeCx5KTsKCWZvcihpbnQgaT1sb2duLTE7aT49MDstLWkpCgkJaWYobFtwW3hdW2ldXT49bFt5XSkKCQkJeD1wW3hdW2ldOwoJaWYoeD09eSkKCQlyZXR1cm4geDsKCWZvcihpbnQgaT1sb2duLTE7aT49MDstLWkpCgkJaWYocFt4XVtpXSE9cFt5XVtpXSkKCQl7CgkJCXg9cFt4XVtpXTsKCQkJeT1wW3ldW2ldOwoJCX0KCXJldHVybiBwW3hdWzBdOwp9Cgp2b2lkIGdvKGludCBjdXIsIGludCBwYXIpCnsKCWluW2N1cl0gPSArK1RpbWU7Cglpbl90b19pZFtpbltjdXJdXSA9IGN1cjsKCXBbY3VyXVswXSA9IHBhcjsKCWxbY3VyXSA9IDErbFtwYXJdOwoJZm9yKGF1dG8geDp0cmVlW2N1cl0pCgkJaWYoeCE9cGFyKQoJCQlnbyh4LGN1cik7CglvdXRbY3VyXSA9IFRpbWU7Cn0KCmludCBnZXROb2RlKGludCB2YXIpCnsKCXJldHVybiBhYnModmFyKSoyLSh2YXI+MCk7Cn0KaW50IGdldFZhcihpbnQgbm9kZSkKewoJcmV0dXJuIChub2RlKzEpLzI7Cn0KCnZvaWQgYWRkX2VkZ2UoaW50IHgsIGludCB5KQp7Cgl2W3hdLlBCKHkpOwoJdjFbeV0uUEIoeCk7Cn0KCnZvaWQgaW5zZXJ0X2NsYXVzZShpbnQgdmFyMSwgaW50IHZhcjIpCnsKCWFkZF9lZGdlKGdldE5vZGUoLXZhcjEpLGdldE5vZGUodmFyMikpOwoJYWRkX2VkZ2UoZ2V0Tm9kZSgtdmFyMiksZ2V0Tm9kZSh2YXIxKSk7Cn0KCnZvaWQgc2NjX2RmczEoaW50IGN1cikKewoJYXNzZXJ0KGN1cj4wKTsKCW1hcmtbY3VyXT0xOwoJZm9yKGF1dG8geDp2MVtjdXJdKQoJCWlmKCFtYXJrW3hdKQoJCQlzY2NfZGZzMSh4KTsKCW9yZGVyLlBCKGN1cik7Cn0KCnZvaWQgc2NjX2RmczIoaW50IGN1cikKewoJYXNzZXJ0KGN1cj4wKTsKCW1hcmtbY3VyXT0xOwoJc2NjW2N1cl0gPSBzY2NfY291bnQ7CglpZihyZXN1bHRbZ2V0VmFyKGN1cildPT0tMSkKCQlyZXN1bHRbZ2V0VmFyKGN1cildID0gKGN1ciYxKTsKCWZvcihhdXRvIHg6dltjdXJdKQoJCWlmKCFtYXJrW3hdKQoJCQlzY2NfZGZzMih4KTsKfQoKdm9pZCBjbGVhcl9kYXRhKGludCBMSU0pCnsKCWZvcihpbnQgaT0wO2k8PUxJTTtpKyspCgl7CgkJdHJlZVtpXS5jbGVhcigpOwoJCXZbaV0uY2xlYXIoKTsKCQl2MVtpXS5jbGVhcigpOwoJCUxpc3RbaV0uY2xlYXIoKTsKCQlyZXN1bHRbaV0gPSAtMTsKCQlzZWxmX2ludmVyc2VbaV0uY2xlYXIoKTsKCQljbnRbaV0gPSAwOwoJCXZhbF92YXJbaV0gPSAwOwoJCXZhcltpXSA9IDA7CgkJbWFya1tpXSA9IDA7Cgl9CgkKCXZhcl9jbnQ9MDsKCglUaW1lID0gMDsKCglzY2NfY291bnQgPSAwOwoKCW9yZGVyLmNsZWFyKCk7CgoJT3V0LmNsZWFyKCk7CgoJaWYoTElNID4gMTAwMDAwKQoJCWNlcnI8PExJTTw8J1xuJzsKfQoKaW50IG1haW4oKQp7CgoJY2xlYXJfZGF0YShOLTEpOwoJLy8gZnJlb3BlbihpbnB1dGZpbGVuYW1lc1tmbm9dLCJyIixzdGRpbik7CgkvLyBmcmVvcGVuKG91dHB1dGZpbGVuYW1lc1tmbm9dLCJ3IixzdGRvdXQpOwoKCWNsb2NrX3Qgc3RhcnQgPSBjbG9jaygpOwoJaW50IHQsaTsKCS8vKioqKioqc2lldmUqKioqKioqKioKCWNscihpc3ByaW1lKTsKCWZvcihpPTI7aTxOO2krKykKCQlpc3ByaW1lW2ldPTE7Cglmb3IoaT0yO2k8TjtpKyspCgl7CgkJaWYoIWlzcHJpbWVbaV0pCWNvbnRpbnVlOwoJCWZvcihpbnQgaj1pO2o8TjtqKz1pKQoJCXsKCQkJaWYoIWlzcHJpbWVbal0pCWNvbnRpbnVlOwoJCQlpc3ByaW1lW2pdPTA7CgkJCWxvd2VzdF9wcmltZVtqXT1pOwoJCX0KCX0KCS8vKioqKioqKioqKioqKioqKioqKioKCglzZCh0KTsKCglpbnQgbl9zdW0gPSAwOwoKCWZvcihpbnQgdHQ9MTt0dDw9dDt0dCsrKQoJewoJCWludCBuOwoJCXNkKG4pOwoJCW5fc3VtICs9IG47CgkJYXNzZXJ0KG4+PTIpOwoJCWFzc2VydChuPD0yMDAwMDApOwoKCQlpbnQgUEhJX04gPSBnZXRwaGkobik7CgkJCgoJCWZvcihpPTE7aTw9bjtpKyspCgkJewoJCQlzZChhW2ldKTsKCQkJYXNzZXJ0KGFbaV0+PTEpOwoJCQlhc3NlcnQoYVtpXTxuKTsKCQkJY250W2FbaV1dKys7CgkJfQoJCQoJCWZvcihpPTE7aTw9bjtpKyspCgkJewoJCQlpbnQgaW52ID0gcG93MShhW2ldLFBISV9OLTEsbik7CgkJCWlmKGdjZChhW2ldLG4pIT0xIHx8IGNudFtpbnZdPT0wKQljb250aW51ZTsKCQkJCgkJCWlmKGFbaV0gPT0gaW52KQoJCQkJc2VsZl9pbnZlcnNlW2FbaV1dLlBCKGkpOwoJCQllbHNlCgkJCXsKCQkJCWlmKHZhbF92YXJbYVtpXV0gPT0gMCkKCQkJCXsKCQkJCQl2YWxfdmFyW2FbaV1dID0gKyt2YXJfY250OwoJCQkJCXZhbF92YXJbaW52XSA9IC12YXJfY250OwoJCQkJfQoJCQkJdmFyW2ldID0gdmFsX3ZhclthW2ldXTsKCQkJfQoJCQlpbnQgeCA9IGFbaV07CgkJCXdoaWxlKHg+MSkKCQkJewoJCQkJaW50IHAgPSBsb3dlc3RfcHJpbWVbeF07CgkJCQl3aGlsZSh4JXA9PTApCgkJCQkJeC89cDsKCQkJCUxpc3RbcF0uUEIoaSk7CgkJCX0KCQl9CgoJCWludCBmYWlsPTA7CgkJZm9yKGk9MTtpPG47aSsrKQoJCXsKCQkJaWYoKGludClzZWxmX2ludmVyc2VbaV0uc2l6ZSgpPjIpCgkJCXsKCQkJCWZhaWw9MTsKCQkJCWJyZWFrOwoJCQl9CgkJCWlmKChpbnQpc2VsZl9pbnZlcnNlW2ldLnNpemUoKSA9PSAyKQoJCQl7CgkJCQl2YXJbc2VsZl9pbnZlcnNlW2ldWzBdXSA9ICsrdmFyX2NudDsKCQkJCXZhcltzZWxmX2ludmVyc2VbaV1bMV1dID0gLXZhcl9jbnQ7CgkJCX0KCQl9CgkJCgkJZm9yKGk9MDtpPG4tMTtpKyspCgkJewoJCQlpbnQgeCx5OwoJCQlzZCh4KTtzZCh5KTsKCgkJCXRyZWVbeF0uUEIoeSk7CgkJCXRyZWVbeV0uUEIoeCk7CgkJfQoJCWxbMV0gPSAtMTsKCQlnbygxLDEpOwoJCWZvcihpPTE7aTw9bjtpKyspCgkJCWFzc2VydChpbltpXT49MSk7CgkJaWYoZmFpbCkKCQl7CgkJCXByaW50ZigiTm9cbiIpOwoJCQljbGVhcl9kYXRhKG1heCgyKnZhcl9jbnQsMipuKSk7CgkJCWNvbnRpbnVlOwoJCX0KCQlmb3IoaW50IGo9MTtqPGxvZ247aisrKQoJCQlmb3IoaT0xO2k8PW47aSsrKQoJCQkJcFtpXVtqXSA9IHBbcFtpXVtqLTFdXVtqLTFdOwoJCWZvcihpPTI7aTxuO2krKykKCQl7CgkJCWlmKExpc3RbaV0uc2l6ZSgpIDwgMikJY29udGludWU7CgkJCQoJCQl2ZWN0b3I8aW50PiB0ZW1wOwoJCQlmb3IoYXV0byB4Okxpc3RbaV0pCgkJCXsKCQkJCW1hcmtbeF0gPSAxOwoJCQkJdGVtcC5QQihpblt4XSk7CgkJCX0KCQkJCgkJCXNvcnQodGVtcC5iZWdpbigpLHRlbXAuZW5kKCkpOwoJCQlmb3IoaW50IGo9MDtqKzE8KGludClMaXN0W2ldLnNpemUoKTtqKyspCgkJCQl0ZW1wLlBCKGluW2xjYShpbl90b19pZFt0ZW1wW2pdXSxpbl90b19pZFt0ZW1wW2orMV1dKV0pOwoKCQkJc2V0PGludD4gc2V0dCh0ZW1wLmJlZ2luKCksdGVtcC5lbmQoKSk7CgkJCXN0YWNrPGludD4gczsKCgkJCWZvcihpbnQgaj0xO2o8PShpbnQpc2V0dC5zaXplKCk7KytqKQoJCQkJYXV4W2pdLmNsZWFyKCk7CgoJCQlpbnQgY29tcF9jbnQ9MDsKCQkJYm9vbCBmPTA7CgkJCWZvcihhdXRvIHQ6c2V0dCkKCQkJewoJCQkJaW50IHg9aW5fdG9faWRbdF07CgkJCQljb21wW3hdPSsrY29tcF9jbnQ7CgkJCQlkZWNvbXBbY29tcF9jbnRdPXg7CgkJCQl3aGlsZSghcy5lbXB0eSgpKQoJCQkJewoJCQkJCWludCB5PXMudG9wKCk7CgkJCQkJaWYoaW5beF0+PWluW3ldICYmIGluW3hdPD1vdXRbeV0pCgkJCQkJCWJyZWFrOwoJCQkJCXMucG9wKCk7CgkJCQl9CgkJCQlpZighcy5lbXB0eSgpKQoJCQkJCWF1eFtjb21wW3MudG9wKCldXS5QQihjb21wW3hdKTsKCQkJCXMucHVzaCh4KTsKCQkJfQoJCQlmb3IoaW50IGo9MTtqPD1jb21wX2NudDtqKyspCgkJCQlkdW1teV92YXJbal0gPSArK3Zhcl9jbnQ7CgkJCWZvcihpbnQgaj0xO2o8PWNvbXBfY250O2orKykKCQkJewoJCQkJZm9yKGF1dG8geDphdXhbal0pCgkJCQl7CgkJCQkJaW5zZXJ0X2NsYXVzZShkdW1teV92YXJbal0sLWR1bW15X3Zhclt4XSk7CgkJCQkJaWYobWFya1tkZWNvbXBbal1dICYmIHZhcltkZWNvbXBbal1dIT0wKQoJCQkJCQlpbnNlcnRfY2xhdXNlKC12YXJbZGVjb21wW2pdXSwtZHVtbXlfdmFyW3hdKTsKCQkJCX0KCQkJCWlmKG1hcmtbZGVjb21wW2pdXSAmJiB2YXJbZGVjb21wW2pdXSE9MCkKCQkJCQlpbnNlcnRfY2xhdXNlKGR1bW15X3ZhcltqXSwtdmFyW2RlY29tcFtqXV0pOwoKCQkJfQoJCQlmb3IoYXV0byB4OnNldHQpCgkJCQltYXJrW2luX3RvX2lkW3hdXT0wOwoJCX0KCQlmb3IoaT0xO2k8PTIqdmFyX2NudDtpKyspCgkJewoJCQlpZihtYXJrW2ldKQljb250aW51ZTsKCQkJc2NjX2RmczEoaSk7CgkJfQoJCXJldmVyc2Uob3JkZXIuYmVnaW4oKSxvcmRlci5lbmQoKSk7CgkJY2xyKG1hcmspOwoJCWZvcihhdXRvIHg6b3JkZXIpCgkJewoJCQlpZihtYXJrW3hdKQljb250aW51ZTsKCQkJKytzY2NfY291bnQ7CgkJCXNjY19kZnMyKHgpOwoJCX0KCQlmb3IoaT0xO2k8PXZhcl9jbnQ7aSsrKQoJCQlpZihzY2NbZ2V0Tm9kZShpKV0gPT0gc2NjW2dldE5vZGUoLWkpXSkKCQkJCWZhaWw9MTsKCQlmb3IoaT0xO2k8PW47aSsrKQoJCXsKCQkJaWYodmFyW2ldID4gMCAmJiByZXN1bHRbdmFyW2ldXSkKCQkJCU91dC5QQihpKTsKCQkJaWYodmFyW2ldIDwgMCAmJiAhcmVzdWx0Wy12YXJbaV1dKQoJCQkJT3V0LlBCKGkpOwoJCX0KCQlpZihmYWlsKQoJCXsKCQkJcHJpbnRmKCJOb1xuIik7CgkJCWNsZWFyX2RhdGEobWF4KDIqdmFyX2NudCwyKm4pKTsKCQkJY29udGludWU7CgkJfQoJCXByaW50ZigiWWVzXG4iKTsKCQljbGVhcl9kYXRhKG1heCgyKnZhcl9jbnQsMipuKSk7CgoJfQoJY2xvY2tfdCBlbmQgPSBjbG9jaygpOwoJY2VyciA8PCJUaW1lOiAiIDw8KGRvdWJsZSkoZW5kLXN0YXJ0KS9DTE9DS1NfUEVSX1NFQyA8PCIgc2Vjb25kcyIgPDxlbmRsOwoJYXNzZXJ0KG5fc3VtPD0yMDAwMDApOwp9