#include <bits/stdc++.h>
using namespace std;
const static int inf = 0x3f3f3f3f;
const static long long INF = 0x3f3f3f3f3f3f3f3f;
const static int maxn = 5e5 + 10;
struct edge {
  int to;
  int next;
} e[maxn << 2];
int tot = 0;
int head[maxn];
void addedge(int u, int v) {
  e[++tot].to = v;
  e[tot].next = head[u];
  head[u] = tot;
}
int sz[maxn];
int son[maxn];
int dep[maxn];
void pre_dfs(int u, int fa) {
  dep[u] = dep[fa] + 1;
  sz[u] = 1;
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa) continue;
    pre_dfs(v, u);
    sz[u] += sz[v];
    if (sz[v] > sz[son[u]]) son[u] = v;
  }
}
int n, m;
char str[maxn];
struct query {
  int d;
  int id;
};
vector<query> q[maxn];
int flag;
int cnt[maxn][26];
void cal(int u, int fa, int val) {
  cnt[dep[u]][str[u - 1] - 'a'] += val;
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa || v == flag) continue;
    cal(v, u, val);
  }
}
int ans[maxn];
int check(int d) {
  int odd = 0;
  for (int i = 0; i < 26; i++) {
    if (cnt[d][i] & 1) odd++;
    if (odd >= 2) return 0;
  }
  return 1;
}
void dfs(int u, int fa, int keep) {
  for (int i = head[u]; i; i = e[i].next) {
    int v = e[i].to;
    if (v == fa || v == son[u]) continue;
    dfs(v, u, 0);
  }
  if (son[u]) {
    dfs(son[u], u, 1);
    flag = son[u];
  }
  cal(u, fa, 1);
  for (int i = 0; i < q[u].size(); i++) {
    ans[q[u][i].id] = check(q[u][i].d);
  }
  flag = 0;
  if (!keep) {
    cal(u, fa, -1);
  }
}
int main() {
  scanf("%d %d", &n, &m);
  for (int i = 2; i <= n; i++) {
    int p;
    scanf("%d", &p);
    addedge(i, p);
    addedge(p, i);
  }
  sz[0] = 0;
  dep[0] = 0;
  pre_dfs(1, 0);
  scanf("%s", str);
  for (int i = 1; i <= m; i++) {
    int v, h;
    scanf("%d %d", &v, &h);
    q[v].push_back((query){h, i});
  }
  dfs(1, 0, 0);
  for (int i = 1; i <= m; i++) {
    if (ans[i])
      printf("Yes\n");
    else
      printf("No\n");
  }
  return 0;
}
