#include<bits/stdc++.h>
using namespace std;

struct Node{
	vector<int> path;
	int s;

	Node(void): path(26,0), s(0) {}

	int operator [] (const int x) const {
		return path[x];
	}

	int& operator [] (const int x){
		return path[x];
	}
};

struct Graph{
	vector<int> path;
	int in,out;
};

struct Aho{
	vector<Node> t;

	Aho(void): t(1) {}

	int nw(void){
		t.emplace_back();
		return t.size()-1;
	}

	int addString(string& s){
		int p=0;

		for(char c : s){
			if(t[p][c-'a'] == 0)
				t[p][c-'a'] = nw();
			p = t[p][c-'a'];
		}

		return p;
	}

	void init(void){
		queue<int> q;
		q.push(0);

		while(!q.empty()){
			int v = q.front();
			q.pop();

			for(int i=0;i<26;i++)
				if(t[v][i] != 0){
					int u = t[v][i];
					int s = t[v].s;

					while(s != 0 && t[s][i] == 0)
						s = t[s].s;

					t[u].s = (v == 0 ? 0 : t[s][i]);
					q.push(u);
				}
		}
	}

	int nx(int p, char c){
		while(p > 0 && t[p][c-'a'] == 0)
			p = t[p].s;
		return t[p][c-'a'];
	}
};

struct SegmentTree{
	vector<int> tree;
	int n;

	SegmentTree(int n=0): tree(n+1,0), n(n) {}

	int insert(int p, int x){
		for(p++;p<=n;p+=(p&(-p)))
			tree[p] += x;
	}

	int query(int p){
		int val=0;
		for(p++;p>0;p-=(p&(-p)))
			val += tree[p];
		return val;
	}

	int query(int b, int e){
		return query(e) - query(b-1);
	}
};

int tim=-1;
vector<Graph> g;
void dfs(int v){
	g[v].in = ++tim;

	for(int u : g[v].path)
		dfs(u);

	g[v].out = tim;
}

SegmentTree tree;
vector<vector<pair<int,char> > > t;

Aho ah;
vector<vector<int> > que;
vector<int> nr;
vector<int> res;

void solve(int v, int x){
	tree.insert(g[x].in, 1);

	for(int i : que[v])
		res[i] = tree.query(g[nr[i]].in, g[nr[i]].out);

	for(auto& e : t[v])
		solve(e.first, ah.nx(x, e.second));

	tree.insert(g[x].in, -1);
}

int main(void){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int n;
	cin >> n;

	t.resize(n+1);
	for(int i=1;i<=n;i++){
		int k;
		cin >> k;

		int p = 0;
		if(k == 2)
			cin >> p;

		char c;
		cin >> c;

		t[p].push_back({i,c});
	}

	int q;
	cin >> q;

	que.resize(n+1);
	nr.resize(q);
	res.resize(q);
	for(int i=0;i<q;i++){
		int id;
		string s;

		cin >> id >> s;
		nr[i] = ah.addString(s);
		que[id].push_back(i);
	}

	ah.init();

	g.resize(n+1);
	for(int v=1;v<=n;v++)
		g[ah.t[v].s].path.push_back(v);

	dfs(0);
	tree = SegmentTree(tim+1);

	solve(0,0);

	for(int i : res)
		cout << i << "\n";

	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=19;

int nsong;
int par[MAXNODE];
char parc[MAXNODE];
int nq;
int qidx[MAXQ],qoff[MAXQ],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

int sa[MAXNODE];
int val[MAXNODE];
int pos[MAXNODE];

int up[MAXNODE][MAXLG+1];
int cnt[MAXNODE+1];
int tmp[MAXNODE];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXNODE];

vector<int> ch[MAXNODE];

int bit[MAXNODE+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong+1) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REPE(i,nsong) { int at=sa[i]; printf("%2d (%2d):",at,val[at]); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } puts(""); }
}

int cmp(int at,char *s,int len) {
	REP(i,len) {
		char a=parc[at],b=s[i]; if(a!=b) return a<b?-1:+1;
		at=par[at];
	}
	return 0;
}

void dfs(int at) {
	bmod(pos[at],+1);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	bmod(pos[at],-1);
}

void solve() {
	REPE(i,nsong) up[i][0]=par[i]==-1?i:par[i];
	REP(k,MAXLG) REPE(i,nsong) up[i][k+1]=up[up[i][k]][k];

	int alph=256;
	REP(i,alph) cnt[i]=0;
	REPE(i,nsong) ++cnt[(int)parc[i]];
	for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
	REP(i,alph) cnt[i+1]+=cnt[i];
	REPE(i,nsong) sa[cnt[(int)parc[i]]++]=i;
	alph=0; REPE(i,nsong) if(i!=0&&parc[sa[i]]==parc[sa[i-1]]) val[sa[i]]=alph-1; else val[sa[i]]=alph++;
	REPE(k,MAXLG) {
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[up[i][k]]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) tmp[cnt[val[up[i][k]]]++]=i;
		//printf("tmp:"); REPE(i,nsong) printf(" %d",tmp[i]); puts("");
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[i]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) sa[cnt[val[tmp[i]]]++]=tmp[i];
		alph=0; REPE(i,nsong) if(i!=0&&val[sa[i]]==val[sa[i-1]]&&val[up[sa[i]][k]]==val[up[sa[i-1]][k]]) tmp[sa[i]]=alph-1; else tmp[sa[i]]=alph++;
		REPE(i,nsong) val[i]=tmp[i];
	}
	REPE(i,nsong) pos[sa[i]]=i;
	//printf("alph=%d\n",alph); print();

	REPE(i,nsong) qat[i].clear();
	REP(i,nq) {
		reverse(qs+qoff[i],qs+qoff[i]+qlen[i]);
		int l,r;
		// find first index such that value>=query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])>=0) hi=mi; else lo=mi; } l=hi; }
		// find first index such that value> query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])> 0) hi=mi; else lo=mi; } r=hi; }
		reverse(qs+qoff[i],qs+qoff[i]+qlen[i]);
		//printf("%d: [%d..%d)\n",i,l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REPE(i,nsong) ch[i].clear();
	REPE(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong+1) bit[i]=0;
	dfs(0);
}

void run() {
	scanf("%d",&nsong);
	par[0]=-1,parc[0]='-';
	FORE(i,1,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=0; else scanf("%d",&par[i]); scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]); qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int qansstupid[MAXQ];

void solvestupid() {

	REP(i,nq) {
		vector<char> tmp;
		for(int at=qidx[i];parc[at]!='-';at=par[at]) tmp.PB(parc[at]);
		reverse(tmp.begin(),tmp.end());
		qansstupid[i]=0;
		REPE(j,SZ(tmp)-qlen[i]) {
			bool ok=true; REP(k,qlen[i]) if(tmp[j+k]!=qs[qoff[i]+k]) { ok=false; break; } if(ok) ++qansstupid[i];
		}
	}
}

void stress() {
	int mxsong=1000,mxalph=2,mxqlen=50; nq=1000;
	REP(rep,100000) {
		nsong=rand()%mxsong+1;
		par[0]=-1,parc[0]='-';
		int alph=rand()%mxalph+1;
		FORE(i,1,nsong) { par[i]=rand()%i; parc[i]='a'+rand()%alph; }
		qoff[0]=0; REP(i,nq) { qidx[i]=rand()%(nsong+1); qlen[i]=rand()%mxqlen+1; REP(j,qlen[i]) qs[qoff[i]+j]='a'+rand()%alph; qoff[i+1]=qoff[i]+qlen[i]; } qs[qoff[nq]]='\0';
		solve();
		solvestupid();
		bool ok=true; REP(i,nq) if(qans[i]!=qansstupid[i]) ok=false;
		//bool allzero=true; REP(i,nq) if(qans[i]!=0) allzero=false; printf("%c",allzero?'0':'+');
		if(ok) { if(rep%100==0) printf("."); continue; }
		printf("err rep=%d\n",rep);
		printf("%d\n",nsong);
		FORE(i,1,nsong) if(par[i]==0) printf("%d %c\n",1,parc[i]); else printf("%d %d %c\n",2,par[i],parc[i]);
		printf("%d\n",nq);
		REP(i,nq) { printf("%d ",qidx[i]); REP(j,qlen[i]) printf("%c",qs[qoff[i]+j]); puts(""); }
		printf("have:"); REP(i,nq) printf(" %d",qans[i]); puts("");
		printf("want:"); REP(i,nq) printf(" %d",qansstupid[i]); puts("");
	}
}

int main() {
	run();
	//stress();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

struct SuffixArray {
	vector<int> sa; // sa[idx] = offset of idx-th suffix
	vector<int> pos; // pos[off] = index in suffix array of suffix at off
	vector<int> lcp; // lcp[idx] = longest common prefix of idth-th suffix and (idx+1)-th suffix

	vector<int> id; int nid; // id[0] = value of the empty suffix, id[off+1] = value of the suffix at off
	vector<int> tmp;
	vector<int> cnt;
	vector<int> rmq;

	template<typename T,typename U> void buildsalcp(int n,int alph,T val,U nxt) { // val(off) -> value at given offset, nxt(off,k) -> offset that is 2^k away
		cnt=vector<int>(max(alph,n+1),0); sa=tmp=pos=lcp=vector<int>(n); id=vector<int>(n+1); rmq=vector<int>(2*(n+1));
		REP(i,n) ++cnt[val(i)];
		for(int i=alph-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
		REP(i,alph-1) cnt[i+1]+=cnt[i];
		REP(i,n) sa[cnt[val(i)]++]=i;
		REP(i,n) pos[sa[i]]=i;
		nid=0; id[0]=nid++; REP(i,n) if(i==0||val(sa[i])!=val(sa[i-1])) id[sa[i]+1]=nid++; else id[sa[i]+1]=nid-1;
		REP(i,n) lcp[i]=i+1<n&&id[sa[i]+1]==id[sa[i+1]+1]?1:0;
		for(int k=0;;++k) {
			bool done=true; REP(i,n) if(lcp[i]==1<<k) done=false; if(done) break;
			REP(i,nid) cnt[i]=0;
			REP(i,n) ++cnt[id[nxt(i,k)+1]];
			for(int i=nid-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
			REP(i,nid-1) cnt[i+1]+=cnt[i];
			REP(i,n) tmp[cnt[id[nxt(i,k)+1]]++]=i;
			REP(i,nid) cnt[i]=0;
			REP(i,n) ++cnt[id[i+1]];
			for(int i=nid-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
			REP(i,nid-1) cnt[i+1]+=cnt[i];
			REP(i,n) sa[cnt[id[tmp[i]+1]]++]=tmp[i];
			REP(i,n) pos[sa[i]]=i;
			REP(i,n) rmq[n+i]=lcp[i]; for(int i=n-1;i>=1;--i) rmq[i]=min(rmq[2*i+0],rmq[2*i+1]);
			auto getrmq=[&](int l,int r) { int ret=INT_MAX; for(l+=n,r+=n;l<r;l>>=1,r>>=1) { if(l&1) ret=min(ret,rmq[l++]); if(r&1) ret=min(ret,rmq[--r]); } return ret; };
			REP(i,n) if(lcp[i]==1<<k) { int ii=nxt(sa[i],k),jj=nxt(sa[i+1],k); if(ii==-1||jj==-1) continue; ii=pos[ii],jj=pos[jj]; if(ii>jj) swap(ii,jj); lcp[i]+=id[sa[ii]+1]==id[sa[jj]+1]?1<<k:getrmq(ii,jj); }
			nid=0; id[0]=nid++; REP(i,n) if(i==0||id[sa[i]+1]!=id[sa[i-1]+1]||id[nxt(sa[i],k)+1]!=id[nxt(sa[i-1],k)+1]) tmp[sa[i]]=nid++; else tmp[sa[i]]=nid-1;
			REP(i,n) id[i+1]=tmp[i];
		}
	}
	void buildsalcp(const string &s) { buildsalcp(SZ(s),256,[&](int off) { return (int)s[off]; },[&](int off,int k) { return off+(1<<k)<SZ(s)?off+(1<<k):-1; }); }

	/*template<typename T> void buildlcp(T getlcp) { // getlcp(i,j,k) -> longest common prefix of two offsets (first k are guaranteed to match)
		int k=0; lcp=vector<int>(SZ(sa)); lcp.back()=-1;
		REPSZ(i,sa) {
			if(pos[i]+1>=SZ(sa)) { k=0; continue; }
			int j=sa[pos[i]+1];
			k=getlcp(i,j,k);
			lcp[pos[i]]=k; if(k>0) --k;
		}
	}
	void buildlcp(const string &s) { buildlcp([&](int i,int j,int k) { while(i+k<SZ(s)&&j+k<SZ(s)&&s[i+k]==s[j+k]) ++k; return k; }); }*/

	vector<int> bsllcp,bsrlcp; // bsllcp[m] and bsrlcp[m] are the lcps of (l,m) and (m,r) in binary search in find-method

	void buildbs() {
		bsllcp=bsrlcp=vector<int>(SZ(sa));
		std::function<int(int,int)> rec=[&](int l,int r)->int {
			if(r-l==1) return l==-1||r==SZ(sa)?0:lcp[l];
			int m=l+(r-l)/2;
			bsllcp[m]=rec(l,m); bsrlcp[m]=rec(m,r);
			return min(bsllcp[m],bsrlcp[m]);
		};
		rec(-1,SZ(sa));
	}

	template<typename T,typename U> int find(T getlcp,U cmp,bool upperbound=false) { // getlcp(off,k) -> longest common prefix with suffix starting at off (first k is guaranteed to match), cmp(off,k) -> comparison of k-th character with suffix starting at off
		int l=-1,r=SZ(sa),llcp=0,rlcp=0;
		while(r-l>=2) {
			int m=l+(r-l)/2;
			if(llcp>=rlcp) { if(bsllcp[m]>llcp) l=m; else if(bsllcp[m]<llcp) r=m,rlcp=bsllcp[m]; else { int nlcp=getlcp(sa[m],llcp); if(cmp(sa[m],nlcp)<(!upperbound?0:1)) l=m,llcp=nlcp; else r=m,rlcp=nlcp; } }
				      else { if(bsrlcp[m]<rlcp) l=m,llcp=bsrlcp[m]; else if(bsrlcp[m]>rlcp) r=m; else { int nlcp=getlcp(sa[m],rlcp); if(cmp(sa[m],nlcp)<(!upperbound?0:1)) l=m,llcp=nlcp; else r=m,rlcp=nlcp; } }
		}
		return r;
	}
	int find(const string &s,const string &p,bool upperbound=false) { return find([&](int i,int k) { while(i+k<SZ(s)&&k<SZ(p)&&s[i+k]==p[k]) ++k; return k; },[&](int i,int k){ if(k==SZ(p)) return 0; if(i+k==SZ(s)) return -1; char a=s[i+k],b=p[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; },upperbound); }
	template<typename T,typename U> pair<int,int> findrange(T getlcp,U cmp) { return MP(find(getlcp,cmp,false),find(getlcp,cmp,true)); }
	pair<int,int> findrange(const string &s,const string &p) { return findrange([&](int i,int k) { while(i+k<SZ(s)&&k<SZ(p)&&s[i+k]==p[k]) ++k; return k; },[&](int i,int k){ if(k==SZ(p)) return 0; if(i+k==SZ(s)) return -1; if(k==SZ(p)) return +1; char a=s[i+k],b=p[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; }); }
};

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=18;

int nsong;
int par[MAXSONG];
char parc[MAXSONG];
int nq;
int qidx[MAXQ],qoff[MAXQ+1],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

SuffixArray suff;

int up[MAXSONG][MAXLG+1];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXSONG];

vector<int> ch[MAXSONG];

int bit[MAXSONG+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REP(i,nsong) { int at=suff.sa[i]; printf("%2d:",at); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } printf(" (%d)\n",suff.lcp[i]); }
}

void dfs(int at) {
	bmod(suff.pos[at],+1);
	//printf("inc(%d)\n",suff.pos[at]);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		//printf("q[%d..%d)\n",l,r);
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	//printf("dec(%d)\n",suff.pos[at]);
	bmod(suff.pos[at],-1);
}

int walk(int i,int steps) { for(int k=MAXLG;k>=0;--k) if(steps&(1<<k)) if(i!=-1) i=up[i][k]; return i; }

void solve() {
	//REP(i,nsong) printf("par=%d parc=%c\n",par[i],parc[i]);

	REP(i,nsong) up[i][0]=par[i];
	REP(k,MAXLG) REP(i,nsong) up[i][k+1]=up[i][k]==-1?-1:up[up[i][k]][k];

	suff.buildsalcp(nsong,26,[&](int off) { return (int)(parc[off]-'a'); },[&](int off,int k) { return up[off][k]; });
	suff.buildbs();

	//print();

	REP(i,nsong) qat[i].clear();
	REP(i,nq) {
		string s(qs+qoff[i],qs+qoff[i]+qlen[i]);
		reverse(s.begin(),s.end());
		int l,r; tie(l,r)=suff.findrange([&](int i,int k) { i=walk(i,k); while(i!=-1&&k<SZ(s)&&parc[i]==s[k]) i=par[i],++k; return k; },[&](int i,int k) { i=walk(i,k); if(k==SZ(s)) return 0; if(i==-1) return -1; char a=parc[i],b=s[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; });
		//printf("%d=%s [%d..%d)\n",i,s.c_str(),l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REP(i,nsong) ch[i].clear();
	REP(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong) bit[i]=0;
	REP(i,nsong) if(par[i]==-1) dfs(i);
}

void run() {
	scanf("%d",&nsong);
	REP(i,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=-1; else scanf("%d",&par[i]),--par[i]; scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]),--qidx[i]; qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int qansstupid[MAXQ];

void solvestupid() {

	REP(i,nq) {
		vector<char> tmp;
		for(int at=qidx[i];at!=-1;at=par[at]) tmp.PB(parc[at]);
		reverse(tmp.begin(),tmp.end());
		qansstupid[i]=0;
		REPE(j,SZ(tmp)-qlen[i]) {
			bool ok=true; REP(k,qlen[i]) if(tmp[j+k]!=qs[qoff[i]+k]) { ok=false; break; } if(ok) ++qansstupid[i];
		}
	}
}

void stress() {
	int mxsong=1000,mxalph=3,mxqlen=5; nq=1000;
	REP(rep,100000) {
		nsong=rand()%mxsong+1;
		int alph=rand()%mxalph+1;
		REP(i,nsong) { par[i]=rand()%(i+1)-1; parc[i]='a'+rand()%alph; }
		qoff[0]=0; REP(i,nq) { qidx[i]=rand()%nsong; qlen[i]=rand()%mxqlen+1; REP(j,qlen[i]) qs[qoff[i]+j]='a'+rand()%alph; qoff[i+1]=qoff[i]+qlen[i]; } qs[qoff[nq]]='\0';
		//if(rep!=8889) continue;
		solve();
		solvestupid();
		bool ok=true; REP(i,nq) if(qans[i]!=qansstupid[i]) ok=false;
		//bool allzero=true; REP(i,nq) if(qans[i]!=0) allzero=false; printf("%c",allzero?'0':'+');
		if(ok) { if(rep%100==0) printf("."); continue; }
		printf("err rep=%d\n",rep);
		printf("%d\n",nsong);
		REP(i,nsong) if(par[i]==-1) printf("%d %c\n",1,parc[i]); else printf("%d %d %c\n",2,par[i]+1,parc[i]);
		printf("%d\n",nq);
		REP(i,nq) { printf("%d ",qidx[i]+1); REP(j,qlen[i]) printf("%c",qs[qoff[i]+j]); puts(""); }
		printf("have:"); REP(i,nq) printf(" %d",qans[i]); puts("");
		printf("want:"); REP(i,nq) printf(" %d",qansstupid[i]); puts("");
		break;
	}
}

int main() {
	run();
	//stress();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=18;

int nsong;
int par[MAXNODE];
char parc[MAXNODE];
int nq;
int qidx[MAXQ],qoff[MAXQ],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

int sa[MAXNODE];
int val[MAXNODE];
int pos[MAXNODE];

int up[MAXNODE][MAXLG+1];
int cnt[MAXNODE+1];
int tmp[MAXNODE];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXNODE];

vector<int> ch[MAXNODE];

int bit[MAXNODE+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REPE(i,nsong) { int at=sa[i]; printf("%2d (%2d):",at,val[at]); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } puts(""); }
}

int cmp(int at,char *s,int len) {
	REP(i,len) {
		char a=parc[at],b=s[i]; if(a!=b) return a<b?-1:+1;
		at=par[at];
	}
	return 0;
}

void dfs(int at) {
	bmod(pos[at],+1);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	bmod(pos[at],-1);
}

void solve() {
	REPE(i,nsong) up[i][0]=par[i]==-1?i:par[i];
	REP(k,MAXLG) REPE(i,nsong) up[i][k+1]=up[up[i][k]][k];

	int alph=256;
	REP(i,alph) cnt[i]=0;
	REPE(i,nsong) ++cnt[(int)parc[i]];
	for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
	REP(i,alph) cnt[i+1]+=cnt[i];
	REPE(i,nsong) sa[cnt[(int)parc[i]]++]=i;
	alph=0; REPE(i,nsong) if(i!=0&&parc[sa[i]]==parc[sa[i-1]]) val[sa[i]]=alph-1; else val[sa[i]]=alph++;
	REPE(k,MAXLG) {
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[up[i][k]]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) tmp[cnt[val[up[i][k]]]++]=i;
		//printf("tmp:"); REPE(i,nsong) printf(" %d",tmp[i]); puts("");
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[i]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) sa[cnt[val[tmp[i]]]++]=tmp[i];
		alph=0; REPE(i,nsong) if(i!=0&&val[sa[i]]==val[sa[i-1]]&&val[up[sa[i]][k]]==val[up[sa[i-1]][k]]) tmp[sa[i]]=alph-1; else tmp[sa[i]]=alph++;
		REPE(i,nsong) val[i]=tmp[i];
	}
	REPE(i,nsong) pos[sa[i]]=i;
	//printf("alph=%d\n",alph); print();

	REPE(i,nsong) qat[i].clear();
	REP(i,nq) {
		reverse(qs+qoff[i],qs+qoff[i]+qlen[i]);
		int l,r;
		// find first index such that value>=query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])>=0) hi=mi; else lo=mi; } l=hi; }
		// find first index such that value> query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])> 0) hi=mi; else lo=mi; } r=hi; }
		//printf("%d: [%d..%d)\n",i,l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REPE(i,nsong) ch[i].clear();
	REPE(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong+1) bit[i]=0;
	dfs(0);
}

void run() {
	scanf("%d",&nsong);
	par[0]=-1,parc[0]='-';
	FORE(i,1,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=0; else scanf("%d",&par[i]); scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]); qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int main() {
	run();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

struct SuffixArray {
	vector<int> sa; // sa[idx] = offset of idx-th suffix
	vector<int> pos; // pos[off] = index in suffix array of suffix at off
	vector<int> lcp; // lcp[idx] = longest common prefix of idth-th suffix and (idx+1)-th suffix

	vector<int> id; int nid; // id[0] = value of the empty suffix, id[off+1] = value of the suffix at off
	vector<int> tmp;
	vector<int> cnt;
	vector<int> rmq;

	template<typename T,typename U> void buildsalcp(int n,int alph,T val,U nxt) { // val(off) -> value at given offset, nxt(off,k) -> offset that is 2^k away
		cnt=vector<int>(max(alph,n+1),0); sa=tmp=pos=lcp=vector<int>(n); id=vector<int>(n+1); rmq=vector<int>(2*(n+1));
		REP(i,n) ++cnt[val(i)];
		for(int i=alph-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
		REP(i,alph-1) cnt[i+1]+=cnt[i];
		REP(i,n) sa[cnt[val(i)]++]=i;
		REP(i,n) pos[sa[i]]=i;
		nid=0; id[0]=nid++; REP(i,n) if(i==0||val(sa[i])!=val(sa[i-1])) id[sa[i]+1]=nid++; else id[sa[i]+1]=nid-1;
		REP(i,n) lcp[i]=i+1<n&&id[sa[i]+1]==id[sa[i+1]+1]?1:0;
		for(int k=0;;++k) {
			bool done=true; REP(i,n) if(lcp[i]==1<<k) done=false; if(done) break;
			REP(i,nid) cnt[i]=0;
			REP(i,n) ++cnt[id[nxt(i,k)+1]];
			for(int i=nid-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
			REP(i,nid-1) cnt[i+1]+=cnt[i];
			REP(i,n) tmp[cnt[id[nxt(i,k)+1]]++]=i;
			REP(i,nid) cnt[i]=0;
			REP(i,n) ++cnt[id[i+1]];
			for(int i=nid-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
			REP(i,nid-1) cnt[i+1]+=cnt[i];
			REP(i,n) sa[cnt[id[tmp[i]+1]]++]=tmp[i];
			REP(i,n) pos[sa[i]]=i;
			REP(i,n) rmq[n+i]=lcp[i]; for(int i=n-1;i>=1;--i) rmq[i]=min(rmq[2*i+0],rmq[2*i+1]);
			auto getrmq=[&](int l,int r) { int ret=INT_MAX; for(l+=n,r+=n;l<r;l>>=1,r>>=1) { if(l&1) ret=min(ret,rmq[l++]); if(r&1) ret=min(ret,rmq[--r]); } return ret; };
			REP(i,n) if(lcp[i]==1<<k) { int ii=nxt(sa[i],k),jj=nxt(sa[i+1],k); if(ii==-1||jj==-1) continue;  ii=pos[ii],jj=pos[jj]; if(ii>jj) swap(ii,jj); lcp[i]+=ii==jj?1<<k:getrmq(ii,jj); }
			nid=0; id[0]=nid++; REP(i,n) if(i==0||id[sa[i]+1]!=id[sa[i-1]+1]||id[nxt(sa[i],k)+1]!=id[nxt(sa[i-1],k)+1]) tmp[sa[i]]=nid++; else tmp[sa[i]]=nid-1;
			REP(i,n) id[i+1]=tmp[i];
		}
	}
	void buildsalcp(const string &s) { buildsalcp(SZ(s),256,[&](int off) { return (int)s[off]; },[&](int off,int k) { return off+(1<<k)<SZ(s)?off+(1<<k):-1; }); }

	/*template<typename T> void buildlcp(T getlcp) { // getlcp(i,j,k) -> longest common prefix of two offsets (first k are guaranteed to match)
		int k=0; lcp=vector<int>(SZ(sa)); lcp.back()=-1;
		REPSZ(i,sa) {
			if(pos[i]+1>=SZ(sa)) { k=0; continue; }
			int j=sa[pos[i]+1];
			k=getlcp(i,j,k);
			lcp[pos[i]]=k; if(k>0) --k;
		}
	}
	void buildlcp(const string &s) { buildlcp([&](int i,int j,int k) { while(i+k<SZ(s)&&j+k<SZ(s)&&s[i+k]==s[j+k]) ++k; return k; }); }*/

	vector<int> bsllcp,bsrlcp; // bsllcp[m] and bsrlcp[m] are the lcps of (l,m) and (m,r) in binary search in find-method

	void buildbs() {
		bsllcp=bsrlcp=vector<int>(SZ(sa));
		std::function<int(int,int)> rec=[&](int l,int r)->int {
			if(r-l==1) return l==-1||r==SZ(sa)?0:lcp[l];
			int m=l+(r-l)/2;
			bsllcp[m]=rec(l,m); bsrlcp[m]=rec(m,r);
			return min(bsllcp[m],bsrlcp[m]);
		};
		rec(-1,SZ(sa));
	}

	template<typename T,typename U> int find(T getlcp,U cmp,bool upperbound=false) { // getlcp(off,k) -> longest common prefix with suffix starting at off (first k is guaranteed to match), cmp(off,k) -> comparison of k-th character with suffix starting at off
		int l=-1,r=SZ(sa),llcp=0,rlcp=0;
		while(r-l>=2) {
			int m=l+(r-l)/2;
			if(llcp>=rlcp) { if(bsllcp[m]>llcp) l=m; else if(bsllcp[m]<llcp) r=m,rlcp=bsllcp[m]; else { int nlcp=getlcp(sa[m],llcp); if(cmp(sa[m],nlcp)<(!upperbound?0:1)) l=m,llcp=nlcp; else r=m,rlcp=nlcp; } }
				      else { if(bsrlcp[m]<rlcp) l=m,llcp=bsrlcp[m]; else if(bsrlcp[m]>rlcp) r=m; else { int nlcp=getlcp(sa[m],rlcp); if(cmp(sa[m],nlcp)<(!upperbound?0:1)) l=m,llcp=nlcp; else r=m,rlcp=nlcp; } }
		}
		return r;
	}
	int find(const string &s,const string &p,bool upperbound=false) { return find([&](int i,int k) { while(i+k<SZ(s)&&k<SZ(p)&&s[i+k]==p[k]) ++k; return k; },[&](int i,int k){ if(k==SZ(p)) return 0; if(i+k==SZ(s)) return -1; char a=s[i+k],b=p[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; },upperbound); }
	template<typename T,typename U> pair<int,int> findrange(T getlcp,U cmp) { return MP(find(getlcp,cmp,false),find(getlcp,cmp,true)); }
	pair<int,int> findrange(const string &s,const string &p) { return findrange([&](int i,int k) { while(i+k<SZ(s)&&k<SZ(p)&&s[i+k]==p[k]) ++k; return k; },[&](int i,int k){ if(k==SZ(p)) return 0; if(i+k==SZ(s)) return -1; if(k==SZ(p)) return +1; char a=s[i+k],b=p[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; }); }
};

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=18;

int nsong;
int par[MAXSONG];
char parc[MAXSONG];
int nq;
int qidx[MAXQ],qoff[MAXQ+1],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

SuffixArray suff;

int up[MAXSONG][MAXLG+1];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXSONG];

vector<int> ch[MAXSONG];

int bit[MAXSONG+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REP(i,nsong) { int at=suff.sa[i]; printf("%2d:",at); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } printf(" (%d)\n",suff.lcp[i]); }
}

void dfs(int at) {
	bmod(suff.pos[at],+1);
	//printf("inc(%d)\n",suff.pos[at]);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		//printf("q[%d..%d)\n",l,r);
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	//printf("dec(%d)\n",suff.pos[at]);
	bmod(suff.pos[at],-1);
}

int walk(int i,int steps) { for(int k=MAXLG;k>=0;--k) if(steps&(1<<k)) if(i!=-1) i=up[i][k]; return i; }

void solve() {
	//REP(i,nsong) printf("par=%d parc=%c\n",par[i],parc[i]);

	REP(i,nsong) up[i][0]=par[i];
	REP(k,MAXLG) REP(i,nsong) up[i][k+1]=up[i][k]==-1?-1:up[up[i][k]][k];

	suff.buildsalcp(nsong,26,[&](int off) { return (int)(parc[off]-'a'); },[&](int off,int k) { return up[off][k]; });
	suff.buildbs();

	//print();

	REP(i,nsong) qat[i].clear();
	REP(i,nq) {
		string s(qs+qoff[i],qs+qoff[i]+qlen[i]);
		reverse(s.begin(),s.end());
		int l,r; tie(l,r)=suff.findrange([&](int i,int k) { i=walk(i,k); while(i!=-1&&k<SZ(s)&&parc[i]==s[k]) i=par[i],++k; return k; },[&](int i,int k) { i=walk(i,k); if(k==SZ(s)) return 0; if(i==-1) return -1; char a=parc[i],b=s[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; });
		//printf("%d=%s [%d..%d)\n",i,s.c_str(),l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REP(i,nsong) ch[i].clear();
	REP(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong) bit[i]=0;
	REP(i,nsong) if(par[i]==-1) dfs(i);
}

void run() {
	scanf("%d",&nsong);
	REP(i,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=-1; else scanf("%d",&par[i]),--par[i]; scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]),--qidx[i]; qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int qansstupid[MAXQ];

void solvestupid() {

	REP(i,nq) {
		vector<char> tmp;
		for(int at=qidx[i];at!=-1;at=par[at]) tmp.PB(parc[at]);
		reverse(tmp.begin(),tmp.end());
		qansstupid[i]=0;
		REPE(j,SZ(tmp)-qlen[i]) {
			bool ok=true; REP(k,qlen[i]) if(tmp[j+k]!=qs[qoff[i]+k]) { ok=false; break; } if(ok) ++qansstupid[i];
		}
	}
}

void stress() {
	int mxsong=1000,mxalph=3,mxqlen=5; nq=1000;
	REP(rep,100000) {
		nsong=rand()%mxsong+1;
		int alph=rand()%mxalph+1;
		REP(i,nsong) { par[i]=rand()%(i+1)-1; parc[i]='a'+rand()%alph; }
		qoff[0]=0; REP(i,nq) { qidx[i]=rand()%nsong; qlen[i]=rand()%mxqlen+1; REP(j,qlen[i]) qs[qoff[i]+j]='a'+rand()%alph; qoff[i+1]=qoff[i]+qlen[i]; } qs[qoff[nq]]='\0';
		//if(rep!=8889) continue;
		solve();
		solvestupid();
		bool ok=true; REP(i,nq) if(qans[i]!=qansstupid[i]) ok=false;
		//bool allzero=true; REP(i,nq) if(qans[i]!=0) allzero=false; printf("%c",allzero?'0':'+');
		if(ok) { if(rep%100==0) printf("."); continue; }
		printf("err rep=%d\n",rep);
		printf("%d\n",nsong);
		REP(i,nsong) if(par[i]==-1) printf("%d %c\n",1,parc[i]); else printf("%d %d %c\n",2,par[i]+1,parc[i]);
		printf("%d\n",nq);
		REP(i,nq) { printf("%d ",qidx[i]+1); REP(j,qlen[i]) printf("%c",qs[qoff[i]+j]); puts(""); }
		printf("have:"); REP(i,nq) printf(" %d",qans[i]); puts("");
		printf("want:"); REP(i,nq) printf(" %d",qansstupid[i]); puts("");
		break;
	}
}

int main() {
	run();
	//stress();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
#include <functional>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

struct SuffixArray {
	vector<int> sa; // sa[idx] = offset of idx-th suffix
	vector<int> pos; // pos[off] = index in suffix array of suffix at off
	vector<int> lcp; // lcp[idx] = longest common prefix of idth-th suffix and (idx+1)-th suffix

	vector<int> id; int nid; // id[0] = value of the empty suffix, id[off+1] = value of the suffix at off
	vector<int> tmp;
	vector<int> cnt;
	vector<int> rmq;

	template<typename T,typename U> void buildsalcp(int n,int alph,T val,U nxt) { // val(off) -> value at given offset, nxt(off,k) -> offset that is 2^k away
		cnt=vector<int>(max(alph,n+1),0); sa=tmp=pos=lcp=vector<int>(n); id=vector<int>(n+1); rmq=vector<int>(2*(n+1));
		REP(i,n) ++cnt[val(i)];
		for(int i=alph-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
		REP(i,alph-1) cnt[i+1]+=cnt[i];
		REP(i,n) sa[cnt[val(i)]++]=i;
		REP(i,n) pos[sa[i]]=i;
		nid=0; id[0]=nid++; REP(i,n) if(i==0||val(sa[i])!=val(sa[i-1])) id[sa[i]+1]=nid++; else id[sa[i]+1]=nid-1;
		REP(i,n) lcp[i]=i+1<n&&id[sa[i]+1]==id[sa[i+1]+1]?1:0;
		for(int k=0;;++k) {
			bool done=true; REP(i,n) if(lcp[i]==1<<k) done=false; if(done) break;
			REP(i,nid) cnt[i]=0;
			REP(i,n) ++cnt[id[nxt(i,k)+1]];
			for(int i=nid-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
			REP(i,nid-1) cnt[i+1]+=cnt[i];
			REP(i,n) tmp[cnt[id[nxt(i,k)+1]]++]=i;
			REP(i,nid) cnt[i]=0;
			REP(i,n) ++cnt[id[i+1]];
			for(int i=nid-2;i>=0;--i) cnt[i+1]=cnt[i]; cnt[0]=0;
			REP(i,nid-1) cnt[i+1]+=cnt[i];
			REP(i,n) sa[cnt[id[tmp[i]+1]]++]=tmp[i];
			REP(i,n) pos[sa[i]]=i;
			REP(i,n) rmq[n+i]=lcp[i]; for(int i=n-1;i>=1;--i) rmq[i]=min(rmq[2*i+0],rmq[2*i+1]);
			auto getrmq=[&](int l,int r) { int ret=INT_MAX; for(l+=n,r+=n;l<r;l>>=1,r>>=1) { if(l&1) ret=min(ret,rmq[l++]); if(r&1) ret=min(ret,rmq[--r]); } return ret; };
			REP(i,n) if(lcp[i]==1<<k) { int ii=nxt(sa[i],k),jj=nxt(sa[i+1],k); if(ii==-1||jj==-1) continue; ii=pos[ii],jj=pos[jj]; if(ii>jj) swap(ii,jj); lcp[i]+=id[ii+1]==id[jj+1]?1<<k:getrmq(ii,jj); }
			nid=0; id[0]=nid++; REP(i,n) if(i==0||id[sa[i]+1]!=id[sa[i-1]+1]||id[nxt(sa[i],k)+1]!=id[nxt(sa[i-1],k)+1]) tmp[sa[i]]=nid++; else tmp[sa[i]]=nid-1;
			REP(i,n) id[i+1]=tmp[i];
		}
	}
	void buildsalcp(const string &s) { buildsalcp(SZ(s),256,[&](int off) { return (int)s[off]; },[&](int off,int k) { return off+(1<<k)<SZ(s)?off+(1<<k):-1; }); }

	/*template<typename T> void buildlcp(T getlcp) { // getlcp(i,j,k) -> longest common prefix of two offsets (first k are guaranteed to match)
		int k=0; lcp=vector<int>(SZ(sa)); lcp.back()=-1;
		REPSZ(i,sa) {
			if(pos[i]+1>=SZ(sa)) { k=0; continue; }
			int j=sa[pos[i]+1];
			k=getlcp(i,j,k);
			lcp[pos[i]]=k; if(k>0) --k;
		}
	}
	void buildlcp(const string &s) { buildlcp([&](int i,int j,int k) { while(i+k<SZ(s)&&j+k<SZ(s)&&s[i+k]==s[j+k]) ++k; return k; }); }*/

	vector<int> bsllcp,bsrlcp; // bsllcp[m] and bsrlcp[m] are the lcps of (l,m) and (m,r) in binary search in find-method

	void buildbs() {
		bsllcp=bsrlcp=vector<int>(SZ(sa));
		std::function<int(int,int)> rec=[&](int l,int r)->int {
			if(r-l==1) return l==-1||r==SZ(sa)?0:lcp[l];
			int m=l+(r-l)/2;
			bsllcp[m]=rec(l,m); bsrlcp[m]=rec(m,r);
			return min(bsllcp[m],bsrlcp[m]);
		};
		rec(-1,SZ(sa));
	}

	template<typename T,typename U> int find(T getlcp,U cmp,bool upperbound=false) { // getlcp(off,k) -> longest common prefix with suffix starting at off (first k is guaranteed to match), cmp(off,k) -> comparison of k-th character with suffix starting at off
		int l=-1,r=SZ(sa),llcp=0,rlcp=0;
		while(r-l>=2) {
			int m=l+(r-l)/2;
			if(llcp>=rlcp) { if(bsllcp[m]>llcp) l=m; else if(bsllcp[m]<llcp) r=m,rlcp=bsllcp[m]; else { int nlcp=getlcp(sa[m],llcp); if(cmp(sa[m],nlcp)<(!upperbound?0:1)) l=m,llcp=nlcp; else r=m,rlcp=nlcp; } }
				      else { if(bsrlcp[m]<rlcp) l=m,llcp=bsrlcp[m]; else if(bsrlcp[m]>rlcp) r=m; else { int nlcp=getlcp(sa[m],rlcp); if(cmp(sa[m],nlcp)<(!upperbound?0:1)) l=m,llcp=nlcp; else r=m,rlcp=nlcp; } }
		}
		return r;
	}
	int find(const string &s,const string &p,bool upperbound=false) { return find([&](int i,int k) { while(i+k<SZ(s)&&k<SZ(p)&&s[i+k]==p[k]) ++k; return k; },[&](int i,int k){ if(k==SZ(p)) return 0; if(i+k==SZ(s)) return -1; char a=s[i+k],b=p[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; },upperbound); }
	template<typename T,typename U> pair<int,int> findrange(T getlcp,U cmp) { return MP(find(getlcp,cmp,false),find(getlcp,cmp,true)); }
	pair<int,int> findrange(const string &s,const string &p) { return findrange([&](int i,int k) { while(i+k<SZ(s)&&k<SZ(p)&&s[i+k]==p[k]) ++k; return k; },[&](int i,int k){ if(k==SZ(p)) return 0; if(i+k==SZ(s)) return -1; if(k==SZ(p)) return +1; char a=s[i+k],b=p[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; }); }
};

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=18;

int nsong;
int par[MAXSONG];
char parc[MAXSONG];
int nq;
int qidx[MAXQ],qoff[MAXQ+1],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

SuffixArray suff;

int up[MAXSONG][MAXLG+1];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXSONG];

vector<int> ch[MAXSONG];

int bit[MAXSONG+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REP(i,nsong) { int at=suff.sa[i]; printf("%2d:",at); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } printf(" (%d)\n",suff.lcp[i]); }
}

void dfs(int at) {
	bmod(suff.pos[at],+1);
	//printf("inc(%d)\n",suff.pos[at]);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		//printf("q[%d..%d)\n",l,r);
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	//printf("dec(%d)\n",suff.pos[at]);
	bmod(suff.pos[at],-1);
}

int walk(int i,int steps) { for(int k=MAXLG;k>=0;--k) if(steps&(1<<k)) if(i!=-1) i=up[i][k]; return i; }

void solve() {
	//REP(i,nsong) printf("par=%d parc=%c\n",par[i],parc[i]);

	REP(i,nsong) up[i][0]=par[i];
	REP(k,MAXLG) REP(i,nsong) up[i][k+1]=up[i][k]==-1?-1:up[up[i][k]][k];

	suff.buildsalcp(nsong,26,[&](int off) { return (int)(parc[off]-'a'); },[&](int off,int k) { return up[off][k]; });
	suff.buildbs();

	//print();

	REP(i,nsong) qat[i].clear();
	REP(i,nq) {
		string s(qs+qoff[i],qs+qoff[i]+qlen[i]);
		reverse(s.begin(),s.end());
		int l,r; tie(l,r)=suff.findrange([&](int i,int k) { i=walk(i,k); while(i!=-1&&k<SZ(s)&&parc[i]==s[k]) i=par[i],++k; return k; },[&](int i,int k) { i=walk(i,k); if(k==SZ(s)) return 0; if(i==-1) return -1; char a=parc[i],b=s[k]; if(a!=b) return a<b?-1:+1; assert(false); return 0; });
		//printf("%d=%s [%d..%d)\n",i,s.c_str(),l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REP(i,nsong) ch[i].clear();
	REP(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong) bit[i]=0;
	REP(i,nsong) if(par[i]==-1) dfs(i);
}

void run() {
	scanf("%d",&nsong);
	REP(i,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=-1; else scanf("%d",&par[i]),--par[i]; scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]),--qidx[i]; qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int qansstupid[MAXQ];

void solvestupid() {

	REP(i,nq) {
		vector<char> tmp;
		for(int at=qidx[i];at!=-1;at=par[at]) tmp.PB(parc[at]);
		reverse(tmp.begin(),tmp.end());
		qansstupid[i]=0;
		REPE(j,SZ(tmp)-qlen[i]) {
			bool ok=true; REP(k,qlen[i]) if(tmp[j+k]!=qs[qoff[i]+k]) { ok=false; break; } if(ok) ++qansstupid[i];
		}
	}
}

void stress() {
	int mxsong=1000,mxalph=3,mxqlen=5; nq=1000;
	REP(rep,100000) {
		nsong=rand()%mxsong+1;
		int alph=rand()%mxalph+1;
		REP(i,nsong) { par[i]=rand()%(i+1)-1; parc[i]='a'+rand()%alph; }
		qoff[0]=0; REP(i,nq) { qidx[i]=rand()%nsong; qlen[i]=rand()%mxqlen+1; REP(j,qlen[i]) qs[qoff[i]+j]='a'+rand()%alph; qoff[i+1]=qoff[i]+qlen[i]; } qs[qoff[nq]]='\0';
		//if(rep!=8889) continue;
		solve();
		solvestupid();
		bool ok=true; REP(i,nq) if(qans[i]!=qansstupid[i]) ok=false;
		//bool allzero=true; REP(i,nq) if(qans[i]!=0) allzero=false; printf("%c",allzero?'0':'+');
		if(ok) { if(rep%100==0) printf("."); continue; }
		printf("err rep=%d\n",rep);
		printf("%d\n",nsong);
		REP(i,nsong) if(par[i]==-1) printf("%d %c\n",1,parc[i]); else printf("%d %d %c\n",2,par[i]+1,parc[i]);
		printf("%d\n",nq);
		REP(i,nq) { printf("%d ",qidx[i]+1); REP(j,qlen[i]) printf("%c",qs[qoff[i]+j]); puts(""); }
		printf("have:"); REP(i,nq) printf(" %d",qans[i]); puts("");
		printf("want:"); REP(i,nq) printf(" %d",qansstupid[i]); puts("");
		break;
	}
}

int main() {
	run();
	//stress();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=19;

int nsong;
int par[MAXNODE];
char parc[MAXNODE];
int nq;
int qidx[MAXQ],qoff[MAXQ+1],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

int sa[MAXNODE];
int val[MAXNODE];
int pos[MAXNODE];

int up[MAXNODE][MAXLG+1];
int cnt[MAXNODE+1];
int tmp[MAXNODE];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXNODE];

vector<int> ch[MAXNODE];

int bit[MAXNODE+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong+1) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REPE(i,nsong) { int at=sa[i]; printf("%2d (%2d):",at,val[at]); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } puts(""); }
}

int cmp(int at,char *s,int len) {
	REP(i,len) {
		char a=parc[at],b=s[i]; if(a!=b) return a<b?-1:+1;
		at=par[at];
	}
	return 0;
}

void dfs(int at) {
	bmod(pos[at],+1);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	bmod(pos[at],-1);
}

void solve() {
	REPE(i,nsong) up[i][0]=par[i]==-1?i:par[i];
	REP(k,MAXLG) REPE(i,nsong) up[i][k+1]=up[up[i][k]][k];

	int alph=256;
	REP(i,alph) cnt[i]=0;
	REPE(i,nsong) ++cnt[(int)parc[i]];
	for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
	REP(i,alph) cnt[i+1]+=cnt[i];
	REPE(i,nsong) sa[cnt[(int)parc[i]]++]=i;
	alph=0; REPE(i,nsong) if(i!=0&&parc[sa[i]]==parc[sa[i-1]]) val[sa[i]]=alph-1; else val[sa[i]]=alph++;
	REPE(k,MAXLG) {
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[up[i][k]]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) tmp[cnt[val[up[i][k]]]++]=i;
		//printf("tmp:"); REPE(i,nsong) printf(" %d",tmp[i]); puts("");
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[i]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) sa[cnt[val[tmp[i]]]++]=tmp[i];
		alph=0; REPE(i,nsong) if(i!=0&&val[sa[i]]==val[sa[i-1]]&&val[up[sa[i]][k]]==val[up[sa[i-1]][k]]) tmp[sa[i]]=alph-1; else tmp[sa[i]]=alph++;
		REPE(i,nsong) val[i]=tmp[i];
	}
	REPE(i,nsong) pos[sa[i]]=i;
	//printf("alph=%d\n",alph); print();

	REPE(i,nsong) qat[i].clear();
	REP(i,nq) {
		reverse(qs+qoff[i],qs+qoff[i]+qlen[i]);
		int l,r;
		// find first index such that value>=query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])>=0) hi=mi; else lo=mi; } l=hi; }
		// find first index such that value> query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])> 0) hi=mi; else lo=mi; } r=hi; }
		reverse(qs+qoff[i],qs+qoff[i]+qlen[i]);
		//printf("%d: [%d..%d)\n",i,l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REPE(i,nsong) ch[i].clear();
	REPE(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong+1) bit[i]=0;
	dfs(0);
}

void run() {
	scanf("%d",&nsong);
	par[0]=-1,parc[0]='-';
	FORE(i,1,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=0; else scanf("%d",&par[i]); scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]); qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int qansstupid[MAXQ];

void solvestupid() {

	REP(i,nq) {
		vector<char> tmp;
		for(int at=qidx[i];parc[at]!='-';at=par[at]) tmp.PB(parc[at]);
		reverse(tmp.begin(),tmp.end());
		qansstupid[i]=0;
		REPE(j,SZ(tmp)-qlen[i]) {
			bool ok=true; REP(k,qlen[i]) if(tmp[j+k]!=qs[qoff[i]+k]) { ok=false; break; } if(ok) ++qansstupid[i];
		}
	}
}

void stress() {
	int mxsong=10000,mxalph=3,mxqlen=10; nq=10000;
	REP(rep,100000) {
		nsong=rand()%mxsong+1;
		par[0]=-1,parc[0]='-';
		int alph=rand()%mxalph+1;
		FORE(i,1,nsong) { par[i]=rand()%i; parc[i]='a'+rand()%alph; }
		qoff[0]=0; REP(i,nq) { qidx[i]=rand()%(nsong+1); qlen[i]=rand()%mxqlen+1; REP(j,qlen[i]) qs[qoff[i]+j]='a'+rand()%alph; qoff[i+1]=qoff[i]+qlen[i]; } qs[qoff[nq]]='\0';
		solve();
		solvestupid();
		bool ok=true; REP(i,nq) if(qans[i]!=qansstupid[i]) ok=false;
		//bool allzero=true; REP(i,nq) if(qans[i]!=0) allzero=false; printf("%c",allzero?'0':'+');
		if(ok) { if(rep%100==0) printf("."); continue; }
		printf("err rep=%d\n",rep);
		printf("%d\n",nsong);
		FORE(i,1,nsong) if(par[i]==0) printf("%d %c\n",1,parc[i]); else printf("%d %d %c\n",2,par[i],parc[i]);
		printf("%d\n",nq);
		REP(i,nq) { printf("%d ",qidx[i]); REP(j,qlen[i]) printf("%c",qs[qoff[i]+j]); puts(""); }
		printf("have:"); REP(i,nq) printf(" %d",qans[i]); puts("");
		printf("want:"); REP(i,nq) printf(" %d",qansstupid[i]); puts("");
	}
}

int main() {
	run();
	//stress();
	return 0;
}


#include <algorithm>
#include <iostream>
#include <sstream>
#include <string>
#include <vector>
#include <queue>
#include <set>
#include <map>
#include <cstdio>
#include <cstdlib>
#include <cctype>
#include <cmath>
#include <cstring>
#include <list>
#include <cassert>
#include <climits>
#include <bitset>
using namespace std;

#define PB push_back
#define MP make_pair
#define SZ(v) ((int)(v).size())
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define FORE(i,a,b) for(int i=(a);i<=(b);++i)
#define REPE(i,n) FORE(i,0,n)
#define FORSZ(i,a,v) FOR(i,a,SZ(v))
#define REPSZ(i,v) REP(i,SZ(v))
typedef long long ll;
ll gcd(ll a,ll b) { return b==0?a:gcd(b,a%b); }

const int MAXSONG=400000;
const int MAXQ=400000;
const int MAXNODE=MAXSONG+1;
const int MAXQLEN=400000;
const int MAXLG=18;

int nsong;
int par[MAXNODE];
char parc[MAXNODE];
int nq;
int qidx[MAXQ],qoff[MAXQ],qlen[MAXQ]; char qs[MAXQLEN+1]; int qans[MAXQ];

int sa[MAXNODE];
int val[MAXNODE];
int pos[MAXNODE];

int up[MAXNODE][MAXLG+1];
int cnt[MAXNODE+1];
int tmp[MAXNODE];

int ql[MAXQ],qr[MAXQ];
vector<int> qat[MAXNODE];

vector<int> ch[MAXNODE];

int bit[MAXNODE+1];
int bget(int idx) { ++idx; int ret=0; while(idx>0) { ret+=bit[idx]; idx-=idx&-idx; } return ret; }
void bmod(int idx,int by) { ++idx; while(idx<=nsong+1) { bit[idx]+=by; idx+=idx&-idx; } }

void print() {
	REPE(i,nsong) { int at=sa[i]; printf("%2d (%2d):",at,val[at]); while(at!=-1) { printf("%c",parc[at]); at=par[at]; } puts(""); }
}

int cmp(int at,char *s,int len) {
	REP(i,len) {
		char a=parc[at],b=s[i]; if(a!=b) return a<b?-1:+1;
		at=par[at];
	}
	return 0;
}

void dfs(int at) {
	bmod(pos[at],+1);
	REPSZ(_,qat[at]) {
		int id=qat[at][_],l=ql[id],r=qr[id];
		qans[id]=bget(r-1)-bget(l-1);
	}
	REPSZ(i,ch[at]) {
		int to=ch[at][i];
		dfs(to);
	}
	bmod(pos[at],-1);
}

void solve() {
	REPE(i,nsong) up[i][0]=par[i]==-1?i:par[i];
	REP(k,MAXLG) REPE(i,nsong) up[i][k+1]=up[up[i][k]][k];

	int alph=256;
	REP(i,alph) cnt[i]=0;
	REPE(i,nsong) ++cnt[(int)parc[i]];
	for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
	REP(i,alph) cnt[i+1]+=cnt[i];
	REPE(i,nsong) sa[cnt[(int)parc[i]]++]=i;
	alph=0; REPE(i,nsong) if(i!=0&&parc[sa[i]]==parc[sa[i-1]]) val[sa[i]]=alph-1; else val[sa[i]]=alph++;
	REPE(k,MAXLG) {
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[up[i][k]]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) tmp[cnt[val[up[i][k]]]++]=i;
		//printf("tmp:"); REPE(i,nsong) printf(" %d",tmp[i]); puts("");
		REP(i,alph) cnt[i]=0;
		REPE(i,nsong) ++cnt[val[i]];
		for(int i=alph-1;i>=0;--i) cnt[i+1]=cnt[i],cnt[i]=0;
		REP(i,alph) cnt[i+1]+=cnt[i];
		REPE(i,nsong) sa[cnt[val[tmp[i]]]++]=tmp[i];
		alph=0; REPE(i,nsong) if(i!=0&&val[sa[i]]==val[sa[i-1]]&&val[up[sa[i]][k]]==val[up[sa[i-1]][k]]) tmp[sa[i]]=alph-1; else tmp[sa[i]]=alph++;
		REPE(i,nsong) val[i]=tmp[i];
	}
	REPE(i,nsong) pos[sa[i]]=i;
	//printf("alph=%d\n",alph); print();

	REPE(i,nsong) qat[i].clear();
	REP(i,nq) {
		reverse(qs+qoff[i],qs+qoff[i]+qlen[i]);
		int l,r;
		// find first index such that value>=query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])>=0) hi=mi; else lo=mi; } l=hi; }
		// find first index such that value> query string
		{ int lo=-1,hi=nsong+1; while(lo+1<hi) { int mi=lo+(hi-lo)/2; if(cmp(sa[mi],qs+qoff[i],qlen[i])> 0) hi=mi; else lo=mi; } r=hi; }
		//printf("%d: [%d..%d)\n",i,l,r);
		ql[i]=l,qr[i]=r; qat[qidx[i]].PB(i);
	}

	REPE(i,nsong) ch[i].clear();
	REPE(i,nsong) if(par[i]!=-1) ch[par[i]].PB(i);
	REPE(i,nsong+1) bit[i]=0;
	dfs(0);
}

void run() {
	scanf("%d",&nsong);
	par[0]=-1,parc[0]='-';
	FORE(i,1,nsong) { int kind; scanf("%d",&kind); if(kind==1) par[i]=0; else scanf("%d",&par[i]); scanf(" %c",&parc[i]); }
	scanf("%d",&nq);
	qoff[0]=0; REP(i,nq) { scanf("%d%s",&qidx[i],qs+qoff[i]); qlen[i]=strlen(qs+qoff[i]); qoff[i+1]=qoff[i]+qlen[i]; }
	solve();
	REP(i,nq) printf("%d\n",qans[i]);
}

int main() {
	run();
	return 0;
}


#include    <bits/stdc++.h>
#define fo(i,a,b) for(int i=(a);i<=(b);++i)
#define __unique(V) (V).resize(unique((V).begin(),(V).end())-(V).begin())
#define cntbit(X)   __builtin_popcount((X))
#define bit(S,i) (((S)>>(i))&1)
#define PI	acos(-1)
#define fi  first
#define se  second
#define LL  long long
#define ii  pair<int,int>
#define iii pair<int,ii>
#define eb  emplace_back
#define TASK "1207G"
using namespace std;
const int maxn =4e5 + 505;
int trie[maxn][30],nxt[maxn][30],link[maxn];
int Din[maxn],Dou[maxn],BIT[maxn];
int cnt,Euler,n,ans[maxn],m;
vector <ii> song[maxn],qr[maxn];
vector <int> tree[maxn];
///--------------------------
void    readf(){
    cin >> n;
    fo(i,1,n){
        int type;
        char c;
        int par;
        cin >> type;
        if (type == 1) par = 0;
        else cin >> par;
        cin >> c;
        song[par].eb(i,c - 'a');
    }
}
///--------------------------
int	add(string t){
    int node = 0;
    for(auto it : t){
		int c = it - 'a';
        if (trie[node][c] == 0) trie[node][c] = ++cnt;
        node = trie[node][c];
    }
    return node;
}
///--------------------------
void	BFS(){
    queue <int> qu;
    qu.push(0);
    while (qu.size()){
		int u = qu.front();
        qu.pop();
        for(int c = 0; c < 26; ++c){
            nxt[u][c] = nxt[link[u]][c];
            int v = trie[u][c];
            if (v){
                link[v] = nxt[u][c];
                nxt[u][c] = v;
				qu.push(v);
            }
        }
    }
    fo(i,1,cnt) tree[link[i]].eb(i);
}
///--------------------------
void    DFS_Tree(int u){
    Din[u] = ++Euler;
    for(auto v : tree[u]) DFS_Tree(v);
    Dou[u] = Euler;
}
///--------------------------
void	add(int x,int v){
    for(; x < maxn; x += -x & x)
		BIT[x] += v;
}
///--------------------------
int	get(int x){
	int ans = 0;
    for(; x > 0; x -= -x & x)
		ans += BIT[x];
	return ans;
}
int get(int l,int r){
    return get(r) - get(l - 1);
}
///--------------------------
void	DFS(int u,int par){
    add(Din[par],1);
    for(auto it : qr[u])
		ans[it.se] = get(Din[it.fi],Dou[it.fi]);
    for(auto it : song[u])
        DFS(it.fi,nxt[par][it.se]);
    add(Din[par], -1);
}
///--------------------------
void    solve(){
	cnt = Euler = 0;
    cin >> m;
    fo(i,1,m){
    	int id;
    	string t;
        cin >> id >> t;
        qr[id].eb(add(t),i);
    }
    BFS();
    DFS_Tree(0);
    DFS(0,0);
    fo(i,1,m) cout << ans[i] << '\n';
}
///--------------------------
int     main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    #ifdef TLH2203
        freopen(TASK".inp", "r", stdin);
        freopen(TASK".out", "w", stdout);
    #endif // TLH2203
    readf();
    solve();
}


#include    <bits/stdc++.h>
#define fo(i,a,b) for(int i=(a);i<=(b);++i)
#define __unique(V) (V).resize(unique((V).begin(),(V).end())-(V).begin())
#define cntbit(X)   __builtin_popcount((X))
#define bit(S,i) (((S)>>(i))&1)
#define PI	acos(-1)
#define fi  first
#define se  second
#define LL  long long
#define ii  pair<int,int>
#define iii pair<int,ii>
#define eb  emplace_back
#define TASK "1207G"
using namespace std;
const int maxn =4e5 + 10;
int trie[maxn][30],nxt[maxn][30],link[maxn];
int Din[maxn],Dou[maxn],BIT[maxn];
int cnt,Euler,n,ans[maxn],m;
vector <ii> song[maxn],qr[maxn];
vector <int> tree[maxn];
///--------------------------
void    readf(){
    cin >> n;
    fo(i,1,n){
        int type;
        char c;
        int par;
        cin >> type;
        if (type == 1) par = 0;
        else cin >> par;
        cin >> c;
        song[par].eb(i,c - 'a');
    }
}
///--------------------------
int	add(string t){
    int node = 0;
    for(auto it : t){
		int c = it - 'a';
        if (trie[node][c] == 0) trie[node][c] = ++cnt;
        node = trie[node][c];
    }
    return node;
}
///--------------------------
void	BFS(){
    queue <int> qu;
    qu.push(0);
    while (qu.size()){
		int u = qu.front();
        qu.pop();
        for(int c = 0; c < 26; ++c){
            nxt[u][c] = nxt[link[u]][c];
            int v = trie[u][c];
            if (v){
                link[v] = nxt[u][c];
                nxt[u][c] = v;
				qu.push(v);
            }
        }
    }
    fo(i,1,cnt) tree[link[i]].eb(i);
}
///--------------------------
void    DFS_Tree(int u){
    Din[u] = ++Euler;
    for(auto v : tree[u]) DFS_Tree(v);
    Dou[u] = Euler;
}
///--------------------------
void	add(int x,int v){
    for(; x < maxn; x += -x & x)
		BIT[x] += v;
}
///--------------------------
int	get(int x){
	int ans = 0;
    for(; x > 0; x -= -x & x)
		ans += BIT[x];
	return ans;
}
int get(int l,int r){
    return get(r) - get(l - 1);
}
///--------------------------
void	DFS(int u,int par){
    add(Din[par],1);
    for(auto it : qr[u])
		ans[it.se] = get(Din[it.fi],Dou[it.fi]);
    for(auto it : song[u])
        DFS(it.fi,nxt[par][it.se]);
    add(Dou[par], -1);
}
///--------------------------
void    solve(){
	cnt = Euler = 0;
    cin >> m;
    fo(i,1,m){
    	int id;
    	string t;
        cin >> id >> t;
        qr[id].eb(add(t),i);
    }
    BFS();
    DFS_Tree(0);
    DFS(0,0);
    fo(i,1,m) cout << ans[i] << '\n';
}
///--------------------------
int     main(){
    ios::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    #ifdef TLH2203
        freopen(TASK".inp", "r", stdin);
        freopen(TASK".out", "w", stdout);
    #endif // TLH2203
    readf();
    solve();
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <random>
#include <chrono>

using namespace std;
using namespace __gnu_pbds;

#define endl '\n'

typedef long long ll;
typedef pair<int, int> pii;
//typedef tree<int,null_type,less<int>,rb_tree_tag, tree_order_statistics_node_update> indexed_set;

//mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());

typedef vector<vector<int>> graph;

const int maxn = 4e5 + 5;
const int alpha = 26;
const int init = 'a';

int go[maxn][alpha];
int fail[maxn], ans[maxn], query[maxn];
bool final[maxn];
char letter[maxn];
int idx = 2;
vector<int> t[maxn];
vector<pii> queries[maxn];

void insert(string s, int p){
    int node = 1;
    int n = s.size();
    for(int i = 0; i < n; i++){
        if(!go[node][s[i] - init])
            go[node][s[i] - init] = idx++;
        node = go[node][s[i] - init];
    }
    final[node] = true;
    query[p] = node;
}

void build(){
    queue<int> Q;

    for(int i = 0; i < alpha; i++){
        if(!go[1][i])
            go[1][i] = 1;
        else
            Q.push(go[1][i]), fail[go[1][i]] = 1;
    }

    fail[1] = 1;

    while(!Q.empty()){
        int u = Q.front();Q.pop();
        int f = fail[u];

        for(int i = 0; i < alpha; i++){
            if(!go[u][i])
                go[u][i] = go[f][i];
            else{
                fail[go[u][i]] = go[f][i];
                final[go[u][i]] |= final[go[f][i]];
                Q.push(go[u][i]);
            }
        }
    }
}

struct segment_tree{

	vector<ll> st, lazy;

	segment_tree(int n): st(4 * n), lazy(4 * n){ }

	void add_lazy(int node, int b, int e, ll x){
		st[node] += 1ll * (e - b + 1) * x;
		lazy[node] += x;
	}

	void push(int node, int b, int e){
		if(b == e || !lazy[node])
			return;

		int m = (b + e) >> 1;
		int l = node << 1;
		int r = l | 1;

		add_lazy(l, b, m, lazy[node]);
		add_lazy(r, m + 1, e, lazy[node]);

		lazy[node] = 0;
	}

	void update(int node, int b, int e, int i, int j, ll val){
		if(b >= i && e <= j){
			add_lazy(node, b, e, val);
			return;
		}

		if(b > j || e < i)
			return;

		int m = (b + e) >> 1;
		int l = node << 1;
		int r = l | 1;

		push(node, b, e);

		update(l, b, m, i, j, val);
		update(r, m + 1, e, i, j, val);

		st[node] = st[l] + st[r];

	}

	ll query(int node, int b, int e, int i, int j){
		if(b >= i && e <= j)
			return st[node];
		if(b > j || e < i)
			return 0;

		int m = (b + e) >> 1;
		int l = node << 1;
		int r = l | 1;

		push(node, b, e);

		ll L = query(l, b, m, i, j);
		ll R = query(r, m + 1, e, i, j);

		return L + R;
	}

};

struct heavy_light{
    int n, heavy[maxn], root[maxn], depth[maxn];
    int pos[maxn], ipos[maxn], parent[maxn];

    int dfs(int s, int f, graph &G){
        parent[s] = f, heavy[s] = -1;
        int size = 1, maxSubtree = 0;

        for (auto u : G[s]) if (u != f){
            depth[u] = depth[s] + 1;
            int subtree = dfs(u, s, G);

            if (subtree > maxSubtree)
                heavy[s] = u, maxSubtree = subtree;

            size += subtree;
        }

        return size;
    }

    void go(graph &G, int ROOT=0){
        n = (int)G.size();

        depth[ROOT] = 0;
        dfs(ROOT, -1, G);

        for (int i = 0, currentPos = 0; i < n; ++i)
            if (parent[i] == -1 || heavy[parent[i]] != i)
                for (int u = i; u != -1; u = heavy[u], currentPos++)
                    root[u] = i, pos[u] = currentPos, ipos[currentPos] = u;
    }

    int query(int u, int v, segment_tree &ST){
        int ans = 0;
        for (; root[u] != root[v]; v = parent[root[v]]) {
            if (depth[root[u]] > depth[root[v]]) swap(u, v);
            ans += ST.query(1, 0, n - 1, pos[root[v]], pos[v]);
        }
        if (depth[u] > depth[v]) swap(u, v);
        ans += ST.query(1, 0, n - 1, pos[u], pos[v]);

        // LCA at u
        return ans;
    }

    void update(int u, int v, segment_tree &ST, ll val){

        for (; root[u] != root[v]; v = parent[root[v]]) {
            if (depth[root[u]] > depth[root[v]]) swap(u, v);
            ST.update(1, 0, n - 1, pos[root[v]], pos[v], val);
        }
        if (depth[u] > depth[v]) swap(u, v);
        ST.update(1, 0, n - 1, pos[u], pos[v], val);
    }
};

heavy_light hld;

void dfs(int u, int st, segment_tree &ST){

	hld.update(0, st - 1, ST, +1);

	for(auto &qr : queries[u]){
		int idx = qr.first;
		int node = qr.second;
		ans[idx] = hld.query(node - 1, node - 1, ST);
	}

	for(auto &v : t[u]){
		int nxt = go[st][letter[v] - init];
		dfs(v, nxt, ST);
	}

	hld.update(0, st - 1, ST, -1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);

	//freopen("input.txt", "r", stdin);
	//freopen("output.txt", "w", stdout);

	int n;
	cin >> n;

	for(int i = 1; i <= n; i++){
		int op;
		cin >> op;
		if(op == 1){
			char c;
			cin >> c;
			letter[i] = c;
			t[0].push_back(i);
		}
		else{
			int adj;
			char c;
			cin >> adj >> c;
			letter[i] = c;
			t[adj].push_back(i);
		}
	}

	int q;
	cin >> q;

	for(int i = 0; i < q; i++){
		int idx;
		string s;
		cin >> idx >> s;
		insert(s, i);
		queries[idx].push_back({i, query[i]});
	}

	build();

	graph g(idx - 1);
	for(int i = 2; i < idx; i++)
		g[fail[i] - 1].push_back(i - 1);

	hld.go(g);
	segment_tree st(idx - 1);

	dfs(0, 1, st);

	for(int i = 0; i < q; i++)
		cout << ans[i] << endl;

	return 0;
}


#include <iostream>
#include <algorithm>
#include <fstream>
#include <vector>
#include <deque>
#include <assert.h>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <stdio.h>
#include <string.h>
#include <utility>
#include <math.h>
#include <bitset>
#include <iomanip>
#include <complex>

using namespace std;

#define mp make_pair
#define x first
#define y second
#define pb push_back
#define ALL(x) (x).begin(), (x).end()

typedef long long LL;

const int N = (int) 1e6 + 6, mod = (int) 0;
int sz = 1, nxt[N][26], inside[N], qv[N], qpos[N], q[N], f[N], fen[N], st[N], ed[N], tot;
vector<int> queries[N], inc[N], adj[N], trie_adj[N];
void aho_corasick() {
	int h = 0, t = 0;
	for (int j = 0; j < 26; ++j)
		if (nxt[0][j])
			q[t++] = nxt[0][j];
	while (h != t) {
		int v = q[h++];
		for (int c = 0; c < 26; ++c)
			if (nxt[v][c]) {
				f[nxt[v][c]] = nxt[f[v]][c];
				q[t++] = nxt[v][c];
			} else {
				nxt[v][c] = nxt[f[v]][c];
			}
	}
}
void update(int m, int x) { ++m;
	while (m < N) {
		fen[m] += x;
		m += m & -m;
	}
}
int query(int m) { ++m;
	int res = 0;
	while (m > 0) {
		res += fen[m];
		m -= m & -m;
	}
	return res;
}
int query(int l, int r) {
	return query(r - 1) - query(l - 1);
}
void dfs_init(int v) {
	st[v] = tot++;
	for (int u : adj[v]) {
		dfs_init(u);
	}
	ed[v] = tot;
}
int res[N];
void dfs_res(int v) {
	update(st[v], +1);
	for (int j : inc[v])
		for (int q : queries[j]) {
			int u = qv[q];
			res[q] = query(st[u], ed[u]);
		}
	for (int u : trie_adj[v]) {
		dfs_res(u);
	}
	update(st[v], -1);
}
int main() {
	ios_base::sync_with_stdio(0);
	int n;
	cin >> n;
	for (int j = 0; j < n; ++j) {
		int t;
		cin >> t;
		if (t == 1) {
			char c;
			cin >> c;
			if (!nxt[0][c - 'a']) {
				nxt[0][c - 'a'] = sz++;
			}
			inc[nxt[0][c - 'a']].pb(j);
			inside[j] = nxt[0][c - 'a'];
		} else {
			int pos;
			char c;
			cin >> pos >> c;
			c -= 'a';
			--pos;
			int v = inside[pos];
			if (!nxt[v][c]) {
				nxt[v][c] = sz++;
			}
			inc[nxt[v][c]].pb(j);
			inside[j] = nxt[v][c];
		}
	}
	int m;
	cin >> m;
	for (int j = 0; j < m; ++j) {
		int &pos = qpos[j];
		string t;
		cin >> pos >> t;
		--pos;
		int v = 0;
		for (char c : t) {
			if (!nxt[v][c - 'a']) {
				nxt[v][c - 'a'] = sz++;
			}
			v = nxt[v][c - 'a'];
		}
		qv[j] = v;
		queries[pos].pb(j);
	}
	for (int v = 0; v < sz; ++v)
		for (int c = 0; c < 26; ++c)
			if (nxt[v][c])
				trie_adj[v].pb(nxt[v][c]);
	aho_corasick();
	for (int v = 1; v < sz; ++v) {
		adj[f[v]].push_back(v);
	}
	dfs_init(0);
	dfs_res(0);
	for (int j = 0; j < m; ++j)
		cout << res[j] << '\n';
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
string RS;
int ind[404040];
ll ret[404040];

struct SuffixArray {
	int N; vector<int> rank,lcp,sa,rsa; string S;

	void build(string S){
		this->S=S;
		int i,h=0; vector<int> tmp;
		N=S.size(); rank.resize(N+1); sa.resize(N+1); tmp.resize(N+1);
		FOR(i,N+1) sa[i]=i, rank[i]=i==N?-1:S[i];

		for(int k=1; k<=N; k<<=1) {
			auto pred2 = [k,this](int& a,int &b)->bool{ return (((a+k<=N)?rank[a+k]:-1)<((b+k<=N)?rank[b+k]:-1));};
			auto pred = [pred2,k,this](int& a,int &b)->bool{ return (rank[a]!=rank[b])?(rank[a]<rank[b]):pred2(a,b);};
			int x=0;
			if(k!=1) for(i=1;i<N+1;i++) if(rank[sa[i]]!=rank[sa[x]]) sort(sa.begin()+x,sa.begin()+i,pred2), x=i;
			sort(sa.begin()+x,sa.end(),pred);
			FOR(i,N+1) tmp[sa[i]]=(i==0)?0:tmp[sa[i-1]]+pred(sa[i-1],sa[i]);
			swap(rank,tmp);
		}
		lcp.resize(N+1); rsa.resize(N+1);
		FOR(i,N+1) rsa[sa[i]]=i;
		FOR(i,N) {
			int j=sa[rsa[i]-1];
			for(h=max(h-1,0);i+h<N && j+h<N; h++) if(S[j+h]!=S[i+h]) break;
			lcp[rsa[i]-1]=h;
		}
	}
};
SuffixArray sa;

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

template<class V,int NV> class SegTree_1 {
public:
	vector<V> val;
	static V const def=1<<20;
	V comp(V l,V r){ return min(l,r);};

	SegTree_1(){val=vector<V>(NV*2,0);};
	V getval(int x,int y,int l=0,int r=NV,int k=1) { // x<=i<y
		if(r<=x || y<=l) return def;
		if(x<=l && r<=y) return val[k];
		return comp(getval(x,y,l,(l+r)/2,k*2),getval(x,y,(l+r)/2,r,k*2+1));
	}
	void update(int entry, V v) {
		entry += NV;
		val[entry]=v;
		while(entry>1) entry>>=1, val[entry]=comp(val[entry*2],val[entry*2+1]);
	}
};
SegTree_1<int,1<<20> st;

template<class V, int ME> class BIT {
public:
	V bit[1<<ME];
	V operator()(int e) {if(e<0) return 0;V s=0;e++;while(e) s+=bit[e-1],e-=e&-e; return s;}
	void add(int e,V v) { e++; while(e<=1<<ME) bit[e-1]+=v,e+=e&-e;}
};
BIT<ll,20> bt;

class ACmatch_enum {
public:
	Trie t;
	vector<vector<int> > acc;
	int ma;
	void create(vector<string> S) {
		int i,j;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) {
			int st=ind[i];
			int cur=0;
			FOR(j,S[i].size()) {
				cur=t.V[cur][S[i][j]+1];
				int tar=sa.rsa[ind[i]+S[i].size()-1-j];
				if(acc[cur].empty()) acc[cur].push_back(tar);
			}
		}
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
			}
		}
	}

	void dfs(int cur,int pos) {
		//cout<<cur<<" ";
		int i;
		//FOR(i,RS.size()) cout<<bt(i)-bt(i-1);
		//cout<<endl;

		FORR(e,ev[cur]) {
			int L=sa.rsa[ind[e]],R=L;
			for(int j=18;j>=0;j--) if(R+(1<<j)<=RS.size() && st.getval(L,R+(1<<j))>=S[e].size()) R+=1<<j;
			for(int j=18;j>=0;j--) if(L-(1<<j)>=0 && st.getval(L-(1<<j),R)>=S[e].size()) L-=1<<j;
			ret[e]=bt(R)-bt(L-1);
			//cout<<"!"<<e<<" "<<L<<" "<<R<<" "<<ret[e]<<endl;
		}

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			FORR(r,acc[pos]) {
				//cout<<"add"<<r<<" "<<ind[r]<<" "<<sa.rsa[ind[r]]<<endl;
				bt.add(r,1);
			}
			dfs(e.first,pos);
			FORR(r,acc[pos]) bt.add(r,-1);

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	map<string,int> memo;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
		FORR(c,s) c+='a';
		reverse(ALL(s));
		if(memo.count(s)) {
			ind[i]=memo[s];
		}
		else {
			ind[i]=RS.size();
			memo[s]=ind[i];
			RS+=s+"#";
		}
	}
	sa.build(RS);
	FOR(i,RS.size()) {
		st.update(i,sa.lcp[i]);
		//cout<<i<<" "<<RS.substr(sa.sa[i])<<endl;
	}

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;
	/*
	cout<<RS<<endl;
	FOR(i,Q) cout<<i<<" "<<ind[i]<<" "<<sa.rsa[ind[i]]<<endl;
	*/
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
string RS;
int ind[404040];
ll ret[404040];

struct SuffixArray {
	int N; vector<int> rank,lcp,sa,rsa; string S;

	void build(string S){
		this->S=S;
		int i,h=0; vector<int> tmp;
		N=S.size(); rank.resize(N+1); sa.resize(N+1); tmp.resize(N+1);
		FOR(i,N+1) sa[i]=i, rank[i]=i==N?-1:S[i];

		for(int k=1; k<=N; k<<=1) {
			auto pred2 = [k,this](int& a,int &b)->bool{ return (((a+k<=N)?rank[a+k]:-1)<((b+k<=N)?rank[b+k]:-1));};
			auto pred = [pred2,k,this](int& a,int &b)->bool{ return (rank[a]!=rank[b])?(rank[a]<rank[b]):pred2(a,b);};
			int x=0;
			if(k!=1) for(i=1;i<N+1;i++) if(rank[sa[i]]!=rank[sa[x]]) sort(sa.begin()+x,sa.begin()+i,pred2), x=i;
			sort(sa.begin()+x,sa.end(),pred);
			FOR(i,N+1) tmp[sa[i]]=(i==0)?0:tmp[sa[i-1]]+pred(sa[i-1],sa[i]);
			swap(rank,tmp);
		}
		lcp.resize(N+1); rsa.resize(N+1);
		FOR(i,N+1) rsa[sa[i]]=i;
		FOR(i,N) {
			int j=sa[rsa[i]-1];
			for(h=max(h-1,0);i+h<N && j+h<N; h++) if(S[j+h]!=S[i+h]) break;
			lcp[rsa[i]-1]=h;
		}
	}
};
SuffixArray sa;

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

template<class V,int NV> class SegTree_1 {
public:
	vector<V> val;
	static V const def=1<<20;
	V comp(V l,V r){ return min(l,r);};

	SegTree_1(){val=vector<V>(NV*2,0);};
	V getval(int x,int y,int l=0,int r=NV,int k=1) { // x<=i<y
		if(r<=x || y<=l) return def;
		if(x<=l && r<=y) return val[k];
		return comp(getval(x,y,l,(l+r)/2,k*2),getval(x,y,(l+r)/2,r,k*2+1));
	}
	void update(int entry, V v) {
		entry += NV;
		val[entry]=v;
		while(entry>1) entry>>=1, val[entry]=comp(val[entry*2],val[entry*2+1]);
	}
};
SegTree_1<int,1<<20> st;

template<class V, int ME> class BIT {
public:
	V bit[1<<ME];
	V operator()(int e) {if(e<0) return 0;V s=0;e++;while(e) s+=bit[e-1],e-=e&-e; return s;}
	void add(int e,V v) { e++; while(e<=1<<ME) bit[e-1]+=v,e+=e&-e;}
};
BIT<ll,20> bt;

class ACmatch_enum {
public:
	Trie t;
	vector<vector<int> > acc;
	int ma;
	void create(vector<string> S) {
		int i,j;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) {
			int st=ind[i];
			int cur=0;
			FOR(j,S[i].size()) {
				cur=t.V[cur][S[i][j]+1];
				int tar=sa.rsa[ind[i]+S[i].size()-1-j];
				if(acc[cur].empty()) acc[cur].push_back(tar);
			}
		}
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
			}
		}
	}

	void dfs(int cur,int pos) {
		int i;

		FORR(e,ev[cur]) {
			int L=sa.rsa[ind[e]],R=L;
			for(int j=18;j>=0;j--) if(R+(1<<j)<=RS.size() && st.getval(L,R+(1<<j))>=S[e].size()) R+=1<<j;
			for(int j=18;j>=0;j--) if(L-(1<<j)>=0 && st.getval(L-(1<<j),R)>=S[e].size()) L-=1<<j;
			ret[e]=bt(R)-bt(L-1);
		}

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			FORR(r,acc[pos]) bt.add(r,1);
			dfs(e.first,pos);
			FORR(r,acc[pos]) bt.add(r,-1);

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	map<string,int> memo;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
		FORR(c,s) c+='a';
		reverse(ALL(s));
		if(memo.count(s)) {
			ind[i]=memo[s];
		}
		else {
			ind[i]=RS.size();
			memo[s]=ind[i];
			RS+=s+"#";
		}
	}
	sa.build(RS);
	FOR(i,RS.size()) st.update(i,sa.lcp[i]);

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
ll ret[404040];

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

class ACmatch_enum {
public:
	Trie t;
	vector<set<int> > acc;
	vector<int> mp;
	int ma;
	void create(vector<string> S) {
		int i;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) acc[t.find(S[i])].insert(i);
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
				ITR(it,acc[t.V[pre][i+1]]) acc[t.V[k][i+1]].insert(*it);
			}
		}
		mp.resize(S.size());
	}

	void dfs(int cur,int pos) {
		FORR(e,ev[cur]) ret[e]=mp[e];

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			ITR(it2,acc[pos]) mp[*it2]++;
			dfs(e.first,pos);
			ITR(it2,acc[pos]) mp[*it2]--;

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
	}

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;

}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
string RS;
int ind[404040];
ll ret[404040];

struct SuffixArray {
	int N; vector<int> rank,lcp,sa,rsa; string S;

	void build(string S){
		this->S=S;
		int i,h=0; vector<int> tmp;
		N=S.size(); rank.resize(N+1); sa.resize(N+1); tmp.resize(N+1);
		FOR(i,N+1) sa[i]=i, rank[i]=i==N?-1:S[i];

		for(int k=1; k<=N; k<<=1) {
			auto pred2 = [k,this](int& a,int &b)->bool{ return (((a+k<=N)?rank[a+k]:-1)<((b+k<=N)?rank[b+k]:-1));};
			auto pred = [pred2,k,this](int& a,int &b)->bool{ return (rank[a]!=rank[b])?(rank[a]<rank[b]):pred2(a,b);};
			int x=0;
			if(k!=1) for(i=1;i<N+1;i++) if(rank[sa[i]]!=rank[sa[x]]) sort(sa.begin()+x,sa.begin()+i,pred2), x=i;
			sort(sa.begin()+x,sa.end(),pred);
			FOR(i,N+1) tmp[sa[i]]=(i==0)?0:tmp[sa[i-1]]+pred(sa[i-1],sa[i]);
			swap(rank,tmp);
		}
		lcp.resize(N+1); rsa.resize(N+1);
		FOR(i,N+1) rsa[sa[i]]=i;
		FOR(i,N) {
			int j=sa[rsa[i]-1];
			for(h=max(h-1,0);i+h<N && j+h<N; h++) if(S[j+h]!=S[i+h]) break;
			lcp[rsa[i]-1]=h;
		}
	}
};
SuffixArray sa;

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

template<class V,int NV> class SegTree_1 {
public:
	vector<V> val;
	static V const def=1<<20;
	V comp(V l,V r){ return min(l,r);};

	SegTree_1(){val=vector<V>(NV*2,0);};
	V getval(int x,int y,int l=0,int r=NV,int k=1) { // x<=i<y
		if(r<=x || y<=l) return def;
		if(x<=l && r<=y) return val[k];
		return comp(getval(x,y,l,(l+r)/2,k*2),getval(x,y,(l+r)/2,r,k*2+1));
	}
	void update(int entry, V v) {
		entry += NV;
		val[entry]=v;
		while(entry>1) entry>>=1, val[entry]=comp(val[entry*2],val[entry*2+1]);
	}
};
SegTree_1<int,1<<20> st;

template<class V, int ME> class BIT {
public:
	V bit[1<<ME];
	V operator()(int e) {if(e<0) return 0;V s=0;e++;while(e) s+=bit[e-1],e-=e&-e; return s;}
	void add(int e,V v) { e++; while(e<=1<<ME) bit[e-1]+=v,e+=e&-e;}
};
BIT<ll,20> bt;

class ACmatch_enum {
public:
	Trie t;
	vector<vector<int> > acc;
	int ma;
	void create(vector<string> S) {
		int i;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) if(acc[t.find(S[i])].empty()) acc[t.find(S[i])].push_back(i);
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
			}
		}
	}

	void dfs(int cur,int pos) {
		//cout<<cur<<" ";
		int i;
		//FOR(i,RS.size()) cout<<bt(i)-bt(i-1);
		//cout<<endl;

		FORR(e,ev[cur]) {
			int L=sa.rsa[ind[e]],R=L;
			for(int j=18;j>=0;j--) if(R+(1<<j)<=RS.size() && st.getval(L,R+(1<<j))>=S[e].size()) R+=1<<j;
			ret[e]=bt(R)-bt(L-1);
			//cout<<"!"<<e<<" "<<L<<" "<<R<<" "<<ret[e]<<endl;
		}

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			FORR(r,acc[pos]) {
				//cout<<"add"<<r<<" "<<ind[r]<<" "<<sa.rsa[ind[r]]<<endl;
				bt.add(sa.rsa[ind[r]],1);
			}
			dfs(e.first,pos);
			FORR(r,acc[pos]) bt.add(sa.rsa[ind[r]],-1);

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	map<string,int> memo;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
		FORR(c,s) c+='a';
		reverse(ALL(s));
		if(memo.count(s)) {
			ind[i]=memo[s];
		}
		else {
			ind[i]=RS.size();
			memo[s]=ind[i];
			RS+=s+"#";
		}
	}
	sa.build(RS);
	FOR(i,RS.size()) {
		st.update(i,sa.lcp[i]);
		//cout<<i<<" "<<RS.substr(sa.sa[i])<<endl;
	}

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;
	//cout<<RS<<endl;
	//FOR(i,Q) cout<<i<<" "<<ind[i]<<" "<<sa.rsa[ind[i]]<<endl;
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
ll ret[404040];

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

class ACmatch_enum {
public:
	Trie t;
	vector<vector<int> > acc;
	vector<int> mp;
	int ma;
	void create(vector<string> S) {
		int i;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) acc[t.find(S[i])].push_back(i);
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
				ITR(it,acc[t.V[pre][i+1]]) acc[t.V[k][i+1]].push_back(*it);
			}
		}
		mp.resize(S.size());
	}

	void dfs(int cur,int pos) {
		FORR(e,ev[cur]) ret[e]=mp[e];

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			ITR(it2,acc[pos]) mp[*it2]++;
			dfs(e.first,pos);
			ITR(it2,acc[pos]) mp[*it2]--;

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
	}

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;

}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
string RS;
int ind[404040];
ll ret[404040];

struct SuffixArray {
	int N; vector<int> rank,lcp,sa,rsa; string S;

	void build(string S){
		this->S=S;
		int i,h=0; vector<int> tmp;
		N=S.size(); rank.resize(N+1); sa.resize(N+1); tmp.resize(N+1);
		FOR(i,N+1) sa[i]=i, rank[i]=i==N?-1:S[i];

		for(int k=1; k<=N; k<<=1) {
			auto pred2 = [k,this](int& a,int &b)->bool{ return (((a+k<=N)?rank[a+k]:-1)<((b+k<=N)?rank[b+k]:-1));};
			auto pred = [pred2,k,this](int& a,int &b)->bool{ return (rank[a]!=rank[b])?(rank[a]<rank[b]):pred2(a,b);};
			int x=0;
			if(k!=1) for(i=1;i<N+1;i++) if(rank[sa[i]]!=rank[sa[x]]) sort(sa.begin()+x,sa.begin()+i,pred2), x=i;
			sort(sa.begin()+x,sa.end(),pred);
			FOR(i,N+1) tmp[sa[i]]=(i==0)?0:tmp[sa[i-1]]+pred(sa[i-1],sa[i]);
			swap(rank,tmp);
		}
		lcp.resize(N+1); rsa.resize(N+1);
		FOR(i,N+1) rsa[sa[i]]=i;
		FOR(i,N) {
			int j=sa[rsa[i]-1];
			for(h=max(h-1,0);i+h<N && j+h<N; h++) if(S[j+h]!=S[i+h]) break;
			lcp[rsa[i]-1]=h;
		}
	}
};
SuffixArray sa;

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

template<class V,int NV> class SegTree_1 {
public:
	vector<V> val;
	static V const def=1<<20;
	V comp(V l,V r){ return min(l,r);};

	SegTree_1(){val=vector<V>(NV*2,0);};
	V getval(int x,int y,int l=0,int r=NV,int k=1) { // x<=i<y
		if(r<=x || y<=l) return def;
		if(x<=l && r<=y) return val[k];
		return comp(getval(x,y,l,(l+r)/2,k*2),getval(x,y,(l+r)/2,r,k*2+1));
	}
	void update(int entry, V v) {
		entry += NV;
		val[entry]=v;
		while(entry>1) entry>>=1, val[entry]=comp(val[entry*2],val[entry*2+1]);
	}
};
SegTree_1<int,1<<20> st;

template<class V, int ME> class BIT {
public:
	V bit[1<<ME];
	V operator()(int e) {if(e<0) return 0;V s=0;e++;while(e) s+=bit[e-1],e-=e&-e; return s;}
	void add(int e,V v) { e++; while(e<=1<<ME) bit[e-1]+=v,e+=e&-e;}
};
BIT<ll,20> bt;

class ACmatch_enum {
public:
	Trie t;
	vector<vector<int> > acc;
	int ma;
	void create(vector<string> S) {
		int i,j;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) {
			int st=ind[i];
			int cur=0;
			FOR(j,S[i].size()) {
				cur=t.V[cur][S[i][j]+1];
				int tar=sa.rsa[ind[i]+S[i].size()-1-j];
				if(acc[cur].empty()) acc[cur].push_back(tar);
			}
		}
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
			}
		}
	}

	void dfs(int cur,int pos) {
		//cout<<cur<<" ";
		int i;
		//FOR(i,RS.size()) cout<<bt(i)-bt(i-1);
		//cout<<endl;

		FORR(e,ev[cur]) {
			int L=sa.rsa[ind[e]],R=L;
			for(int j=18;j>=0;j--) if(R+(1<<j)<=RS.size() && st.getval(L,R+(1<<j))>=S[e].size()) R+=1<<j;
			ret[e]=bt(R)-bt(L-1);
			//cout<<"!"<<e<<" "<<L<<" "<<R<<" "<<ret[e]<<endl;
		}

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			FORR(r,acc[pos]) {
				//cout<<"add"<<r<<" "<<ind[r]<<" "<<sa.rsa[ind[r]]<<endl;
				bt.add(r,1);
			}
			dfs(e.first,pos);
			FORR(r,acc[pos]) bt.add(r,-1);

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	map<string,int> memo;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
		FORR(c,s) c+='a';
		reverse(ALL(s));
		if(memo.count(s)) {
			ind[i]=memo[s];
		}
		else {
			ind[i]=RS.size();
			memo[s]=ind[i];
			RS+=s+"#";
		}
	}
	sa.build(RS);
	FOR(i,RS.size()) {
		st.update(i,sa.lcp[i]);
		//cout<<i<<" "<<RS.substr(sa.sa[i])<<endl;
	}

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;
	/*
	cout<<RS<<endl;
	FOR(i,Q) cout<<i<<" "<<ind[i]<<" "<<sa.rsa[ind[i]]<<endl;
	*/
}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef signed long long ll;

#undef _P
#define _P(...) (void)printf(__VA_ARGS__)
#define FOR(x,to) for(x=0;x<(to);x++)
#define FORR(x,arr) for(auto& x:arr)
#define ITR(x,c) for(__typeof(c.begin()) x=c.begin();x!=c.end();x++)
#define ALL(a) (a.begin()),(a.end())
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
//-------------------------------------------------------

int N;
vector<pair<int,char>> E[402020];

int Q;
vector<int> ev[404040];
vector<string> S;
ll ret[404040];

const int NUMC=26;
class Trie {
public:
	vector<vector<int> > V;
	int find(string s) {
		int cur=0;
		ITR(it,s) if((cur=V[cur][*it+1])==0) return -1;
		return cur;
	}
	void create(vector<string> S) { // 0 is for backtrack
		V.clear();
		V.push_back(vector<int>(NUMC+1));
		sort(S.begin(),S.end());
		ITR(it,S) {
			int cur=0;
			ITR(c,(*it)) {
				if(V[cur][*c+1]==0) V.push_back(vector<int>(NUMC+1)),V[cur][*c+1]=V.size()-1;
				cur=V[cur][*c+1];
			}
		}
	}
};

class ACmatch_enum {
public:
	Trie t;
	vector<vector<int> > acc;
	vector<int> mp;
	int ma;
	void create(vector<string> S) {
		int i;
		ma=S.size();
		t.create(S);
		acc.clear();
		acc.resize(t.V.size());
		FOR(i,S.size()) acc[t.find(S[i])].push_back(i);
		queue<int> Q;
		FOR(i,NUMC) if(t.V[0][i+1]) t.V[t.V[0][i+1]][0]=0, Q.push(t.V[0][i+1]);

		while(!Q.empty()) {
			int k=Q.front(); Q.pop();
			FOR(i,NUMC) if(t.V[k][i+1]) {
				Q.push(t.V[k][i+1]);
				int pre=t.V[k][0];
				while(pre && t.V[pre][i+1]==0) pre=t.V[pre][0];
				t.V[t.V[k][i+1]][0]=t.V[pre][i+1];
				vector<int> NV;
				int a=0,b=0,x=t.V[pre][i+1],y=t.V[k][i+1];
				while(a<acc[x].size() || b<acc[y].size()) {
					if(b==acc[y].size()) NV.push_back(acc[x][a++]);
					else if(a==acc[x].size()) NV.push_back(acc[y][b++]);
					else if(acc[x][a]==acc[y][b]) NV.push_back(acc[x][a++]), b++;
					else if(acc[x][a]<acc[y][b]) NV.push_back(acc[x][a++]);
					else NV.push_back(acc[y][b++]);
				}
				swap(NV,acc[t.V[k][i+1]]);
			}
		}
		mp.resize(S.size());
	}

	void dfs(int cur,int pos) {
		FORR(e,ev[cur]) ret[e]=mp[e];

		FORR(e,E[cur]) {
			int prev=pos;
			while(pos && t.V[pos][e.second+1]==0) pos=t.V[pos][0];
			pos=t.V[pos][e.second+1];
			FORR(r,acc[pos]) mp[r]++;
			dfs(e.first,pos);
			FORR(r,acc[pos]) mp[r]--;

			pos=prev;

		}
	}
};
ACmatch_enum ac;

void solve() {
	int i,j,k,l,r,x,y; string s;

	cin>>N;
	FOR(i,N) {
		cin>>j;
		x=0;
		if(j==2) cin>>x;
		cin>>s;
		E[x].push_back({i+1,s[0]-'a'});
	}
	cin>>Q;
	FOR(i,Q) {
		cin>>x>>s;
		ev[x].push_back(i);
		FORR(c,s) c-='a';
		S.push_back(s);
	}

	ac.create(S);
	ac.dfs(0,0);

	FOR(i,Q) cout<<ret[i]<<endl;

}

int main(int argc,char** argv){
	string s;int i;
	if(argc==1) ios::sync_with_stdio(false), cin.tie(0);
	FOR(i,argc-1) s+=argv[i+1],s+='\n'; FOR(i,s.size()) ungetc(s[s.size()-1-i],stdin);
	cout.tie(0); solve(); return 0;
}


#include<bits/stdc++.h>
#define o 1000005
#define re register int
#define ll long long
#define g0(a) memset(a,0,sizeof(a))
#define gc(a,b) memcpy(a,b,sizeof(a))
#define FOR(i,a,b) for(int i=a;i<=b;i++)
#define REP(i,a,b) for(int i=a;i>=b;i--)
#define pa pair<int,int>
#define mpp make_pair
#define s1 first
#define s2 second
using namespace std;
inline int read()
{
	register int data=0,w=1;
	char ch=0;
	while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
	if(ch=='-')w=-1,ch=getchar();
	while(ch>='0'&&ch<='9')data=(data<<1)+(data<<3)+(ch^48),ch=getchar();
	return data*w;
}
int c[o][28],cnt=1,pos[o],len[o];
string s[400005];
int n,m,sum[o];
vector<int> v[400005];
int fail[o],q[o];
void build_()
{
	int l=0,r=0;
	fail[1]=1;
	FOR(i,0,25)if(c[1][i])q[++r]=c[1][i],fail[c[1][i]]=1;
	else c[1][i]=1;
	while(l<r){
		int x=q[++l];
		FOR(i,0,25)if(c[x][i])q[++r]=c[x][i],fail[c[x][i]]=c[fail[x]][i];
		else c[x][i]=c[fail[x]][i];
	}
}
vector<int> e[400005],t[400005];
int st[o],ed[o];
void dfs(int x){
	st[x]=++st[0];
	for(auto y:e[x])dfs(y);
	ed[x]=st[0];
}
int b[o];
void add(int x,int v){for(int i=x;i<=st[0];i+=i&-i)b[i]+=v;}
int ask(int x){int ans=0;for(int i=x;i;i-=i&-i)ans+=b[i];return ans;}
int ans[o];
char ch[o];
void dfs(int x,int p)
{
//	cout<<"k="<<x<<'\n';
	if(p)add(st[p],1);
	for(auto k:v[x])ans[k]=ask(ed[pos[k]])-ask(st[pos[k]]-1);
	for(auto y:t[x])
		dfs(y,c[p][ch[y]-'a']);
	if(p)add(st[p],-1);
}
int main()
{
	n=read();
	FOR(i,1,n){
		int op=read(),fa=0;
		if(op==2)fa=read();
		t[fa].push_back(i);
		scanf("%s",ch+i);
	}
	m=read();
	FOR(i,1,m)
	{
		int x=read();cin>>s[0];
		int root=1;
		FOR(j,0,(int)s[0].length()-1){int to=s[0][j]-'a';if(!c[root][to])c[root][to]=++cnt;root=c[root][to];}
		pos[i]=root;
		v[x].push_back(i);
	}
	build_();
	FOR(i,2,cnt)e[fail[i]].push_back(i);
	dfs(1);dfs(0,1);
	FOR(i,1,m)cout<<ans[i]<<'\n';
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int N=4e5+10,M=8e5+10;
int tot,cnt=1,stp;
vector<char>s[N],tmp;
vector< pair<int,int> >ask[M];
int ed[M],que[M],fir[M],dfn[M][2],rt[M],ans[N];
struct edge
{
	int to;
	int nxt;
}e[M];
inline void add(int x,int y)
{
	e[++tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot;
}
struct ACauto
{
	int son1[27];
	int son2[27];
	int fail;
}t[M];
inline void insert(vector<char>S,int id)
{
	int p=1,len=S.size();
	for(int i=0;i<len;i++)
	{
		int ch=S[i]-'a';
		if(!t[p].son1[ch]) t[p].son1[ch]=++cnt;
		p=t[p].son1[ch];
	}
	ed[id]=p;
}
inline void getfail()
{
	for(int i=0;i<26;i++)
		t[0].son2[i]=1;
	que[1]=1,t[1].fail=0;
	int head=1,tail=1;
	while(head<=tail)
	{
		int p=que[head++];
		for(int i=0;i<26;i++)
		{
			int q=t[p].son2[i],nxt=t[p].fail;
			if(!q){ t[p].son2[i]=t[nxt].son2[i]; continue; }
			t[q].fail=t[nxt].son2[i];
			que[++tail]=q;
		}
	}
}
inline int lowbit(int x)
{
	return x&(-x);
}
inline void change(int x,int c)
{
	for(int i=x;i<=cnt+1;i+=lowbit(i))
		rt[i]+=c;
}
inline int query(int x)
{
	int res=0;
	for(int i=x;i>=1;i-=lowbit(i))
		res+=rt[i];
	return res;
}
inline void dfs1(int p)
{
	dfn[p][0]=++stp;
	for(int i=fir[p];i;i=e[i].nxt)
		dfs1(e[i].to);
	dfn[p][1]=stp;
}
inline void dfs2(int p)
{
	change(dfn[p][0],1);
	for(int i=0;i<ask[p].size();i++)
	{
		int x=ask[p][i].first;
		ans[ask[p][i].second]=query(dfn[x][1])-query(dfn[x][0]-1);
	}
	for(int i=0;i<26;i++)
		if(t[p].son1[i]) dfs2(t[p].son1[i]);
	change(dfn[p][0],-1);
}
int main()
{
	int T,n=0,m,opt,pos; char ch[N];
	scanf("%d",&T);
	for(int i=1;i<=T;i++)
	{
		scanf("%d",&opt);
		if(opt==1) n++;
		else
		{
			scanf("%d",&pos);
			s[++n]=s[pos];
		}
		scanf("%s",ch);
		s[n].push_back(ch[0]);
	}
	for(int i=1;i<=n;i++)
		insert(s[i],i);
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%s",&pos,ch);
		tmp.clear();
		for(int j=0;j<strlen(ch);j++)
			tmp.push_back(ch[j]);
		insert(tmp,n+i);
		ask[ed[pos]].push_back(make_pair(ed[n+i],i));
	}
	for(int i=1;i<=cnt;i++)
		for(int j=0;j<26;j++)
			t[i].son2[j]=t[i].son1[j];
	getfail();
	for(int i=1;i<=cnt;i++)
		add(t[i].fail,i);
	dfs1(0),dfs2(1);
	for(int i=1;i<=m;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include <iostream>
#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
using namespace std;
const int N=4e5+10,M=8e5+10;
int tot,cnt=1,stp;
vector< pair<int,int> >ask[M];
int ed[M],que[M],fir[M],dfn[M][2],rt[M],ans[N];
struct edge
{
	int to;
	int nxt;
}e[M];
inline void add(int x,int y)
{
	e[++tot].to=y; e[tot].nxt=fir[x]; fir[x]=tot;
}
struct ACauto
{
	int son1[27];
	int son2[27];
	int fail;
}t[M];
inline void insert(char *s,int id)
{
	int p=1,len=strlen(s);
	for(int i=0;i<len;i++)
	{
		int ch=s[i]-'a';
		if(!t[p].son1[ch]) t[p].son1[ch]=++cnt;
		p=t[p].son1[ch];
	}
	ed[id]=p;
}
inline void getfail()
{
	for(int i=0;i<26;i++)
		t[0].son2[i]=1;
	que[1]=1,t[1].fail=0;
	int head=1,tail=1;
	while(head<=tail)
	{
		int p=que[head++];
		for(int i=0;i<26;i++)
		{
			int q=t[p].son2[i],nxt=t[p].fail;
			if(!q){ t[p].son2[i]=t[nxt].son2[i]; continue; }
			t[q].fail=t[nxt].son2[i];
			que[++tail]=q;
		}
	}
}
inline int lowbit(int x)
{
	return x&(-x);
}
inline void change(int x,int c)
{
	for(int i=x;i<=cnt+1;i+=lowbit(i))
		rt[i]+=c;
}
inline int query(int x)
{
	int res=0;
	for(int i=x;i>=1;i-=lowbit(i))
		res+=rt[i];
	return res;
}
inline void dfs1(int p)
{
	dfn[p][0]=++stp;
	for(int i=fir[p];i;i=e[i].nxt)
		dfs1(e[i].to);
	dfn[p][1]=stp;
}
inline void dfs2(int p)
{
	change(dfn[p][0],1);
	for(int i=0;i<ask[p].size();i++)
	{
		int x=ask[p][i].first;
		ans[ask[p][i].second]=query(dfn[x][1])-query(dfn[x][0]-1);
	}
	for(int i=0;i<26;i++)
		if(t[p].son1[i]) dfs2(t[p].son1[i]);
	change(dfn[p][0],-1);
}
int main()
{
	int T,n=0,m,opt,pos; char ch[N];
	scanf("%d",&T);
	for(int i=1;i<=T;i++)
	{
		scanf("%d",&opt);
		if(opt==1) pos=++n;
		else scanf("%d",&pos);
		pos=(ed[pos]?ed[pos]:1);
		scanf("%s",ch);
		if(!t[pos].son1[ch[0]-'a']) t[pos].son1[ch[0]-'a']=++cnt;
		ed[i]=t[pos].son1[ch[0]-'a'];
	}
	scanf("%d",&m);
	for(int i=1;i<=m;i++)
	{
		scanf("%d%s",&pos,ch);
		insert(ch,T+i);
		ask[ed[pos]].push_back(make_pair(ed[T+i],i));
	}
	for(int i=1;i<=cnt;i++)
		for(int j=0;j<26;j++)
			t[i].son2[j]=t[i].son1[j];
	getfail();
	for(int i=1;i<=cnt;i++)
		add(t[i].fail,i);
	dfs1(0),dfs2(1);
	for(int i=1;i<=m;i++)
		printf("%d\n",ans[i]);
	return 0;
}