const int MAXN=5e5+5;
struct Edge{
int to,next;
}edge[MAXN<<1];
int head[MAXN],edge_cnt;
void Insert(int u,int v){
edge[++edge_cnt].to=v;
edge[edge_cnt].next=head[u];
head[u]=edge_cnt;
}
char buf[MAXN];
int cnt[MAXN][30];
bool ans[MAXN];
vector<pair<int,int> > query[MAXN];
bool check(int d){
int temp=0;
_for(i,0,26)temp+=cnt[d][i]&1;
return temp<=1;
}
int d[MAXN],sz[MAXN],dfs_id[MAXN],node_id[MAXN],dfs_t;
int h_son[MAXN],mson[MAXN];
void dfs_1(int u,int depth){
sz[u]=1;d[u]=depth;dfs_id[u]=++dfs_t;node_id[dfs_t]=u;mson[u]=0;
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
dfs_1(v,depth+1);
sz[u]+=sz[v];
if(sz[v]>mson[u]){
h_son[u]=v;
mson[u]=sz[v];
}
}
}
void update_node(int u,int v){cnt[d[u]][buf[u]-'a']+=v;}
void update_tree(int u,int v){
_for(i,0,sz[u])
update_node(node_id[dfs_id[u]+i],v);
}
void dfs_2(int u,bool del){
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==h_son[u])continue;
dfs_2(v,true);
}
if(h_son[u])dfs_2(h_son[u],false);
update_node(u,1);
for(int i=head[u];i;i=edge[i].next){
int v=edge[i].to;
if(v==h_son[u])continue;
update_tree(v,1);
}
_for(i,0,query[u].size())
ans[query[u][i].first]=check(query[u][i].second);
if(del)update_tree(u,-1);
}
int main()
{
int n=read_int(),q=read_int(),root=1,u,d;
_rep(i,2,n)
Insert(read_int(),i);
scanf("%s",buf+1);
_for(i,0,q){
u=read_int(),d=read_int();
query[u].push_back(make_pair(i,d));
}
dfs_1(root,root);
dfs_2(root,false);
_for(i,0,q){
if(ans[i])
puts("Yes");
else
puts("No");
}
return 0;
}