var g1,g2,g3,next,last,en,tail:array[1..100000] of longint;
e,q,fa,ps,pt,fail,ans:array[1..100000] of longint;
trie:array[1..100000,1..26] of longint;
c:array[1..200000] of longint;
s:array[1..100000] of char;
tot,size,len,len1,len2,l,r,n:longint;
//============================================================================
procedure ins(x,y:longint);
begin
inc(len1); g1[len1]:=y;
next[len1]:=en[x]; en[x]:=len1;
end;
//============================================================================
procedure insert(x,y,z:longint); //本来打算对询问排序一下一起搞的。。看到网上建图的奇葩做法顿觉我弱爆了。。。
begin
inc(len2); g2[len2]:=y; g3[len2]:=z;
last[len2]:=tail[x]; tail[x]:=len2;
end;
//============================================================================
procedure add(x,y:longint); //树状数组的修改操作。(添加和取消标号一起搞,加上±1)
begin
while x<=size do
begin
inc(c[x],y);
inc(x,x and -x);
end;
end;
//============================================================================
function sum(x:longint):longint; //树状数组的求和操作。
begin sum:=0;
while x>0 do
begin
inc(sum,c[x]);
dec(x,x and -x);
end;
end;
//============================================================================
procedure init;
var now,tmp:longint;
ch:char;
begin
read(ch); tot:=1; now:=1; n:=0;
while ch in ['B','P','a'..'z'] do
begin
inc(len); s[len]:=ch;
if ch='B' then now:=fa[now] else
if ch='P' then
begin
inc(n); e[n]:=now;
end else
begin
tmp:=ord(ch)-ord('a')+1;
if trie[now,tmp]<>0 then now:=trie[now,tmp] else //建立trie树。
begin
inc(tot); trie[now,tmp]:=tot;
fa[tot]:=now; now:=tot;
end;
end; read(ch);
end;
end;
//============================================================================
procedure get_fail; //生成失败指针。顺便反向建树。
var g,h,i,j,now:longint;
tmp:char;
begin
l:=1; r:=0; fail[1]:=0;
for i:=1 to 26 do //后来写的一个AC自动机引入一个-1点貌似在求失败指针的时候更简洁。
begin
if trie[1,i]<>0 then
begin
inc(r); q[r]:=trie[1,i];
fail[q[r]]:=1; ins(1,q[r]); //建树。
end;
end;
while l<=r do
begin g:=r;
for h:=l to g do
begin now:=q[h];
for i:=1 to 26 do
begin
if trie[now,i]<>0 then
begin
inc(r); q[r]:=trie[now,i]; j:=fail[now];
while j<>0 do
if trie[j,i]<>0 then
begin
fail[q[r]]:=trie[j,i];
ins(trie[j,i],q[r]); break; //建树。
end else j:=fail[j];
if j=0 then
begin
fail[q[r]]:=1;
ins(1,q[r]);
end;
end;
end;
end; l:=g+1;
end;
end;
//============================================================================
procedure dfs(x:longint); //求dfs序。
var i:longint;
begin
inc(size); ps[x]:=size; i:=en[x];
while i<>0 do
begin
dfs(g1[i]); i:=next[i];
end;
inc(size); pt[x]:=size; //弹出的时候我也加入了。可以不用的貌似。
end;
//============================================================================
procedure main;
var x,y,i,j,m,now,tmp:longint;
begin
readln(m);
for i:=1 to m do
begin
readln(x,y);
insert(y,x,i); //这样就把询问分类了。OTZ...
end;
now:=1; tmp:=1;
for i:=1 to len do
begin
if s[i]='P' then
begin j:=tail[tmp];
while j>0 do
begin
ans[g3[j]]:=sum(pt[e[g2[j]]])-sum(ps[e[g2[j]]]-1);
j:=last[j];
end; inc(tmp);
end else
if s[i]='B' then
begin
add(ps[now],-1); //标记的时候只要标记在dfs序中先出现的点。(其实都一样,只要标任一个)
now:=fa[now];
end else
begin
now:=trie[now,ord(s[i])-ord('a')+1];
add(ps[now],1);
end;
end;
for i:=1 to m do writeln(ans[i]);
end;
//============================================================================
begin
assign(input,'type.in');
assign(output,'type.out');
reset(input); rewrite(output);
init;
get_fail;
dfs(1);
main;
close(input); close(output);
end.