#include<bits/stdc++.h>
using namespace std;
#define int long long
struct node{
int x, y, z, w;
}sum[200005];
int n, idx, a[200005], b[200005], q, p, c, cnt, cntb, low[200005], dfn[200005], vis[200005];
stack<int> st;
vector<pair<int, int> > g[200005];
int co[200005], res[200005];
void tarjan(int u){
cnt++;
dfn[u]=low[u]=cnt;
st.push(u);
vis[u]=1;
for(int i=0;i<vc[u].size();i++){
int to=vc[u][i];
if(dfn[to]==0){
tarjan(to);
low[u]=min(low[u], low[to]);
}else if(vis[u]==1){
low[u]=min(low[u], dfn[to]);
}
}
if(dfn[u]==low[u]){
int id;
cntb++;
vector<int> v;
do{
id=st.top();
st.pop();
vis[id]=0;
co[id]=cntb;
v.push_back(id);
}while(id!=u);
int ww=0;
for(int i=v.size()-1;i>=0;i--){
g[cntb].push_back({v[i], 0});
res[v[i]]=ww;
ww++;
}
}
}
int fpow(int a, int b){
int ans=1;
while(b){
if(b%2==1)ans=ans*a%mod;
a=a*a%mod;
b/=2;
}
return ans;
}
int nxt[200005], in[200005], num[200005], en[200005];
//sum中对应的编号 末尾的环的tarjan上的编号 剩余长度 当前消耗了多少长度
int get(int )
signed main(){
cin >> n;
for(int i=1;i<=n;i++){
cin >> a[i];
}
for(int i=1;i<=n;i++){
int x;
cin >> x;
vc[i].push_back(x);
}
for(int i=1;i<=n;i++){
tarjan(i);
}
for(int i=1;i<=n;i++){
for(int j=0;j<vc[i].size();i++){
int to=vc[i][j];
if(co[i]!=co[to]){
nxt[co[i]]=nxt[co[to]];
in[co[to]]++;
}
}
}
for(int i=1;i<=cntb;i++){
if(in[i]!=0)continue;
int tot=0, lst=0;
for(int j=i;j;j=nxt[j]){
tot++;
int u=j;
for(int k=0;k<g[u].size();k++){
lst=j;
idx++;
g[u][k].second=idx;
int v=g[u][k].first;
sum[idx].x=num*a[v];
sum[idx].y=2*a[v];
sum[idx].z=a[v];
sum[idx].w=a[v]*a[v];
if(nxt[j]!=0&&j!=i){
sum[idx].x+=sum[idx-1].x;
sum[idx].y+=sum[idx-1].y;
sum[idx].z+=sum[idx-1].z;
sum[idx].w+=sum[idx-1].w;
}else if(nxt[j]==0&&k!=0){
sum[idx].x+=sum[idx-1].x;
sum[idx].y+=sum[idx-1].y;
sum[idx].z+=sum[idx-1].z;
sum[idx].w+=sum[idx-1].w;
}
}
}
for(int j=i;j;j=nxt[j]){
num[j]=tot;
en[j]=lst;
}
}
cin >> q;
while(q--){
cin >> p >> c;
int id=co[p], ans=0;
ans=n*(n-1)%mod*(2*n%mod-1)%mod*fpow(6, mod-2)%mod;
if(vc[id].size()==1){
idx=g[id][0].second;
if(num[id]>c){
ans+=sum[idx+c-1].w+2*sum[idx+c-1].x;
}else{
ans+=sum[idx+num[id]-2].w+2*sum[idx+num[id]-2].x;
ans+=get(idx+num[id]-1, en[id], c-num[id]+1, num[id]-1);
//sum中对应的编号 末尾的环的tarjan上的编号 剩余长度 当前消耗了多少长度
}
}else{
idx=g[id][res[p]].second;
if(res[p]==0){
ans+=get(idx, id, c, 0);
}else{
int end=idx+g[id].size()-1-res[p];
ans+=get(g[id][0].first, id, c-(end-res[p]+1), end-res[p]+1);
ans+=2*(sum[end].x-sum[idx-1].x)-res[p]*(sum[end].z-sum[idx-1].z)+sum[end].w-sum[idx-1].w;
}
}
cout << ans <<endl;
}
return 0;
}
/*
(ax+j)^2=ax^2+2*ax*j+j^2;
j^2=n*(n+1)*(2*n+1)/6;
缩点找出所有的环
然后按照点唯一的走法分出不同的链 但其实用一个数组存就够了
每条链都必然走向一个环 环之前的部分可以预处理出ax^2+2*ax*j的贡献
环上的点的贡献ax^2
设环上点的顺序编号为id len为环长 num=c/len
则这个点的贡献为a[i]*(id*num+2*num*(num-1))
求一个环上的前缀和分别为 a[i]*id a[i]*2 a[i]
*/