#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<queue>
#include<vector>
#include<set>
#include<stack>
#include<map>
#include<ctime>
#include<bitset>
#define LL long long
#define ll long long
#define INF 0x3f3f3f3f
#define maxn 100010
#define eps 1e-6
#define mod 1000000007
using namespace std;
struct node
{
int ls,rs,lmax,rmax,max1,max2;
int len,Lmax,Rmax;
void init()
{
ls=rs=lmax=rmax=0;
max1=max2=Lmax=Rmax=0;
len=0;
}
}tree[maxn*3];
int head[maxn],to[maxn*2],next1[maxn*2] ;
int tot,val[maxn],fa[maxn],top[maxn];
int dep[maxn],son[maxn],w[maxn];
int sz,ql,qr,n;
node v;
node Unit(node &a,node &b)
{
node ans;
ans.len=a.len+b.len ;
ans.ls=a.ls ;
ans.rs=b.rs ;
ans.max1=max(a.max1,b.max1) ;
ans.max2=max(a.max2,b.max2) ;
if(a.rs < b.ls )
{
if(a.lmax==a.len)
ans.lmax = a.lmax+b.lmax ;
else ans.lmax=a.lmax;
ans.max1=max(ans.max1,a.rmax+b.lmax) ;
if(b.rmax==b.len)
ans.rmax = a.rmax+b.rmax ;
else ans.rmax=b.rmax;
}
else {
ans.lmax = a.lmax ;
ans.rmax = b.rmax ;
}
if(b.ls < a.rs )
{
if(a.Lmax==a.len)
ans.Lmax = a.Lmax+b.Lmax ;
else ans.Lmax=a.Lmax;
ans.max2=max(ans.max2,a.Rmax+b.Lmax) ;
if(b.Rmax == b.len)
ans.Rmax = a.Rmax+b.Rmax ;
else ans.Rmax=b.Rmax;
}
else {
ans.Lmax = a.Lmax ;
ans.Rmax = b.Rmax ;
}
return ans;
}
void Unit(int u,int v)
{
to[tot]=v;next1[tot]=head[u];
head[u]=tot++;
}
void dfs(int u,int f)
{
son[u]=0;w[u]=1;
int i,v;
for( i = head[u] ; i != -1; i = next1[i])
{
v = to[i] ;
if(v==f) continue ;
fa[v]=u;
dep[v]=dep[u]+1;
dfs(v,u) ;
if(w[v]>w[son[u]])
son[u]=v;
w[u] += w[v] ;
}
}
void build(int u,int f,int t)
{
w[u]=++sz ;
top[u]=t;
if(son[u])build(son[u],u,t) ;
for( int i = head[u] ; i != -1 ; i = next1[i])
if(son[u] != to[i]&&f != to[i])
build(to[i],u,to[i]) ;
}
void init(int L,int R,int o)
{
if(L==R)
{
tree[o].ls=tree[o].rs=son[L] ;
tree[o].len=tree[o].max1=tree[o].max2=1;
tree[o].lmax=tree[o].Lmax=1;
tree[o].Rmax=tree[o].rmax = 1;
return ;
}
int mid=(L+R)>>1;
init(L,mid,o<<1) ;
init(mid+1,R,o<<1|1) ;
tree[o]=Unit(tree[o<<1],tree[o<<1|1]) ;
}
void find(int L,int R,int o)
{
if(ql<=L&&qr>=R)
{
if(v.max1==0)v=tree[o] ;
else v = Unit(v,tree[o]) ;
return ;
}
int mid=(L+R)>>1 ;
if(ql<=mid) find(L,mid,o<<1) ;
if(qr>mid) find(mid+1,R,o<<1|1);
}
int solve(int u,int vv)
{
int f1,f2;
node v1,v2;
v1.init();
v2.init();
f1=top[u];
f2=top[vv];
while(f1 != f2)
{
if(dep[f1]>dep[f2])
{
ql=w[f1];
qr=w[u] ;
v.init();
find(1,sz,1) ;
if(v1.max1==0)
v1=v;
else v1=Unit(v,v1) ;
u=fa[f1];
f1=top[u];
}
else{
ql=w[f2];
qr=w[vv] ;
v.init();
find(1,sz,1) ;
if(v2.max1==0)
v2=v;
else v2=Unit(v,v2) ;
vv=fa[f2] ;
f2=top[vv] ;
}
}
int ans=0;
if(u==vv&&0){
ans=max(v1.max2,v2.max1);
if(v1.ls < v2.ls)
{
ans=max(ans,v1.Lmax+v2.lmax) ;
}
return ans;
}
else
{
if(dep[u]>dep[vv])
{
ql=w[vv];
qr=w[u];
v.init();
find(1,sz,1) ;
if(v1.max1==0)v1=v;
else v1=Unit(v,v1) ;
}
else
{
ql=w[u];
qr=w[vv];
v.init();
find(1,sz,1) ;
if(v2.max1==0)v2=v;
else v2=Unit(v,v2) ;
}
}
ans=max(v1.max2,v2.max1);
if(v1.ls < v2.ls)
{
ans=max(ans,v1.Lmax+v2.lmax) ;
}
return ans;
}
int main()
{
int i,m,k,case1=0;
int j ,T,x,y ;
// freopen("in.txt","r",stdin);
// freopen("yy.txt","w",stdout);
bool hehe=false;
cin >> T ;
while(T--)
{
if(hehe)puts("") ;
hehe=true;
scanf("%d",&n) ;
for( i =1 ; i <= n ;i++)
scanf("%d",&val[i]) ;
tot=0;
memset(head,-1,sizeof(head)) ;
for( i = 2 ; i <= n ;i++)
{
scanf("%d",&k) ;
Unit(k,i) ;
Unit(i,k) ;
}
dep[1]=0;
fa[1]=1;
sz=0;
dfs(1,-1) ;
build(1,-1,1) ;
for( i = 1 ; i <= n ;i++)
{
son[w[i]]=val[i] ;
}
init(1,sz,1) ;
scanf("%d",&m) ;
printf("Case #%d:\n",++case1);
while(m--)
{
scanf("%d%d",&x,&y) ;
printf("%d\n",solve(x,y)) ;
}
}
return 0 ;
}