#include<bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#define int long long
#define maxn 50005
#define maxb 256
#define itachi ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
using namespace std;
int n,q;
int a[maxn],par[maxn],high[maxn];
vector<int> adj[maxn];
int up_cnt[maxn][maxb];
int down_cnt[maxn][maxb];
int ans[maxn][maxb];
// SOS DP buffers
int f[maxb][8], g[maxb][8], dp[maxb][8];
void OR_conv(int A[], int B[], int res[]){
for(int mask=0;mask<maxb;mask++){
f[mask][0]=A[mask];
g[mask][0]=B[mask];
}
// SOS forward
for(int j=0;j<8;j++){
for(int mask=0;mask<maxb;mask++){
if(mask&(1<<j)){
if(j){
f[mask][j]=f[mask][j-1]+f[mask^(1<<j)][j-1];
g[mask][j]=g[mask][j-1]+g[mask^(1<<j)][j-1];
}else{
f[mask][j]=A[mask]+A[mask^(1<<j)];
g[mask][j]=B[mask]+B[mask^(1<<j)];
}
}else{
if(j){
f[mask][j]=f[mask][j-1];
g[mask][j]=g[mask][j-1];
}else{
f[mask][j]=A[mask];
g[mask][j]=B[mask];
}
}
}
}
// multiply
for(int mask=0;mask<maxb;mask++){
dp[mask][0]=f[mask][7]*g[mask][7];
}
// Möbius
for(int j=0;j<8;j++){
for(int mask=0;mask<maxb;mask++){
if(mask&(1<<j)){
if(j==0) dp[mask][j]=dp[mask][0]-dp[mask^(1<<j)][0];
else dp[mask][j]=dp[mask][j-1]-dp[mask^(1<<j)][j-1];
}else{
if(j) dp[mask][j]=dp[mask][j-1];
else dp[mask][j]=dp[mask][0];
}
}
}
for(int mask=0;mask<maxb;mask++){
res[mask]=dp[mask][7];
}
}
void dfs_pre(int u){
for(int v:adj[u]){
par[v]=u;
high[v]=high[u]+1;
dfs_pre(v);
}
}
signed main(){
itachi
cin>>n>>q;
for(int i=1;i<=n;i++) cin>>a[i];
for(int i=2;i<=n;i++){
cin>>par[i];
adj[par[i]].push_back(i);
}
dfs_pre(1);
// ======================
// build up_cnt
// ======================
static int order[maxn];
for(int i=1;i<=n;i++) order[i]=i;
sort(order+1,order+n+1,[](int u,int v){
return high[u]<high[v];
});
for(int i=1;i<=n;i++){
int u=order[i];
up_cnt[u][a[u]]++;
for(int mask=0;mask<maxb;mask++){
up_cnt[u][mask | a[u]] += up_cnt[par[u]][mask];
}
}
// ======================
// build down_cnt
// ======================
sort(order+1,order+n+1,[](int u,int v){
return high[u]>high[v];
});
for(int i=1;i<=n;i++){
int u=order[i];
down_cnt[u][a[u]]++;
for(int v:adj[u]){
for(int mask=0;mask<maxb;mask++){
down_cnt[u][mask | a[u]] += down_cnt[v][mask];
}
}
}
// ======================
// xử lý từng node
// ======================
static int used[maxb], group[maxb], tmp[maxb];
for(int i=1;i<=n;i++){
for(int mask=0;mask<maxb;mask++){
used[mask]=0;
ans[i][mask]=0;
}
// ===== group 1: node i =====
for(int mask=0;mask<maxb;mask++) group[mask]=0;
group[a[i]] = 1;
OR_conv(used, group, tmp);
for(int mask=0;mask<maxb;mask++) ans[i][mask]+=tmp[mask];
for(int mask=0;mask<maxb;mask++) used[mask]+=group[mask];
// ===== group 2: ancestor =====
for(int mask=0;mask<maxb;mask++) group[mask]=up_cnt[i][mask];
OR_conv(used, group, tmp);
for(int mask=0;mask<maxb;mask++) ans[i][mask]+=tmp[mask];
for(int mask=0;mask<maxb;mask++) used[mask]+=group[mask];
// ===== group 3: từng subtree =====
for(int v:adj[i]){
for(int mask=0;mask<maxb;mask++) group[mask]=0;
for(int mask=0;mask<maxb;mask++){
group[mask | a[i]] += down_cnt[v][mask];
}
OR_conv(used, group, tmp);
for(int mask=0;mask<maxb;mask++) ans[i][mask]+=tmp[mask];
for(int mask=0;mask<maxb;mask++) used[mask]+=group[mask];
}
}
while(q--){
int x,i;
cin>>x>>i;
cout<<ans[i][x]<<'\n';
}
}