#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef pair<int, int> ii;
const int INF = 1e9;
const ll LINF = 1e18;
const int N = 5e5 + 5;
const int Q = 5e5 + 5;
int n, q;
vector<int> adj[N];
string s;
int c[N];
int tin[N], tout[N], timer;
int depth[N]; // depth[u] = Độ sâu của đỉnh u
void dfs(int u, int p) {
tin[u] = ++timer;
for (int v : adj[u]) {
if (v == p) continue;
depth[v] = depth[u] + 1;
dfs(v, u);
}
tout[u] = timer;
}
struct Fenwick {
int n;
vector<int> ft;
Fenwick(int n) : n(n) {
ft.resize(n, 0);
}
void update(int pos, int val) {
for (; pos < n; pos += pos & (-pos)) {
ft[pos] ^= val;
}
}
int get(int pos) {
int ans = 0;
for (; pos > 0; pos -= pos & (-pos)) {
ans ^= ft[pos];
}
return ans;
}
};
// - Bài toán con: Cho xâu s chỉ chứa các chữ cái in thường,
// hỏi có tồn tại cách sắp xếp lại các kí tự trong xâu s sao cho s trở thành xâu đối xứng (palindrome)?
// - Đáp án: (Số lượng kí tự có số lần xuất hiện là lẻ) phải <= 1
// - Cây con gốc u sẽ tương ứng với đoạn [tin(u), tout(u)] trên Euler Tour
// - Biến đổi truy vấn trong bài thành: Xét các kí tự của những đỉnh v có trong đoạn [tin(u), tout(u)] và depth[v] = d,
// hỏi có tồn tại cách sắp xếp lại các kí tự đó sao cho tạo thành xâu đối xứng
// => Có thể sử dụng hướng giải tương tự như ở bài Count Descendants:
// Chuẩn bị trước các vector pos[d][c] cho từng độ sâu d và kí tự c
// Độ phức tạp: O(q * 26 * log2(n)), nhưng với giới hạn của bài này thì vẫn cần tối ưu thêm
// - Nhận xét: Số lượng kí tự là khá ít, chỉ có 26 kí tự ('a' - 'z'), nếu đổi sang số thì sẽ là từ 0 - 25
// => Ta có thể xem mỗi giá trị c ứng với một mask 2^c (chỉ có bit c bật và các bit còn lại đều tắt)
// Khi đó giá trị mask tương ứng với 1 đoạn sẽ là tổng XOR của đoạn đó
// (tức các giá trị c xuất hiện lẻ lần trong đoạn thì các bit tương ứng sẽ được bật, ngược lại sẽ tắt)
// - Ngoài ra còn có cách xử lí offline bằng Fenwick Tree/Segment Tree: trả lời các truy vấn theo độ cao, đi kèm với nhận xét tối ưu ở trên
// (Được sử dụng trong code này)
// Độ phức tạp: O((n + q) * log2(n))
vector<int> vertices[N]; // vertices[d] = Danh sách các đỉnh u nằm ở độ sâu d
vector<ii> queries[N];
int ans[Q]; // ans[i] = Đáp án của truy vấn thứ i
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
cin >> n >> q;
for (int u = 2; u <= n; u++) {
int p; cin >> p;
adj[u].push_back(p);
adj[p].push_back(u);
}
cin >> s;
s = ' ' + s;
for (int u = 1; u <= n; u++) {
c[u] = s[u] - 'a';
}
timer = 0;
depth[1] = 1;
dfs(1, -1);
for (int u = 1; u <= n; u++) {
vertices[depth[u]].push_back(u);
}
for (int i = 0; i < q; i++) {
int u, d;
cin >> u >> d;
queries[d].push_back({u, i});
}
Fenwick fenw(n + 1);
for (int d = 1; d <= n; d++) {
for (int u : vertices[d]) {
fenw.update(tin[u], 1 << c[u]);
}
for (ii q : queries[d]) {
int u = q.first, idx = q.second;
int mask = fenw.get(tout[u]) ^ fenw.get(tin[u] - 1);
ans[idx] = (__builtin_popcount(mask) <= 1);
}
for (int u : vertices[d]) {
fenw.update(tin[u], 1 << c[u]);
}
}
for (int i = 0; i < q; i++) {
cout << (ans[i] ? "Yes" : "No") << '\n';
}
}