#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1<<(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.clear();
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			cout << "Yes" << endl;
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		sum = 0;
		for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			cout << "Yes" << endl;
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		sum = 0;
		for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (sum&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
vector<int> level[500009];
vector<int> cumxor[500009];

vector<int> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
vector<int> level[500009];
vector<int> cumxor[500009];

vector<int> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
		children[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//assert(perm[level[lev][R]] <= finaldesc[n] && (R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		//assert(perm[level[lev][L]] >= perm[n] && (L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int tot = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
std::vector<unsigned> level[500001];
std::vector<unsigned> cumxor[500001];

std::vector<unsigned> children[500001];
int perm[500001];
int finaldesc[500001];

int place;
void traverse(int n) {
	perm[n] = place++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] = cumxor[depth[n]][k] ^ cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j]);
	finaldesc[n] = place-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	place = 1;
	traverse(1);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction;
		if (L==0) correction = 0;
		else correction = cumxor[lev][L-1];
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<int> level[500009];
std::vector<int> cumxor[500009];

std::vector<int> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
		children[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",&(par[n]));
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		assert(i == lindex[n]);
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			cout << "Yes" << endl;
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;
		err("Sum: %d ",sum);
		err("This shoudl be the xor of: [%d:%d]",L,R);
		for (int i=L; i<=R; i++) {
			err(" %c",label[level[lev][i]]);
		} err("\n");

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		assert(i == lindex[n]);
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			cout << "Yes" << endl;
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
vector<int> level[500009];
vector<int> cumxor[500009];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
std::vector<unsigned> level[500001];
std::vector<unsigned> cumxor[500001];

std::vector<unsigned> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
std::vector<unsigned> level[500001];
std::vector<unsigned> cumxor[500001];

std::vector<unsigned> children[500001];
int perm[500001];
int finaldesc[500001];

int place;
void traverse(int n) {
	perm[n] = place++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] = cumxor[depth[n]][k] ^ cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j]);
	finaldesc[n] = place-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	place = 1;
	traverse(1);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction;
		if (L==0) correction = 0;
		else correction = cumxor[lev][L-1];
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] && (R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] && (L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int tot = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		assert(i == lindex[n]);
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			cout << "Yes" << endl;
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[l].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;
		//err("Sum: %d ",sum);

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		cin >> par[n];
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = cumxor[depth[n]].size()-1;
		assert(i == lindex[n]);
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; cin >> n >> lev;
		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=-1; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[l].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		err("nodes at depth %d: ",lev);
		for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;
		err("Sum: %d ",sum);

		int bits = 0;
		for (int e=0; e<26; e++) if (sum & (1<<e)) bits++;
		if (bits > 1) cout << "No" << endl;
		else cout << "Yes" << endl;
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int tot = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	cumxor[depth[n]].push_back(1LL<<(int)(label[n]-'a'));
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int i=1; i<=N; i++) {
		level[i].clear();
		cumxor[i].clear();
		children[i].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int i=0; i<26; i++) {
			if (sum&(1LL<<i)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	set<int> ok;
	ok.insert(0);
	for (int i=0; i<26; i++) ok.insert(1<<i);
	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		assert(perm[level[lev][R]] <= finaldesc[n] &&
			(R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[lev].size()-1;
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;
		assert(perm[level[lev][L]] >= perm[n] &&
			(L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		if (ok.count(sum) == 0) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

//using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//assert(perm[level[lev][R]] <= finaldesc[n] && (R == level[lev].size()-1 || perm[level[lev][R+1]] > finaldesc[n]));
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;
		//assert(perm[level[lev][L]] >= perm[n] && (L==0 || perm[level[lev][L-1]] < perm[n]));

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int tot = (overcount ^ correction);

		//sum = 0;
		//for (int i=L; i<=R; i++) sum ^= (1<<(s[level[lev][i]-1]-'a'));
		//err("Sum: %d ",sum);
		//err("This shoudl be the xor of: [%d:%d]",L,R);
		//for (int i=L; i<=R; i++) {
		//	err(" %c",label[level[lev][i]]);
		//} err("\n");

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
std::vector<unsigned> level[500001];
std::vector<unsigned> cumxor[500001];

std::vector<unsigned> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction;
		if (L==0) correction = 0;
		else correction = cumxor[lev][L-1];
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500009];
char label[500009];
int depth[500009];
std::vector<unsigned> level[500009];
std::vector<unsigned> cumxor[500009];

std::vector<unsigned> children[500009];
int perm[500009];
int finaldesc[500009];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] ^= cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction = ((L == 0)? 0 : cumxor[lev][L-1]);
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>
#include <set>

#pragma GCC optimize("O0")

typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
std::vector<unsigned> level[500001];
std::vector<unsigned> cumxor[500001];

std::vector<unsigned> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] = cumxor[depth[n]][k] ^ cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	std::cin >> N >> Q;
	for (int n=1; n<=N; n++) {
		level[n].clear();
		cumxor[n].clear();
		children[n].clear();
	}
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	int i=1;
	traverse(1,i);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction;
		if (L==0) correction = 0;
		else correction = cumxor[lev][L-1];
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include <cassert>
#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <string>

using namespace std;
typedef long long ll;
#define err(...) fprintf(stderr,__VA_ARGS__)

int N,Q; //Nodes; queries
int par[500001];
char label[500001];
int depth[500001];
vector<int> level[500001];
int lindex[500001]; //Index within its level
vector<int> cumxor[500001];

vector<int> children[500001];
int perm[500001];
int finaldesc[500001];

void traverse(int n, int &i) {
	perm[n] = i++;
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j],i);
	finaldesc[n] = i-1;
}

int main() {
	cin >> N >> Q;
	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		cin >> par[n];
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
		level[depth[n]].push_back(n);
		lindex[n] = level[depth[n]].size()-1;
	}
	string s; cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
		cumxor[depth[n]].push_back(1<<(label[n]-'a'));
		int i = lindex[n];
		assert(i == lindex[n]);
		if (i > 0) {
			cumxor[depth[n]][i] ^= cumxor[depth[n]][i-1];
		}
	}

	int i=1;
	traverse(1,i);

	//for (int n=1; n<=N; n++) err("perm[%d]=%d... encompases perm[%d] through perm[%d].\n",n,perm[n],perm[n],finaldesc[n]);

	for (int q=1; q<=Q; q++) {
		int n,lev; cin >> n >> lev;
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			cout << "Yes" << endl;
			continue;
		}

		//Find largest R such that perm[level[lev][R]] <=  finaldesc[n];
		//Where I interpret perm[level[lev][-1] as -infty and perm[level[lev][size]] as infty
		int l=-1; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		//Find smallest L such that perm[level[l][L]] >= perm[n]
		l=-1; r=level[l].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] >= perm[n]) r=m;
			else l=m;
		}
		int L = r;

		//err("nodes at depth %d: ",lev);
		//for (int i=0; i<level[lev].size(); i++) err("%d ",level[lev][i]);
		//err("Those underneath %d: from %d to %d.\n",n,level[lev][L],level[lev][R]);
		//err("cumxors: "); for (int i=0; i<level[lev].size(); i++) err("%d ",cumxor[lev][i]);

		int overcount = cumxor[lev][R];
		int correction = (L == 0)? 0 : cumxor[lev][L-1];
		int sum = overcount ^ correction;
		//err("Sum: %d ",sum);

		int bits = 0;
		for (int e=0; e<26; e++) if (sum & (1<<e)) bits++;
		if (bits > 1) cout << "No" << endl;
		else cout << "Yes" << endl;
	}
}


#include <iostream>
#include <cstdio>
#include <vector>
#include <string>

int N,Q;
int par[500001];
char label[500001];
int depth[500001];
std::vector<unsigned> level[500001];
std::vector<unsigned> cumxor[500001];

std::vector<unsigned> children[500001];
int perm[500001];
int finaldesc[500001];

int place;
void traverse(int n) {
	perm[n] = place++;
	level[depth[n]].push_back(n);
	int offset = (int) (label[n]-'a');
	cumxor[depth[n]].push_back(1<<offset);
	int k = cumxor[depth[n]].size()-1;
	if (k>0) cumxor[depth[n]][k] = cumxor[depth[n]][k] ^ cumxor[depth[n]][k-1];
	for (int j=0; j<children[n].size(); j++) traverse(children[n][j]);
	finaldesc[n] = place-1;
}

int main() {
	std::cin >> N >> Q;

	par[1] = 0;
	depth[1] = 1;
	level[1].push_back(1);
	for (int n=2; n<=N; n++) {
		scanf("%d",par+n);
		children[par[n]].push_back(n);
		depth[n] = depth[par[n]]+1;
	}
	std::string s; std::cin >> s;
	for (int n=1; n<=N; n++) {
		label[n] = s[n-1];
	}

	place = 1;
	traverse(1);

	for (int q=1; q<=Q; q++) {
		int n,lev; scanf("%d %d",&n,&lev);
		if (level[lev].size() == 0 || perm[level[lev][0]] > finaldesc[n] || perm[level[lev][level[lev].size()-1]] < perm[n]) {
			printf("Yes\n");
			continue;
		}
		int l=0; int r=level[lev].size();
		while (l+1<r) {
			int m = (l+r)/2;
			if (perm[level[lev][m]] <= finaldesc[n]) l=m;
			else r=m;
		}
		int R = l;
		int ll=-1; int rr=level[lev].size()-1;
		while (ll+1<rr) {
			int mm = (ll+rr)/2;
			if (perm[level[lev][mm]] >= perm[n]) rr=mm;
			else ll=mm;
		}
		int L = rr;

		int overcount = cumxor[lev][R];
		int correction;
		if (L==0) correction = 0;
		else correction = cumxor[lev][L-1];
		int tot = (overcount ^ correction);

		int bits = 0;
		for (int b=0; b<26; b++) {
			if (tot&(1LL<<b)) bits++;
		}
		if (bits >= 2) printf("No\n");
		else printf("Yes\n");
	}
}


#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef unsigned long long s64;

const int ONE = 2000005;
const int MOD = 1e9 + 7;

int get()
{
		int res = 1, Q = 1; char c;
		while( (c = getchar()) < 48 || c > 57)
			if(c == '-') Q = -1;
		if(Q) res = c - 48;
		while( (c = getchar()) >= 48 && c <= 57)
			res = res * 10 + c - 48;
		return res * Q;
}

char s[ONE];
int n;
s64 hash[ONE], Pow[ONE];

void Deal()
{
		for(int i = 1; i <= n; i++)
			hash[i] = hash[i - 1] * 10 + s[i] - 48;
		Pow[0] = 1;
		for(int i = 1; i <= n; i ++)
			Pow[i] = Pow[i - 1] * 10;
}

s64 val(int l, int r)
{
		return hash[r] - hash[l - 1] * Pow[r - l + 1];
}

void Check(int a, int b)
{
		if(1 > a - 1 || b > n) return;
		if(a > b - 1) return;
		if(val(1, a - 1) + val(a, b - 1) == val(b, n))
		{
			for(int i = 1; i <= a-1; i++) printf("%c", s[i]); cout<<"+";
			for(int i = a; i <= b-1; i++) printf("%c", s[i]); cout<<"=";
			for(int i = b; i <= n; i++) printf("%c", s[i]);
			exit(0);
		}
}

int main()
{
		//freopen(".in","r",stdin);
		//freopen(".out","w",stdout);
		scanf("%s", s + 1); n = strlen(s + 1);
		Deal();
		for(int i = 3; i <= n; i++)
		{
			int pos, len = n - i + 1;
			pos = 1 + len;
			for(int j = 0; j <= 5; j++)
				Check(pos + j, i), Check(pos - j, i);
			pos = n - len * 2;
			for(int j = 0; j <= 5; j++)
				Check(pos + j, i), Check(pos - j, i);
		}
}


#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef unsigned long long s64;

const int ONE = 3000005;
const int MOD = 1e9 + 7;

int get()
{
		int res = 1, Q = 1; char c;
		while( (c = getchar()) < 48 || c > 57)
			if(c == '-') Q = -1;
		if(Q) res = c - 48;
		while( (c = getchar()) >= 48 && c <= 57)
			res = res * 10 + c - 48;
		return res * Q;
}

char s[ONE];
int n;
s64 hash[ONE], Pow[ONE];

void Deal()
{
		for(int i = 1; i <= n + 1; i++)
			hash[i] = hash[i - 1] * 29 + s[i] - 48;
		Pow[0] = 1;
		for(int i = 1; i <= n + 1; i ++)
			Pow[i] = Pow[i - 1] * 29;
}

s64 val(int l, int r)
{
		return hash[r] - hash[l - 1] * Pow[r - l + 1];
}

void Check(int a, int b)
{
		if(1 > a - 1 || b > n || a > b - 1) return;
		if(s[a] == '0' && a + 1 <= b - 1) return;
		if(s[b] == '0' && b + 1 <= n) return;
		if(val(1, a - 1) + val(a, b - 1) == val(b, n))
		{
			for(int i = 1; i <= a-1; i++) printf("%c", s[i]); cout<<"+";
			for(int i = a; i <= b-1; i++) printf("%c", s[i]); cout<<"=";
			for(int i = b; i <= n; i++) printf("%c", s[i]);
			exit(0);
		}
}

int main()
{
		//freopen(".in","r",stdin);
		//freopen(".out","w",stdout);
		scanf("%s", s + 1); n = strlen(s + 1);
		Deal();
		for(int i = 3; i <= n; i++)
		{
			int pos, len = n - i + 1;
			pos = 1 + len;
			for(int j = 0; j <= 10; j++)
				Check(pos + j, i), Check(pos - j, i);
			pos = n - len * 2;
			for(int j = 0; j <= 10; j++)
				Check(pos + j, i), Check(pos - j, i);
		}
}


#include<iostream>
#include<string>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cstdlib>
#include<cmath>
using namespace std;
typedef long long s64;

const int ONE = 3000005;
const int MOD = 1e9 + 7;

int get()
{
		int res = 1, Q = 1; char c;
		while( (c = getchar()) < 48 || c > 57)
			if(c == '-') Q = -1;
		if(Q) res = c - 48;
		while( (c = getchar()) >= 48 && c <= 57)
			res = res * 10 + c - 48;
		return res * Q;
}

char s[ONE];
int n;
s64 hash[ONE], Pow[ONE];

void Deal()
{
		for(int i = 1; i <= n + 100; i++)
			hash[i] = hash[i - 1] * 10 + s[i] - 48;
		Pow[0] = 1;
		for(int i = 1; i <= n + 100; i ++)
			Pow[i] = Pow[i - 1] * 10;
}

s64 val(int l, int r)
{
		return hash[r] - hash[l - 1] * Pow[r - l + 1];
}

void Check(int a, int b)
{
		if(1 > a - 1 || b > n || a > b - 1) return;
		if(s[a] == '0' && a + 1 <= b - 1) return;
		if(s[b] == '0' && b + 1 <= n) return;
		if(val(1, a - 1) + val(a, b - 1) == val(b, n))
		{
			for(int i = 1; i <= a-1; i++) printf("%c", s[i]); cout<<"+";
			for(int i = a; i <= b-1; i++) printf("%c", s[i]); cout<<"=";
			for(int i = b; i <= n; i++) printf("%c", s[i]);
			exit(0);
		}
}

int main()
{
		//freopen(".in","r",stdin);
		//freopen(".out","w",stdout);
		scanf("%s", s + 1); n = strlen(s + 1);
		Deal();
		for(int i = n; i >= 3; i--)
		{
			int pos, len = n - i + 1;
			pos = 1 + len;
			for(int j = 0; j <= 10; j++)
				Check(pos + j, i), Check(pos - j, i);
			pos = n - len * 2;
			for(int j = 0; j <= 10; j++)
				Check(pos + j, i), Check(pos - j, i);
		}
}


#include<cstdio>
#include<cstring>
#define N 1000005
bool find=0;
char s[N];
int q[5]={23333,66666,576345,234455,1000007};
int n,p[N][5],mi[N][5];
int split(int i,int l,int r)
{
	return p[r][i]-1ll*p[l-1][i]*mi[r-l+1][i]%q[i];
}
void check(int a,int b)
{
	if(a<1)return;
	if(b>=n)return;
	if(a>=b)return;
	if(find)return;
	for(int i=0;i<5;++i)
		if((split(i,1,a)+split(i,a+1,b)-split(i,b+1,n))%q[i])return;
	find=1;
	for(int i=1;i<=a;++i)
		putchar(s[i]+48);
	putchar('+');
	for(int i=a+1;i<=b;++i)
		putchar(s[i]+48);
	putchar('=');
	for(int i=b+1;i<=n;++i)
		putchar(s[i]+48);
}
int main()
{
	scanf("%s",s+1);n=strlen(s+1);
	for(int i=1;i<=n;++i)s[i]-=48;
	for(int i=0;i<5;++i)mi[0][i]=1;
	for(int i=1;i<=n;++i)
		for(int j=0;j<5;++j)
		{
			p[i][j]=(p[i-1][j]*10ll+s[i])%q[j];
			mi[i][j]=mi[i-1][j]*10ll%q[j];
		}
	for(int i=n/2;i<=n;++i)
	{
		check(n-i-1,i);
		check(n-i,i);
		check(n-i+1,i);
		check(i-(n-i)-1,i);
		check(i-(n-i),i);
		check(i-(n-i)+1,i);
	}
}


#include<cstdio>
#include<cstring>
#define N 1000005
bool find=0;
char s[N];
int q[5]={23333,66666,576345,234455,1000007};
int n,p[N][5],mi[N][5];
int split(int i,int l,int r)
{
	return p[r][i]-1ll*p[l-1][i]*mi[r-l+1][i]%q[i];
}
void check(int a,int b)
{
	if(s[a+1]==0 && b-a>=2)return;
	if(s[b+1]==0 && n-b>=2)return;
	if(a<1)return;
	if(b>=n)return;
	if(a>=b)return;
	if(find)return;
	for(int i=0;i<5;++i)
		if((split(i,1,a)+split(i,a+1,b)-split(i,b+1,n))%q[i])return;
	find=1;
	for(int i=1;i<=a;++i)
		putchar(s[i]+48);
	putchar('+');
	for(int i=a+1;i<=b;++i)
		putchar(s[i]+48);
	putchar('=');
	for(int i=b+1;i<=n;++i)
		putchar(s[i]+48);
}
int main()
{
	scanf("%s",s+1);n=strlen(s+1);
	for(int i=1;i<=n;++i)s[i]-=48;
	for(int i=0;i<5;++i)mi[0][i]=1;
	for(int i=1;i<=n;++i)
		for(int j=0;j<5;++j)
		{
			p[i][j]=(p[i-1][j]*10ll+s[i])%q[j];
			mi[i][j]=mi[i-1][j]*10ll%q[j];
		}
	for(int i=n/2;i<=n;++i)
	{
		check(n-i-1,i);
		check(n-i,i);
		check(n-i+1,i);
		check(i-(n-i)-1,i);
		check(i-(n-i),i);
		check(i-(n-i)+1,i);
	}
}


#include<bits/stdc++.h>
#include <ext/numeric>
using namespace std;
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define scd(a) scanf("%lf",&a)
#define scd2(a,b) scanf("%lf%lf",&a,&b)
#define scd3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define scd4(a,b,c,d) scanf("%lf%lf%lf%lf",&a,&b,&c,&d)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ALL(x) x.begin(), x.end()
#define BUFF ios::sync_with_stdio(false)
#define endl "\n"
#define power(a,x) __gnu_cxx::power(a, x)
#define forN(i,n) for(int i=0;i<n;i++)
#define eps 1e-5
#define INF INT_MAX
#define INFLL LLONG_MAX
#define gcd(a,b) __gcd(a,b)
typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vector<int> >vvi;
const int inf = 0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f;
#define MOD 1000004099
#define base 10
string ss;
vector<ll> pre;
vector<ll> pot;
void calcPot(int n)
{
	pot.pb(1);
	for(int i=1;i<n;i++)
	{
		pot.pb(pot[i-1]*base);
		pot[i]%=MOD;
	}
}
void calcPre(int n)
{
	pre.pb(ss[0]-'0');
	for(int i=1;i<n;i++)
	{
		pre.pb(pre[i-1]*base+ss[i]-'0');
		pre[i]%=MOD;
	}
}
ll hash(int i,int j)
{
	if(i==0)return pre[j];
	ll ret=pre[j]-pre[i-1]*pot[j-i+1];
	ret%=MOD;
	if(ret<0)ret+=MOD;
	return ret;
}
int converte(int i)
{
    return ss.size()-i-1;
}
bool valid(int i,int j)
{
	if(j==i)return true;
	return ss[i]!='0';
}
int main()
{
    BUFF;
    cin>>ss;
    int n=ss.size();
    calcPot(n);
    calcPre(n);
	 int j=0;
	 for(int i=n-1;i>=2;i--)
	 {
		int l=n-i;
		ll h3=hash(i,n-1);
		ll h1,h2;
		if(2*l<n)
		{
			h1=hash(0,l-1);
			h2=hash(l,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-1) && valid(l,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l);
					s2=ss.substr(l,i-l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
			int start=i-l;
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}

		if(l>1 && 2*l-1<n)
		{
			h1=hash(0,l-2);
			h2=hash(l-1,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-2) && valid(l-1,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l-1);
					s2=ss.substr(l-1,i-(l-1));
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}

			int start=i-(l-1);
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l-1);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#include <ext/numeric>
using namespace std;
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define scd(a) scanf("%lf",&a)
#define scd2(a,b) scanf("%lf%lf",&a,&b)
#define scd3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define scd4(a,b,c,d) scanf("%lf%lf%lf%lf",&a,&b,&c,&d)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ALL(x) x.begin(), x.end()
#define BUFF ios::sync_with_stdio(false)
#define endl "\n"
#define power(a,x) __gnu_cxx::power(a, x)
#define forN(i,n) for(int i=0;i<n;i++)
#define eps 1e-5
#define INF INT_MAX
#define INFLL LLONG_MAX
#define gcd(a,b) __gcd(a,b)
typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vector<int> >vvi;
const int inf = 0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f;
#define MOD 1000000007
#define base 10
string ss;
vector<ll> pre;
vector<ll> pot;
void calcPot(int n)
{
	pot.pb(1);
	for(int i=1;i<n;i++)
	{
		pot.pb(pot[i-1]*base);
		pot[i]%=MOD;
	}
}
void calcPre(int n)
{
	pre.pb(ss[0]-'0');
	for(int i=1;i<n;i++)
	{
		pre.pb(pre[i-1]*base+ss[i]-'0');
		pre[i]%=MOD;
	}
}
ll hash(int i,int j)
{
	if(i==0)return pre[j];
	ll ret=pre[j]-pre[i-1]*pot[j-i+1];
	ret%=MOD;
	if(ret<0)ret+=MOD;
	return ret;
}
int converte(int i)
{
    return ss.size()-i-1;
}
bool valid(int i,int j)
{
	if(j==i)return true;
	return ss[i]!=0;
}
int main()
{
    BUFF;
    cin>>ss;
    int n=ss.size();
    calcPot(n);
    calcPre(n);
	 int j=0;
	 for(int i=n-1;i>=2;i--)
	 {
		int l=n-i;
		ll h3=hash(i,n-1);
		ll h1,h2;
		if(2*l<n)
		{
			h1=hash(0,l-1);
			h2=hash(l,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-1) && valid(l,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l);
					s2=ss.substr(l,i-l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
			int start=i-l;
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}

		if(l>1 && 2*l-1<n)
		{
			h1=hash(0,l-2);
			h2=hash(l-1,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-2) && valid(l-1,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l-1);
					s2=ss.substr(l-1,i-(l-1));
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}

			int start=i-(l-1);
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l-1);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#include <ext/numeric>
using namespace std;
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define scd(a) scanf("%lf",&a)
#define scd2(a,b) scanf("%lf%lf",&a,&b)
#define scd3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define scd4(a,b,c,d) scanf("%lf%lf%lf%lf",&a,&b,&c,&d)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ALL(x) x.begin(), x.end()
#define BUFF ios::sync_with_stdio(false)
#define endl "\n"
#define power(a,x) __gnu_cxx::power(a, x)
#define forN(i,n) for(int i=0;i<n;i++)
#define eps 1e-5
#define INF INT_MAX
#define INFLL LLONG_MAX
#define gcd(a,b) __gcd(a,b)
typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vector<int> >vvi;
const int inf = 0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f;
#define MOD 1000000009
#define base 10
string ss;
vector<ll> pre;
vector<ll> pot;
void calcPot(int n)
{
	pot.pb(1);
	for(int i=1;i<n;i++)
	{
		pot.pb(pot[i-1]*base);
		pot[i]%=MOD;
	}
}
void calcPre(int n)
{
	pre.pb(ss[0]-'0');
	for(int i=1;i<n;i++)
	{
		pre.pb(pre[i-1]*base+ss[i]-'0');
		pre[i]%=MOD;
	}
}
ll hash(int i,int j)
{
	if(i==0)return pre[j];
	ll ret=pre[j]-pre[i-1]*pot[j-i+1];
	ret%=MOD;
	if(ret<0)ret+=MOD;
	return ret;
}
int converte(int i)
{
    return ss.size()-i-1;
}
bool valid(int i,int j)
{
	if(j==i)return true;
	return ss[i]!='0';
}
int main()
{
    BUFF;
    cin>>ss;
    int n=ss.size();
    calcPot(n);
    calcPre(n);
	 int j=0;
	 for(int i=n-1;i>=2;i--)
	 {
		int l=n-i;
		ll h3=hash(i,n-1);
		ll h1,h2;
		if(2*l<n)
		{
			h1=hash(0,l-1);
			h2=hash(l,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-1) && valid(l,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l);
					s2=ss.substr(l,i-l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
			int start=i-l;
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}

		if(l>1 && 2*l-1<n)
		{
			h1=hash(0,l-2);
			h2=hash(l-1,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-2) && valid(l-1,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l-1);
					s2=ss.substr(l-1,i-(l-1));
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}

			int start=i-(l-1);
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l-1);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}
	}
	return 0;
}


#include<bits/stdc++.h>
#include <ext/numeric>
using namespace std;
#define sc(a) scanf("%d",&a)
#define sc2(a,b) scanf("%d%d",&a,&b)
#define sc3(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define sc4(a,b,c,d) scanf("%d%d%d%d",&a,&b,&c,&d)
#define scd(a) scanf("%lf",&a)
#define scd2(a,b) scanf("%lf%lf",&a,&b)
#define scd3(a,b,c) scanf("%lf%lf%lf",&a,&b,&c)
#define scd4(a,b,c,d) scanf("%lf%lf%lf%lf",&a,&b,&c,&d)
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define ALL(x) x.begin(), x.end()
#define BUFF ios::sync_with_stdio(false)
#define endl "\n"
#define power(a,x) __gnu_cxx::power(a, x)
#define forN(i,n) for(int i=0;i<n;i++)
#define eps 1e-5
#define INF INT_MAX
#define INFLL LLONG_MAX
#define gcd(a,b) __gcd(a,b)
typedef unsigned long long int ull;
typedef long long int ll;
typedef long double ld;
typedef pair<int,int> ii;
typedef vector<int> vi;
typedef vector<ii> vii;
typedef vector<vector<int> >vvi;
const int inf = 0x3f3f3f3f;
const ll infll=0x3f3f3f3f3f3f3f;
#define MOD 1000000007
#define base 10
string ss;
vector<ll> pre;
vector<ll> pot;
void calcPot(int n)
{
	pot.pb(1);
	for(int i=1;i<n;i++)
	{
		pot.pb(pot[i-1]*base);
		pot[i]%=MOD;
	}
}
void calcPre(int n)
{
	pre.pb(ss[0]-'0');
	for(int i=1;i<n;i++)
	{
		pre.pb(pre[i-1]*base+ss[i]-'0');
		pre[i]%=MOD;
	}
}
ll hash(int i,int j)
{
	if(i==0)return pre[j];
	ll ret=pre[j]-pre[i-1]*pot[j-i+1];
	ret%=MOD;
	if(ret<0)ret+=MOD;
	return ret;
}
int converte(int i)
{
    return ss.size()-i-1;
}
bool valid(int i,int j)
{
	if(j==i)return true;
	return ss[i]!='0';
}
int main()
{
    BUFF;
    cin>>ss;
    int n=ss.size();
    calcPot(n);
    calcPre(n);
	 int j=0;
	 for(int i=n-1;i>=2;i--)
	 {
		int l=n-i;
		ll h3=hash(i,n-1);
		ll h1,h2;
		if(2*l<n)
		{
			h1=hash(0,l-1);
			h2=hash(l,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-1) && valid(l,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l);
					s2=ss.substr(l,i-l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
			int start=i-l;
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}

		if(l>1 && 2*l-1<n)
		{
			h1=hash(0,l-2);
			h2=hash(l-1,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,l-2) && valid(l-1,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,l-1);
					s2=ss.substr(l-1,i-(l-1));
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}

			int start=i-(l-1);
			h1=hash(0,start-1);
			h2=hash(start,i-1);
			if( (h1+h2)%MOD==h3)
			{
				if(valid(0,start-1) && valid(start,i-1) && valid(i,n-1))
				{
					string s1,s2,s3;
					s1=ss.substr(0,start);
					s2=ss.substr(start,l-1);
					s3=ss.substr(i);
					cout<<s1<<"+"<<s2<<"="<<s3<<endl;
					return 0;
				}
			}
		}
	}
	return 0;
}