/* Creation Date - 30-01-2023 */
/* Creation Time - 21:13:32.27 */
#define ill
/*
Written By : mafailure
In the name of God
O Allah, May you grant peace and honor on Muhammad and his family.
Allahumm-a-Sall-iAla Muhammad-in Wa Al-i Muhammad
*/
#ifdef LOCAL
#define AATIF_DEBUG
#endif
/*Add -DLOCAL in
compiler command
to trigger it*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#include <functional> // for less
using namespace std;
using namespace __gnu_pbds;
#define IOS ios::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define endl "\n"
/*------------------------int to long long -----------------*/
#ifdef ill
#define int long long
#endif
/*---------------------------DEBUG HELPER--------------------------------------*/
template<typename T> ostream& operator<<(ostream &os, const vector<T> &v) { os << '{'; string sep; for (const auto &x : v) os << sep << x, sep = ", "; return os << '}'; }
template<typename T, size_t size> ostream& operator<<(ostream &os, const array<T, size> &arr) { os << '{'; string sep; for (const auto &x : arr) os << sep << x, sep = ", "; return os << '}'; }
template<typename A, typename B> ostream& operator<<(ostream &os, const pair<A, B> &p) { return os << '(' << p.first << ", " << p.second << ')'; }
template<typename T,typename K> ostream& operator<<(ostream & os,const map<T,K> & mapp){ os<<"{"; string sep=""; for(const auto& x:mapp)os<<sep<<x,sep=", "; return os<<'}'; }
template <typename T> ostream & operator<<(ostream & os,const set<T> & sett){os<<'{'; string sep=""; for(const auto & x:sett)os<<sep<<x,sep=", "; return os<<'}';}
void dbg_out() { cerr << endl; }
template<typename Head, typename... Tail> void dbg_out(Head H, Tail... T) { cerr << ' ' << H; dbg_out(T...); }
#ifdef AATIF_DEBUG
#define dbg(...) cerr << "(" << #__VA_ARGS__ << "):", dbg_out(__VA_ARGS__)
#else
#define dbg(...)
#endif
//#define int long long
// int dx[]={-1,1,0,0}; int dy[]={0,0,1,-1};
// int dx[]={2,2,-2,-2,1,1,-1,-1}; int dy[]={1,-1,1,-1,2,-2,2,-2};
#ifndef mod_2
long long mod = 1e9 + 7;
#else
long long mod =998244353;
#endif
const double eps=1e-9;
typedef vector<int> vi;
typedef vector<vi> vvi;
typedef vector<string> vs;
typedef vector<bool> vb;
typedef pair<int, int> ii;
typedef vector< pair< int, int > > vii;
typedef map<int, int> mii;
typedef pair<int, ii> pip;
typedef pair<ii, int> ppi;
#define arrinp(arr,init,final,size,type) type* arr=new type[size];for(int i=init;i<final;i++)cin>>arr[i];
#define cr2d(arr,n,m,t) t**arr=new t*[n];for(int i=0;i<n;i++)arr[i]=new t[m];
#define w(t) int t;cin>>t; while(t--)
#define takeInp(n) int n;cin>>n;
#define fr(i,init,final) for(int i=init;i<final;i++)
#define frr(i,init,final) for(int i=init;i>=final;i--)
#define Fr(i,final) for(int i=0;i<final;i++)
#define Frr(i,first) for(int i=first;i>=0;i--)
#define fi first
#define se second
#define mp make_pair
#define pb push_back
#define all(c) (c).begin(),(c).end()
#define rall(c) (c).rbegin(),(c).rend()
#define debug(x) cerr<<">value ("<<#x<<") : "<<x<<endl;
#define setb __builtin_popcount
#define lsone(n) (n&(-n))
#define rlsone(n) (n&(n-1))
#define clr(a,b) memset(a,b,sizeof(a))
#ifdef ill
const int inf =1e18;
#else
const int inf=1e9;
#endif
/*-----------------------------RANDOM NUMBER GENERATOR ---------------------*/
#ifdef RNG
unsigned seed=chrono::high_resolution_clock::now().time_since_epoch().count();
mt19937 rng(seed);
#endif
/*------------------------------UNORDERED MAP HASH --------------------------------------------*/
//To make unordered_map unhackable
// use it as unordered_map<int,int,custom_hash> mapp;
struct custom_hash {
static uint64_t splitmix64(uint64_t x) {
/* http://x...content-available-to-author-only...i.it/splitmix64.c */
x += 0x9e3779b97f4a7c15;
x = (x ^ (x >> 30)) * 0xbf58476d1ce4e5b9;
x = (x ^ (x >> 27)) * 0x94d049bb133111eb;
return x ^ (x >> 31);
}
size_t operator()(uint64_t x) const {
static const uint64_t FIXED_RANDOM = chrono::steady_clock::now().time_since_epoch().count();
return splitmix64(x + FIXED_RANDOM);
}
};
/*---------------------------ORDERED SET--------------------------------------*/
typedef tree<int, null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
/*----------------------------------------------------------------------------*/
vi init(string s)
{
istringstream sin(s);
int n;
vi arr;
while(sin>>n)arr.push_back(n);
return arr;
}
int power(int x, int y,int mod)
{
if(y==0)return 1;
int u=power(x,y/2,mod);
u=(u*u)%mod;
if(y%2)u=(x*u)%mod;
return u;
}
int gcd(int a,int b)
{
if(a<b)return gcd(b,a);
return (b==0?a:(a%b?gcd(b,a%b):b));
}
int gcd_e(int a,int b,int &x,int &y)
{
if(b==0){x=1; y=0; return a;}
int x1,y1;
int p=gcd_e(b,a%b,x1,y1);
x=y1;
y=x1-(a/b)*y1;
return p;
}
/*-----------------to solve int to long long problem-----------------*/
int Min (int a,int b){return min(a,b);}
int Max(int a,int b){ return max(a,b);}
inline int add(int a,int b,int mod=mod){return (a+b)%mod;}
inline int sub(int a,int b,int mod=mod){return (a-b+mod)%mod;}
inline int mul(int a,int b,int mod=mod){return (a*b%mod);}
inline int divide(int a,int b,int mod=mod){return a*power(b,mod-2,mod)%mod;}
inline int high(int a,int b){return (a>>b)&1;}
//786 121 786 121 786 121 786 121 786 121 786 121 786 121 786 121 786 121
/*========================CODE*****CODE****CODE======================*/
/*
Use Code submitted in ARC 60 F
*/
template<const int X=2>
class StringHashing
{
using T=array<int,X> ;
public:
function<T(int,int)> get_sub;
function<bool(int,int,int,int)> match_two_sub;
vector<T> hash,pp,ipp;
T p,ip,mod;
StringHashing(int N)
{
/*TODO Base values of mod, p, ip needs to be updated if you are using different X*/
mod={(int)1e9+7,(int)1e8+7};
p={37,43};
ip={power(p[0],mod[0]-2,mod[0]),power(p[1],mod[1]-2,mod[1])};
T base_val;
base_val.fill(1);
pp=vector<T>(N,base_val);
ipp=vector<T>(N,base_val);
for(int i=1;i<N;i++)
{
for(int j=0;j<X;j++)
{
pp[i][j]=mul(pp[i-1][j],p[j],mod[j]);
ipp[i][j]=mul(ipp[i-1][j],ip[j],mod[j]);
}
}
}
};
signed main()
{
IOS
using T=array<int,2>;
w(TC)
{
int n;
cin>>n;
vector<char> a(n);
fr(i,0,n)cin>>a[i];
StringHashing<> helper(n+5);
vector<T>hash(n);
vvi g(n);
fr(i,0,n-1){
int u,v; cin>>u>>v; u--; v--; g[u].pb(v);
g[v].pb(u);}
function<void(int,int,int,T)>pre=[&](int u,int p,int dep,T h)
{
fr(i,0,2){
hash[u][i]=add(h[i],mul((a[u]-'a'+1),helper.pp[dep][i],helper.mod[i]),helper.mod[i]);
}
for(auto v:g[u])
{
if(v!=p)pre(v,u,dep+1,hash[u]);
}
};
pre(0,-1,1,T({0,0}));
vector<map<pair<int,int>,int>> mapp(n);
vector<int> ans(n);
function<void(int,int)> dfs=[&](int u,int p)
{
ans[u]=1;
mapp[u][mp(hash[u][0],hash[u][1])]++;
for(auto v:g[u]){
if(v==p)continue;
dfs(v,u);
for(auto &it: mapp[v])
{
ans[u]+=it.se*mapp[u][it.fi];
mapp[u][it.fi]+=it.se;
}
}
};
dfs(0,-1);
int q;
cin>>q;
fr(i,0,q)
{
int u;
cin>>u;
u--;
cout<<ans[u]<<endl;
}
}
}
LyogQ3JlYXRpb24gRGF0ZSAtIDMwLTAxLTIwMjMgKi8gIAovKiBDcmVhdGlvbiBUaW1lIC0gMjE6MTM6MzIuMjcgKi8gIAojZGVmaW5lIGlsbCAKLyoKV3JpdHRlbiBCeSA6IG1hZmFpbHVyZQpJbiB0aGUgbmFtZSBvZiBHb2QgCk8gQWxsYWgsIE1heSB5b3UgZ3JhbnQgcGVhY2UgYW5kIGhvbm9yIG9uIE11aGFtbWFkIGFuZCBoaXMgZmFtaWx5LgpBbGxhaHVtbS1hLVNhbGwtaUFsYSBNdWhhbW1hZC1pbiBXYSBBbC1pIE11aGFtbWFkCiovCgojaWZkZWYgTE9DQUwgCiNkZWZpbmUgQUFUSUZfREVCVUcKI2VuZGlmIAovKkFkZCAtRExPQ0FMIGluIApjb21waWxlciBjb21tYW5kIAp0byB0cmlnZ2VyIGl0Ki8KICAKI2luY2x1ZGU8Yml0cy9zdGRjKysuaD4KI2luY2x1ZGUgPGV4dC9wYl9kcy9hc3NvY19jb250YWluZXIuaHBwPiAvLyBDb21tb24gZmlsZSAKI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+IAojaW5jbHVkZSA8ZnVuY3Rpb25hbD4gLy8gZm9yIGxlc3MKdXNpbmcgbmFtZXNwYWNlIHN0ZDsKdXNpbmcgbmFtZXNwYWNlIF9fZ251X3BiZHM7CiNkZWZpbmUgSU9TIGlvczo6c3luY193aXRoX3N0ZGlvKDApO2Npbi50aWUoMCk7Y291dC50aWUoMCk7CiAKI2RlZmluZSBlbmRsICJcbiIKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1pbnQgdG8gbG9uZyBsb25nIC0tLS0tLS0tLS0tLS0tLS0tKi8KI2lmZGVmIGlsbAojZGVmaW5lIGludCBsb25nIGxvbmcgCiNlbmRpZgovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLURFQlVHIEhFTFBFUi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tKi8KdGVtcGxhdGU8dHlwZW5hbWUgVD4gb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtICZvcywgY29uc3QgdmVjdG9yPFQ+ICZ2KSB7IG9zIDw8ICd7Jzsgc3RyaW5nIHNlcDsgZm9yIChjb25zdCBhdXRvICZ4IDogdikgb3MgPDwgc2VwIDw8IHgsIHNlcCA9ICIsICI7IHJldHVybiBvcyA8PCAnfSc7IH0KdGVtcGxhdGU8dHlwZW5hbWUgVCwgc2l6ZV90IHNpemU+IG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSAmb3MsIGNvbnN0IGFycmF5PFQsIHNpemU+ICZhcnIpIHsgb3MgPDwgJ3snOyBzdHJpbmcgc2VwOyBmb3IgKGNvbnN0IGF1dG8gJnggOiBhcnIpIG9zIDw8IHNlcCA8PCB4LCBzZXAgPSAiLCAiOyByZXR1cm4gb3MgPDwgJ30nOyB9CnRlbXBsYXRlPHR5cGVuYW1lIEEsIHR5cGVuYW1lIEI+IG9zdHJlYW0mIG9wZXJhdG9yPDwob3N0cmVhbSAmb3MsIGNvbnN0IHBhaXI8QSwgQj4gJnApIHsgcmV0dXJuIG9zIDw8ICcoJyA8PCBwLmZpcnN0IDw8ICIsICIgPDwgcC5zZWNvbmQgPDwgJyknOyB9CnRlbXBsYXRlPHR5cGVuYW1lIFQsdHlwZW5hbWUgSz4gb3N0cmVhbSYgb3BlcmF0b3I8PChvc3RyZWFtICYgb3MsY29uc3QgbWFwPFQsSz4gJiBtYXBwKXsgb3M8PCJ7Ijsgc3RyaW5nIHNlcD0iIjsgZm9yKGNvbnN0IGF1dG8mIHg6bWFwcClvczw8c2VwPDx4LHNlcD0iLCAiOyByZXR1cm4gb3M8PCd9JzsgfQp0ZW1wbGF0ZSA8dHlwZW5hbWUgVD4gb3N0cmVhbSAmIG9wZXJhdG9yPDwob3N0cmVhbSAmIG9zLGNvbnN0IHNldDxUPiAmIHNldHQpe29zPDwneyc7IHN0cmluZyBzZXA9IiI7IGZvcihjb25zdCBhdXRvICYgeDpzZXR0KW9zPDxzZXA8PHgsc2VwPSIsICI7IHJldHVybiBvczw8J30nO30KIAp2b2lkIGRiZ19vdXQoKSB7IGNlcnIgPDwgZW5kbDsgfQp0ZW1wbGF0ZTx0eXBlbmFtZSBIZWFkLCB0eXBlbmFtZS4uLiBUYWlsPiB2b2lkIGRiZ19vdXQoSGVhZCBILCBUYWlsLi4uIFQpIHsgY2VyciA8PCAnICcgPDwgSDsgZGJnX291dChULi4uKTsgfQogCiNpZmRlZiBBQVRJRl9ERUJVRwojZGVmaW5lIGRiZyguLi4pIGNlcnIgPDwgIigiIDw8ICNfX1ZBX0FSR1NfXyA8PCAiKToiLCBkYmdfb3V0KF9fVkFfQVJHU19fKQojZWxzZQojZGVmaW5lIGRiZyguLi4pCiNlbmRpZgogCi8vI2RlZmluZSBpbnQgbG9uZyBsb25nIAovLyBpbnQgZHhbXT17LTEsMSwwLDB9OyBpbnQgZHlbXT17MCwwLDEsLTF9OwovLyBpbnQgZHhbXT17MiwyLC0yLC0yLDEsMSwtMSwtMX07IGludCBkeVtdPXsxLC0xLDEsLTEsMiwtMiwyLC0yfTsKI2lmbmRlZiBtb2RfMiAKbG9uZyBsb25nIG1vZCA9IDFlOSArIDc7CiNlbHNlIApsb25nIGxvbmcgbW9kID05OTgyNDQzNTM7IAojZW5kaWYgCmNvbnN0IGRvdWJsZSBlcHM9MWUtOTsKdHlwZWRlZiB2ZWN0b3I8aW50PiB2aTsKdHlwZWRlZiB2ZWN0b3I8dmk+IHZ2aTsKdHlwZWRlZiB2ZWN0b3I8c3RyaW5nPiB2czsKdHlwZWRlZiB2ZWN0b3I8Ym9vbD4gdmI7CnR5cGVkZWYgcGFpcjxpbnQsIGludD4gaWk7CnR5cGVkZWYgdmVjdG9yPCBwYWlyPCBpbnQsIGludCA+ID4gdmlpOwp0eXBlZGVmIG1hcDxpbnQsIGludD4gbWlpOwp0eXBlZGVmIHBhaXI8aW50LCBpaT4gcGlwOwp0eXBlZGVmIHBhaXI8aWksIGludD4gcHBpOwojZGVmaW5lIGFycmlucChhcnIsaW5pdCxmaW5hbCxzaXplLHR5cGUpIHR5cGUqIGFycj1uZXcgdHlwZVtzaXplXTtmb3IoaW50IGk9aW5pdDtpPGZpbmFsO2krKyljaW4+PmFycltpXTsKI2RlZmluZSBjcjJkKGFycixuLG0sdCkgdCoqYXJyPW5ldyB0KltuXTtmb3IoaW50IGk9MDtpPG47aSsrKWFycltpXT1uZXcgdFttXTsKI2RlZmluZSB3KHQpIGludCB0O2Npbj4+dDsgd2hpbGUodC0tKQojZGVmaW5lIHRha2VJbnAobikgaW50IG47Y2luPj5uOwojZGVmaW5lIGZyKGksaW5pdCxmaW5hbCkgZm9yKGludCBpPWluaXQ7aTxmaW5hbDtpKyspCiNkZWZpbmUgZnJyKGksaW5pdCxmaW5hbCkgZm9yKGludCBpPWluaXQ7aT49ZmluYWw7aS0tKQojZGVmaW5lIEZyKGksZmluYWwpIGZvcihpbnQgaT0wO2k8ZmluYWw7aSsrKQojZGVmaW5lIEZycihpLGZpcnN0KSBmb3IoaW50IGk9Zmlyc3Q7aT49MDtpLS0pCiNkZWZpbmUgZmkgZmlyc3QKI2RlZmluZSBzZSBzZWNvbmQKI2RlZmluZSBtcCBtYWtlX3BhaXIKI2RlZmluZSBwYiBwdXNoX2JhY2sKI2RlZmluZSBhbGwoYykgKGMpLmJlZ2luKCksKGMpLmVuZCgpCiNkZWZpbmUgcmFsbChjKSAoYykucmJlZ2luKCksKGMpLnJlbmQoKQojZGVmaW5lIGRlYnVnKHgpIGNlcnI8PCI+dmFsdWUgKCI8PCN4PDwiKSA6ICI8PHg8PGVuZGw7CiNkZWZpbmUgc2V0YiBfX2J1aWx0aW5fcG9wY291bnQKI2RlZmluZSBsc29uZShuKSAobiYoLW4pKQojZGVmaW5lIHJsc29uZShuKSAobiYobi0xKSkKI2RlZmluZSBjbHIoYSxiKSBtZW1zZXQoYSxiLHNpemVvZihhKSkKI2lmZGVmIGlsbCAKY29uc3QgaW50IGluZiA9MWUxODsgCiNlbHNlIApjb25zdCBpbnQgaW5mPTFlOTsKI2VuZGlmCi8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1SQU5ET00gTlVNQkVSIEdFTkVSQVRPUiAtLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwojaWZkZWYgUk5HIAp1bnNpZ25lZCBzZWVkPWNocm9ubzo6aGlnaF9yZXNvbHV0aW9uX2Nsb2NrOjpub3coKS50aW1lX3NpbmNlX2Vwb2NoKCkuY291bnQoKTsKbXQxOTkzNyBybmcoc2VlZCk7CiNlbmRpZiAKLyotLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS1VTk9SREVSRUQgTUFQIEhBU0ggLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwovL1RvIG1ha2UgdW5vcmRlcmVkX21hcCB1bmhhY2thYmxlIAovLyB1c2UgaXQgYXMgdW5vcmRlcmVkX21hcDxpbnQsaW50LGN1c3RvbV9oYXNoPiBtYXBwOwpzdHJ1Y3QgY3VzdG9tX2hhc2ggewogICAgc3RhdGljIHVpbnQ2NF90IHNwbGl0bWl4NjQodWludDY0X3QgeCkgewogICAgICAgIC8qIGh0dHA6Ly94Li4uY29udGVudC1hdmFpbGFibGUtdG8tYXV0aG9yLW9ubHkuLi5pLml0L3NwbGl0bWl4NjQuYyAqLwogICAgICAgIHggKz0gMHg5ZTM3NzliOTdmNGE3YzE1OwogICAgICAgIHggPSAoeCBeICh4ID4+IDMwKSkgKiAweGJmNTg0NzZkMWNlNGU1Yjk7CiAgICAgICAgeCA9ICh4IF4gKHggPj4gMjcpKSAqIDB4OTRkMDQ5YmIxMzMxMTFlYjsKICAgICAgICByZXR1cm4geCBeICh4ID4+IDMxKTsKICAgIH0KIAogICAgc2l6ZV90IG9wZXJhdG9yKCkodWludDY0X3QgeCkgY29uc3QgewogICAgICAgIHN0YXRpYyBjb25zdCB1aW50NjRfdCBGSVhFRF9SQU5ET00gPSBjaHJvbm86OnN0ZWFkeV9jbG9jazo6bm93KCkudGltZV9zaW5jZV9lcG9jaCgpLmNvdW50KCk7CiAgICAgICAgcmV0dXJuIHNwbGl0bWl4NjQoeCArIEZJWEVEX1JBTkRPTSk7CiAgICB9Cn07Ci8qLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tT1JERVJFRCBTRVQtLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLSovCnR5cGVkZWYgdHJlZTxpbnQsIG51bGxfdHlwZSwgbGVzczxpbnQ+LCByYl90cmVlX3RhZywgdHJlZV9vcmRlcl9zdGF0aXN0aWNzX25vZGVfdXBkYXRlPiAgb3JkZXJlZF9zZXQ7IAovKi0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0qLwp2aSBpbml0KHN0cmluZyBzKQp7Cglpc3RyaW5nc3RyZWFtIHNpbihzKTsKCWludCBuOwoJdmkgYXJyOwoJd2hpbGUoc2luPj5uKWFyci5wdXNoX2JhY2sobik7CglyZXR1cm4gYXJyOwp9CmludCBwb3dlcihpbnQgeCwgaW50IHksaW50IG1vZCkKeyAKCWlmKHk9PTApcmV0dXJuIDE7CglpbnQgdT1wb3dlcih4LHkvMixtb2QpOwoJdT0odSp1KSVtb2Q7CglpZih5JTIpdT0oeCp1KSVtb2Q7CglyZXR1cm4gdTsKICAgIAp9CmludCBnY2QoaW50IGEsaW50IGIpCnsKCWlmKGE8YilyZXR1cm4gZ2NkKGIsYSk7CglyZXR1cm4gKGI9PTA/YTooYSViP2djZChiLGElYik6YikpOwp9CmludCBnY2RfZShpbnQgYSxpbnQgYixpbnQgJngsaW50ICZ5KQp7CgkKCWlmKGI9PTApe3g9MTsgeT0wOyByZXR1cm4gYTt9CglpbnQgeDEseTE7CglpbnQgcD1nY2RfZShiLGElYix4MSx5MSk7Cgl4PXkxOwoJeT14MS0oYS9iKSp5MTsKCXJldHVybiBwOwp9Ci8qLS0tLS0tLS0tLS0tLS0tLS10byBzb2x2ZSBpbnQgdG8gbG9uZyBsb25nIHByb2JsZW0tLS0tLS0tLS0tLS0tLS0tLSovCmludCBNaW4gKGludCBhLGludCBiKXtyZXR1cm4gbWluKGEsYik7fQppbnQgTWF4KGludCBhLGludCBiKXsgcmV0dXJuIG1heChhLGIpO30KaW5saW5lIGludCBhZGQoaW50IGEsaW50IGIsaW50IG1vZD1tb2Qpe3JldHVybiAoYStiKSVtb2Q7fSAKaW5saW5lIGludCBzdWIoaW50IGEsaW50IGIsaW50IG1vZD1tb2Qpe3JldHVybiAoYS1iK21vZCklbW9kO30KaW5saW5lIGludCBtdWwoaW50IGEsaW50IGIsaW50IG1vZD1tb2Qpe3JldHVybiAoYSpiJW1vZCk7fQppbmxpbmUgaW50IGRpdmlkZShpbnQgYSxpbnQgYixpbnQgbW9kPW1vZCl7cmV0dXJuIGEqcG93ZXIoYixtb2QtMixtb2QpJW1vZDt9CmlubGluZSBpbnQgaGlnaChpbnQgYSxpbnQgYil7cmV0dXJuIChhPj5iKSYxO30KLy83ODYgMTIxIDc4NiAxMjEgNzg2IDEyMSA3ODYgMTIxIDc4NiAxMjEgNzg2IDEyMSA3ODYgMTIxIDc4NiAxMjEgNzg2IDEyMQovKj09PT09PT09PT09PT09PT09PT09PT09PUNPREUqKioqKkNPREUqKioqQ09ERT09PT09PT09PT09PT09PT09PT09PT0qLwoKLyoKIFVzZSBDb2RlIHN1Ym1pdHRlZCBpbiBBUkMgNjAgRgoqLwoKCnRlbXBsYXRlPGNvbnN0IGludCBYPTI+IApjbGFzcyBTdHJpbmdIYXNoaW5nCnsKCXVzaW5nIFQ9YXJyYXk8aW50LFg+IDsgCglwdWJsaWM6IAoJZnVuY3Rpb248VChpbnQsaW50KT4gZ2V0X3N1YjsgCglmdW5jdGlvbjxib29sKGludCxpbnQsaW50LGludCk+IG1hdGNoX3R3b19zdWI7IAoJdmVjdG9yPFQ+IGhhc2gscHAsaXBwOyAKCVQgcCxpcCxtb2Q7IAoJU3RyaW5nSGFzaGluZyhpbnQgTikKCXsKCQkvKlRPRE8gQmFzZSB2YWx1ZXMgb2YgbW9kLCBwLCBpcCBuZWVkcyB0byBiZSB1cGRhdGVkIGlmIHlvdSBhcmUgdXNpbmcgZGlmZmVyZW50IFgqLwoJCW1vZD17KGludCkxZTkrNywoaW50KTFlOCs3fTsgCgkJcD17MzcsNDN9OyAKCQlpcD17cG93ZXIocFswXSxtb2RbMF0tMixtb2RbMF0pLHBvd2VyKHBbMV0sbW9kWzFdLTIsbW9kWzFdKX07IAoJCVQgYmFzZV92YWw7IAoJCWJhc2VfdmFsLmZpbGwoMSk7IAoJICAgIHBwPXZlY3RvcjxUPihOLGJhc2VfdmFsKTsgCgkgICAgaXBwPXZlY3RvcjxUPihOLGJhc2VfdmFsKTsgCgkJZm9yKGludCBpPTE7aTxOO2krKykKCQl7CgkJCWZvcihpbnQgaj0wO2o8WDtqKyspCgkJCXsKCQkJCXBwW2ldW2pdPW11bChwcFtpLTFdW2pdLHBbal0sbW9kW2pdKTsgCgkJCQlpcHBbaV1bal09bXVsKGlwcFtpLTFdW2pdLGlwW2pdLG1vZFtqXSk7IAoJCQl9CgkJfQoJfQoJCgkKfTsKc2lnbmVkIG1haW4oKQp7CglJT1MKCXVzaW5nIFQ9YXJyYXk8aW50LDI+OyAKCXcoVEMpCgl7CgkJaW50IG47IAoJCWNpbj4+bjsgCgkJdmVjdG9yPGNoYXI+IGEobik7IAoJCWZyKGksMCxuKWNpbj4+YVtpXTsKCQlTdHJpbmdIYXNoaW5nPD4gaGVscGVyKG4rNSk7CgkJdmVjdG9yPFQ+aGFzaChuKTsgCgkJdnZpIGcobik7IAoJCWZyKGksMCxuLTEpewoJCWludCB1LHY7IGNpbj4+dT4+djsgdS0tOyB2LS07IGdbdV0ucGIodik7IAoJCWdbdl0ucGIodSk7fQoJCQoJCWZ1bmN0aW9uPHZvaWQoaW50LGludCxpbnQsVCk+cHJlPVsmXShpbnQgdSxpbnQgcCxpbnQgZGVwLFQgaCkKCQl7CgkJCWZyKGksMCwyKXsKCQkJaGFzaFt1XVtpXT1hZGQoaFtpXSxtdWwoKGFbdV0tJ2EnKzEpLGhlbHBlci5wcFtkZXBdW2ldLGhlbHBlci5tb2RbaV0pLGhlbHBlci5tb2RbaV0pOwoJCQl9CgkJCWZvcihhdXRvIHY6Z1t1XSkKCQkJewoJCQkJaWYodiE9cClwcmUodix1LGRlcCsxLGhhc2hbdV0pOyAKCQkJfQoJCQkKCQl9OwoJCXByZSgwLC0xLDEsVCh7MCwwfSkpOyAKCQl2ZWN0b3I8bWFwPHBhaXI8aW50LGludD4saW50Pj4gbWFwcChuKTsgCgkJdmVjdG9yPGludD4gYW5zKG4pOyAKCQlmdW5jdGlvbjx2b2lkKGludCxpbnQpPiBkZnM9WyZdKGludCB1LGludCBwKQoJCXsKCQkJYW5zW3VdPTE7CgkJCW1hcHBbdV1bbXAoaGFzaFt1XVswXSxoYXNoW3VdWzFdKV0rKzsKCQkJZm9yKGF1dG8gdjpnW3VdKXsKCQkJCWlmKHY9PXApY29udGludWU7CgkJCQlkZnModix1KTsKCQkJCWZvcihhdXRvICZpdDogbWFwcFt2XSkKCQkJCXsKCQkJCQlhbnNbdV0rPWl0LnNlKm1hcHBbdV1baXQuZmldOyAKCQkJCQltYXBwW3VdW2l0LmZpXSs9aXQuc2U7ICAKCQkJCX0KCQkJfQoJCQkKCQl9OwoJCWRmcygwLC0xKTsgCgkJaW50IHE7IAoJCWNpbj4+cTsgCgkJZnIoaSwwLHEpCgkJewoJCQlpbnQgdTsgCgkJCWNpbj4+dTsgCgkJCXUtLTsgCgkJCWNvdXQ8PGFuc1t1XTw8ZW5kbDsgCgkJfQoJCQoJfQoJIAoJCgkJIAp9CgoKCg==