#include<bits/stdc++.h>
#pragma GCC optimize("O3,unroll-loops")
#define maxn 50005
#define itachi ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);
#define fi first
#define se second
#define maxb ((1<<8)+5)
#define ll long long
#define sti string
using namespace std;
const int mod=1e9+7;
const int MAX=1e6;
int high[maxn],all[maxb],tmp[maxb];
int cur[maxb],used[maxb];
vector<int> adj[maxn];
int ans[maxb],res[1000005];
int dp[maxb][maxn];
int choose[maxb],par[maxn];
int up_cnt[maxn][maxb];
int down_cnt[maxn][maxb];
int a[maxn],q,n,order[maxn];
int out[maxn];
vector<pair<int,int>> que[maxn];
int SOSA[maxb][15],SOSB[maxb][15];
void SOS(int materialA[],int materialB[],int res[]){
for(int j=0;j<8;j++){
for(int mask=0;mask<(1<<8);mask++){
if(mask&(1<<j)){
if(j==0) {
SOSA[mask][j]=materialA[mask]+materialA[mask^(1<<j)];
SOSB[mask][j]=materialB[mask]+materialB[mask^(1<<j)];
}
else {
SOSA[mask][j]=SOSA[mask][j-1]+SOSA[mask^(1<<j)][j-1];
SOSB[mask][j]=SOSB[mask][j-1]+SOSB[mask^(1<<j)][j-1];
}
}
else{
if(j==0) {
SOSA[mask][j]=materialA[mask];
SOSB[mask][j]=materialB[mask];
}
else {
SOSA[mask][j]=SOSA[mask][j-1];
SOSB[mask][j]=SOSB[mask][j-1];
}
}
}
}
for(int mask=0;mask<(1<<8);mask++) choose[mask]=SOSA[mask][7]*SOSB[mask][7];
for(int j=0;j<8;j++){
for(int mask=0;mask<(1<<8);mask++){
if((mask&(1<<j))){
if(j==0) dp[mask][j]=choose[mask]-choose[mask^(1<<j)];
else dp[mask][j]=dp[mask][j-1] - dp[mask^(1<<j)][j-1];
}
else{
if(j==0) dp[mask][j]=choose[mask];
else dp[mask][j]=dp[mask][j-1];
}
}
}
for(int mask=0;mask<(1<<8);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++){
int p; cin>>p;
adj[p].push_back(i);
}
dfs_pre(1);
for(int id=1;id<=q;id++){
int x,i;
cin>>x>>i;
que[i].push_back({x,id});
}
for(int i=1;i<=n;i++) order[i]=i;
sort(order+1,order+n+1,
[&](int a, int b){ return high[a] > high[b]; });
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<(1<<8);mask++){
down_cnt[u][mask | a[u]] += down_cnt[v][mask];
}
}
}
for(int u=1;u<=n;u++){
memset(all,0,sizeof(all));
all[a[u]]++;
for(int mask=0;mask<(1<<8);mask++){
all[mask] += up_cnt[u][mask];
}
for(int v : adj[u]){
memset(tmp,0,sizeof(tmp));
for(int mask=0;mask<(1<<8);mask++){
tmp[mask | a[u]] += down_cnt[v][mask];
}
for(int mask=0;mask<(1<<8);mask++){
all[mask] += tmp[mask];
}
}
for(int v : adj[u]){
memset(tmp,0,sizeof(tmp));
for(int mask=0;mask<(1<<8);mask++){
tmp[mask | a[u]] += down_cnt[v][mask];
}
for(int mask=0;mask<(1<<8);mask++){
up_cnt[v][mask | a[v]] += all[mask] - tmp[mask];
}
}
}
for(int i=1;i<=n;i++){
memset(out,0,sizeof(out));
memset(used,0,sizeof(used));
memset(ans,0,sizeof(ans));
used[a[i]]=1;
ans[a[i]]++;
for(int mask=0;mask<(1<<8);mask++) cur[mask]=up_cnt[i][mask];
SOS(used, cur, out);
for(int mask=0;mask<(1<<8);mask++) ans[mask] += out[mask];
for(int mask=0;mask<(1<<8);mask++) used[mask] += cur[mask];
for(int v : adj[i]){
memset(cur,0,sizeof(cur));
for(int mask=0;mask<(1<<8);mask++){
cur[mask | a[i]] += down_cnt[v][mask];
}
SOS(used, cur, out);
for(int mask=0;mask<(1<<8);mask++) ans[mask] += out[mask];
for(int mask=0;mask<(1<<8);mask++) used[mask] += cur[mask];
}
for(auto &it : que[i]){
int x = it.fi;
int id = it.se;
res[id] = ans[x];
}
}
for(int i=1;i<=q;i++) cout<<res[i]<<'\n';
return 0;
}