#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define MAX ((ll)(1e18))
#define pi (2.0*acos(0))
#define M ((int)(998244353))
#define NN ((int)(1e5 + 5))
#define N ((int)(2*8e5 + 5))
#define eps ((double)(1e-12))
#define logn 20

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

typedef tree < ll,  null_type,  less < ll >,  rb_tree_tag,  tree_order_statistics_node_update > o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

char s[N];

int arr[N], ans[N], tr[N], to[N], from[N], Time;

vector < pair < int , int > > qr[N];

///trie
int node[27][N];
vector < int > mark[N], v[N]; /// mark = to mark endpoint
void init(int n){ /// creating new node
    for(int i = 0; i<26; i++) node[i][n] = -1;
    mark[n].clear();
}
int Insert(char s[], int tot, int cur, int j){  /// inserting a string
    for(int i = 0; s[i]!='\0'; i++){
        if(node[s[i]-'a'][cur]==-1){
            init(tot);
            node[s[i]-'a'][cur] = tot++;
        }
        cur = node[s[i]-'a'][cur];
    }

    mark[cur].push_back(j);
    arr[j] = cur;

    return tot;
}
void visit_trie(int n, char c){ /// utility function to check the trie
    printf("%d %c start\n",n,c);
    //for(int a:mark[n]) cout<<a<<" ";
    //cout<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit_trie(node[i][n],'a'+i);
    }
    printf("%d %c end\n",n,c);
}
///aho_corasick...build trie first
int sfx_link[N];
void aho_corasick(){
    sfx_link[0] = -1;
    queue < int > q;
    q.push(0);
    while(!q.empty()){
        int a = q.front();
        q.pop();
        for(int i = 0; i<26; i++){
            if(node[i][a]==-1) continue;
            q.push(node[i][a]);
            int cur = sfx_link[a];
            while(cur!=-1 && node[i][cur]==-1) cur = sfx_link[cur];
            if(cur==-1) cur = 0;
            else cur = node[i][cur];
            sfx_link[node[i][a]] = cur;
            v[cur].push_back(node[i][a]);
        }
    }
}

void update(int n , int b , int e , int i, int v)
{
    if(i<b || i>e) return;
    if(b==e){
        tr[n] += v;
        return;
    }

    int l = n<<1, m = (b+e)>>1;
    update(l,b,m,i,v);
    update(l+1,m+1,e,i,v);
    tr[n] = tr[l]+tr[l+1];
}

int get(int n , int b  , int e , int i , int j)
{
    if(e<i || j<b) return 0;
    if(i<=b && j>=e) return tr[n];
    int l = n<<1, m = (b+e)>>1;
    return get(l,b,m,i,j)+get(l+1,m+1,e,i,j);
}

void visit(int n)
{
    //cout<<n<<" :::\n";
    update(1,1,Time,from[n],1);
    for(int a:mark[n]){
        //cout<<a<<" :\n";
        for(auto p:qr[a]){
            int b = arr[p.second];
            //cout<<p.first<<" "<<p.second<<" "<<b<<"\n";
            ans[p.first] = get(1,1,Time,from[b],to[b]);
        }
    }
    //cout<<"::: "<<n<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit(node[i][n]);
    }
    update(1,1,Time,from[n],-1);
}

void dfs(int n)
{
    ////cout<<n<<" ::::\n";
    from[n] = Time++;
    for(int a:v[n]){
        dfs(a);
    }
    to[n] = Time-1;
    ////cout<<":::: "<<n<<endl;
}

int main()
{
    int n;
    scanf("%d",&n);
    int tot = 1;
    init(0);
    for(int i = 1; i<=n; i++){
        int t;
        scanf("%d",&t);
        if(t==1){
            scanf("%s",s);
            tot = Insert(s,tot,0,i);
        }
        else{
            int j;
            scanf("%d %s",&j,s);
            tot = Insert(s,tot,arr[j],i);
        }
    }
    int m;
    scanf("%d",&m);
    for(int i = 1; i<=m; i++){
        int j;
        scanf("%d %s",&j,s);
        tot = Insert(s,tot,0,n+i);
        qr[j].push_back(make_pair(i,n+i));
    }
//    //cout<<"bug:\n";
//    for(int i = 1; i<=n+m; i++){
//        //cout<<i<<" "<<arr[i]<<endl;
//    }
//    //cout<<endl;

    aho_corasick();
//    //cout<<"trie ::::::::\n";
//    visit_trie(0,'\0');
//    //cout<<":::::::: trie\n";
    Time = 1;
//    //cout<<"dfs ::::::::\n";
    dfs(0);
//    //cout<<":::::::: dfs\n";
    Time--;
    visit(0);
    for(int i = 1; i<=m; i++) printf("%d\n",ans[i]);
    return 0;
}

//7
//1 a
//2 1 c
//2 1 b
//1 b
//2 1 b
//2 4 a
//2 6 c
//10
//1 d
//7 d
//2 bac
//6 bac
//7 bac
//2 ac
//7 ac
//4 ba
//5 ba
//6 ba


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define MAX ((ll)(1e18))
#define pi (2.0*acos(0))
#define M ((int)(998244353))
#define NN ((int)(1e5 + 5))
#define N ((int)(2*8e5 + 5))
#define eps ((double)(1e-12))
#define logn 20

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

typedef tree < ll,  null_type,  less < ll >,  rb_tree_tag,  tree_order_statistics_node_update > o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

char s[N];

int arr[N], ans[N], tr[N], to[N], from[N], Time;

vector < pair < int , int > > qr[N];

///trie
int node[27][N];
vector < int > mark[N], v[N]; /// mark = to mark endpoint
void init(int n){ /// creating new node
    for(int i = 0; i<26; i++) node[i][n] = -1;
    mark[n].clear();
}
int Insert(char s[], int tot, int cur, int j){  /// inserting a string
    for(int i = 0; s[i]!='\0'; i++){
        if(node[s[i]-'a'][cur]==-1){
            init(tot);
            node[s[i]-'a'][cur] = tot++;
            if(tot>=N) exit(-1);
        }
        cur = node[s[i]-'a'][cur];
    }

    mark[cur].push_back(j);
    arr[j] = cur;

    return tot;
}
void visit_trie(int n, char c){ /// utility function to check the trie
    printf("%d %c start\n",n,c);
    //for(int a:mark[n]) cout<<a<<" ";
    //cout<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit_trie(node[i][n],'a'+i);
    }
    printf("%d %c end\n",n,c);
}
///aho_corasick...build trie first
int sfx_link[N];
void aho_corasick(){
    sfx_link[0] = -1;
    queue < int > q;
    q.push(0);
    while(!q.empty()){
        int a = q.front();
        q.pop();
        for(int i = 0; i<26; i++){
            if(node[i][a]==-1) continue;
            q.push(node[i][a]);
            int cur = sfx_link[a];
            while(cur!=-1 && node[i][cur]==-1) cur = sfx_link[cur];
            if(cur==-1) cur = 0;
            else cur = node[i][cur];
            sfx_link[node[i][a]] = cur;
            v[cur].push_back(node[i][a]);
        }
    }
}

void update(int n , int b , int e , int i, int v)
{
    if(i<b || i>e) return;
    if(b==e){
        tr[n] += v;
        return;
    }

    int l = n<<1, m = (b+e)>>1;
    update(l,b,m,i,v);
    update(l+1,m+1,e,i,v);
    tr[n] = tr[l]+tr[l+1];
}

int get(int n , int b  , int e , int i , int j)
{
    if(e<i || j<b) return 0;
    if(i<=b && j>=e) return tr[n];
    int l = n<<1, m = (b+e)>>1;
    return get(l,b,m,i,j)+get(l+1,m+1,e,i,j);
}

void visit(int n)
{
    //cout<<n<<" :::\n";
    update(1,1,Time,from[n],1);
    for(int a:mark[n]){
        //cout<<a<<" :\n";
        for(auto p:qr[a]){
            int b = arr[p.second];
            //cout<<p.first<<" "<<p.second<<" "<<b<<"\n";
            ans[p.first] = get(1,1,Time,from[b],to[b]);
        }
    }
    //cout<<"::: "<<n<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit(node[i][n]);
    }
    update(1,1,Time,from[n],-1);
}

void dfs(int n)
{
    ////cout<<n<<" ::::\n";
    from[n] = Time++;
    for(int a:v[n]){
        dfs(a);
    }
    to[n] = Time-1;
    ////cout<<":::: "<<n<<endl;
}

int main()
{
    int n;
    scanf("%d",&n);
    int tot = 1;
    init(0);
    for(int i = 1; i<=n; i++){
        int t;
        scanf("%d",&t);
        if(t==1){
            scanf("%s",s);
            tot = Insert(s,tot,0,i);
        }
        else{
            int j;
            scanf("%d %s",&j,s);
            tot = Insert(s,tot,arr[j],i);
        }
    }
    int m;
    scanf("%d",&m);
    for(int i = 1; i<=m; i++){
        int j;
        scanf("%d %s",&j,s);
        tot = Insert(s,tot,0,n+i);
        qr[j].push_back(make_pair(i,n+i));
    }
//    //cout<<"bug:\n";
//    for(int i = 1; i<=n+m; i++){
//        //cout<<i<<" "<<arr[i]<<endl;
//    }
//    //cout<<endl;

    aho_corasick();
//    //cout<<"trie ::::::::\n";
//    visit_trie(0,'\0');
//    //cout<<":::::::: trie\n";
    Time = 1;
//    //cout<<"dfs ::::::::\n";
    dfs(0);
//    //cout<<":::::::: dfs\n";
    Time--;
    visit(0);
    for(int i = 1; i<=m; i++) printf("%d\n",ans[i]);
    return 0;
}

//7
//1 a
//2 1 c
//2 1 b
//1 b
//2 1 b
//2 4 a
//2 6 c
//10
//1 d
//7 d
//2 bac
//6 bac
//7 bac
//2 ac
//7 ac
//4 ba
//5 ba
//6 ba


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define MAX ((ll)(1e18))
#define pi (2.0*acos(0))
#define M ((int)(998244353))
#define NN ((int)(1e5 + 5))
#define N ((int)(8e5 + 5))
#define eps ((double)(1e-12))
#define logn 20

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

typedef tree < ll,  null_type,  less < ll >,  rb_tree_tag,  tree_order_statistics_node_update > o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

char s[N];

int arr[N], ans[N], tr[N], to[N], from[N], Time;

vector < pair < int , int > > qr[N];

///trie
int node[27][N];
vector < int > mark[N], v[N]; /// mark = to mark endpoint
void init(int n){ /// creating new node
    for(int i = 0; i<26; i++) node[i][n] = -1;
    mark[n].clear();
}
int Insert(char s[], int tot, int cur, int j){  /// inserting a string
    for(int i = 0; s[i]!='\0'; i++){
        if(node[s[i]-'a'][cur]==-1){
            init(tot);
            node[s[i]-'a'][cur] = tot++;
        }
        cur = node[s[i]-'a'][cur];
    }

    mark[cur].push_back(j);
    arr[j] = cur;

    return tot;
}
void visit_trie(int n, char c){ /// utility function to check the trie
    printf("%d %c start\n",n,c);
    //for(int a:mark[n]) cout<<a<<" ";
    //cout<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit_trie(node[i][n],'a'+i);
    }
    printf("%d %c end\n",n,c);
}
///aho_corasick...build trie first
int sfx_link[N];
void aho_corasick(){
    sfx_link[0] = -1;
    queue < int > q;
    q.push(0);
    while(!q.empty()){
        int a = q.front();
        q.pop();
        for(int i = 0; i<26; i++){
            if(node[i][a]==-1) continue;
            q.push(node[i][a]);
            int cur = sfx_link[a];
            while(cur!=-1 && node[i][cur]==-1) cur = sfx_link[cur];
            if(cur==-1) cur = 0;
            else cur = node[i][cur];
            sfx_link[node[i][a]] = cur;
            v[cur].push_back(node[i][a]);
        }
    }
}

void update(int n , int b , int e , int i, int v)
{
    if(i<b || i>e) return;
    if(b==e){
        tr[n] += v;
        return;
    }

    int l = n<<1, m = (b+e)>>1;
    update(l,b,m,i,v);
    update(l+1,m+1,e,i,v);
    tr[n] = tr[l]+tr[l+1];
}

int get(int n , int b  , int e , int i , int j)
{
    if(e<i || j<b) return 0;
    if(i<=b && j>=e) return tr[n];
    int l = n<<1, m = (b+e)>>1;
    return get(l,b,m,i,j)+get(l+1,m+1,e,i,j);
}

void visit(int n)
{
    //cout<<n<<" :::\n";
    update(1,1,Time,from[n],1);
    for(int a:mark[n]){
        //cout<<a<<" :\n";
        for(auto p:qr[a]){
            int b = arr[p.second];
            //cout<<p.first<<" "<<p.second<<" "<<b<<"\n";
            ans[p.first] = get(1,1,Time,from[b],to[b]);
        }
    }
    //cout<<"::: "<<n<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit(node[i][n]);
    }
    update(1,1,Time,from[n],-1);
}

void dfs(int n)
{
    ////cout<<n<<" ::::\n";
    from[n] = Time++;
    for(int a:v[n]){
        dfs(a);
    }
    to[n] = Time-1;
    ////cout<<":::: "<<n<<endl;
}

int main()
{
    int n;
    scanf("%d",&n);
    int tot = 1;
    init(0);
    for(int i = 1; i<=n; i++){
        int t;
        scanf("%d",&t);
        if(t==1){
            scanf("%s",s);
            tot = Insert(s,tot,0,i);
        }
        else{
            int j;
            scanf("%d %s",&j,s);
            tot = Insert(s,tot,arr[j],i);
        }
    }
    int m;
    scanf("%d",&m);
    for(int i = 1; i<=m; i++){
        int j;
        scanf("%d %s",&j,s);
        tot = Insert(s,tot,0,n+i);
        qr[j].push_back(make_pair(i,n+i));
    }
//    //cout<<"bug:\n";
//    for(int i = 1; i<=n+m; i++){
//        //cout<<i<<" "<<arr[i]<<endl;
//    }
//    //cout<<endl;

    aho_corasick();
//    //cout<<"trie ::::::::\n";
//    visit_trie(0,'\0');
//    //cout<<":::::::: trie\n";
    Time = 1;
//    //cout<<"dfs ::::::::\n";
    dfs(0);
//    //cout<<":::::::: dfs\n";
    Time--;
    visit(0);
    for(int i = 1; i<=m; i++) printf("%d\n",ans[i]);
    return 0;
}

//7
//1 a
//2 1 c
//2 1 b
//1 b
//2 1 b
//2 4 a
//2 6 c
//10
//1 d
//7 d
//2 bac
//6 bac
//7 bac
//2 ac
//7 ac
//4 ba
//5 ba
//6 ba


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define MAX ((ll)(1e18))
#define pi (2.0*acos(0))
#define M ((int)(998244353))
#define NN ((int)(1e5 + 5))
#define N ((int)(4*8e5 + 5))
#define eps ((double)(1e-12))
#define logn 20

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

typedef tree < ll,  null_type,  less < ll >,  rb_tree_tag,  tree_order_statistics_node_update > o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

char s[N];

int arr[N], ans[N], tr[N], to[N], from[N], Time;

vector < pair < int , int > > qr[N];

///trie
int node[27][N];
vector < int > mark[N], v[N]; /// mark = to mark endpoint
void init(int n){ /// creating new node
    for(int i = 0; i<26; i++) node[i][n] = -1;
    mark[n].clear();
}
int Insert(char s[], int tot, int cur, int j){  /// inserting a string
    for(int i = 0; s[i]!='\0'; i++){
        if(node[s[i]-'a'][cur]==-1){
            init(tot);
            node[s[i]-'a'][cur] = tot++;
        }
        cur = node[s[i]-'a'][cur];
    }

    mark[cur].push_back(j);
    arr[j] = cur;

    return tot;
}
void visit_trie(int n, char c){ /// utility function to check the trie
    printf("%d %c start\n",n,c);
    //for(int a:mark[n]) cout<<a<<" ";
    //cout<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit_trie(node[i][n],'a'+i);
    }
    printf("%d %c end\n",n,c);
}
///aho_corasick...build trie first
int sfx_link[N];
void aho_corasick(){
    sfx_link[0] = -1;
    queue < int > q;
    q.push(0);
    while(!q.empty()){
        int a = q.front();
        q.pop();
        for(int i = 0; i<26; i++){
            if(node[i][a]==-1) continue;
            q.push(node[i][a]);
            int cur = sfx_link[a];
            while(cur!=-1 && node[i][cur]==-1) cur = sfx_link[cur];
            if(cur==-1) cur = 0;
            else cur = node[i][cur];
            sfx_link[node[i][a]] = cur;
            v[cur].push_back(node[i][a]);
        }
    }
}

void update(int n , int b , int e , int i, int v)
{
    if(i<b || i>e) return;
    if(b==e){
        tr[n] += v;
        return;
    }

    int l = n<<1, m = (b+e)>>1;
    update(l,b,m,i,v);
    update(l+1,m+1,e,i,v);
    tr[n] = tr[l]+tr[l+1];
}

int get(int n , int b  , int e , int i , int j)
{
    if(e<i || j<b) return 0;
    if(i<=b && j>=e) return tr[n];
    int l = n<<1, m = (b+e)>>1;
    return get(l,b,m,i,j)+get(l+1,m+1,e,i,j);
}

void visit(int n)
{
    //cout<<n<<" :::\n";
    update(1,1,Time,from[n],1);
    for(int a:mark[n]){
        //cout<<a<<" :\n";
        for(auto p:qr[a]){
            int b = arr[p.second];
            //cout<<p.first<<" "<<p.second<<" "<<b<<"\n";
            ans[p.first] = get(1,1,Time,from[b],to[b]);
        }
    }
    //cout<<"::: "<<n<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit(node[i][n]);
    }
    update(1,1,Time,from[n],-1);
}

void dfs(int n)
{
    ////cout<<n<<" ::::\n";
    from[n] = Time++;
    for(int a:v[n]){
        dfs(a);
    }
    to[n] = Time-1;
    ////cout<<":::: "<<n<<endl;
}

int main()
{
    int n;
    scanf("%d",&n);
    int tot = 1;
    init(0);
    for(int i = 1; i<=n; i++){
        int t;
        scanf("%d",&t);
        if(t==1){
            scanf("%s",s);
            tot = Insert(s,tot,0,i);
        }
        else{
            int j;
            scanf("%d %s",&j,s);
            tot = Insert(s,tot,arr[j],i);
        }
    }
    int m;
    scanf("%d",&m);
    for(int i = 1; i<=m; i++){
        int j;
        scanf("%d %s",&j,s);
        tot = Insert(s,tot,0,n+i);
        qr[j].push_back(make_pair(i,n+i));
    }
//    //cout<<"bug:\n";
//    for(int i = 1; i<=n+m; i++){
//        //cout<<i<<" "<<arr[i]<<endl;
//    }
//    //cout<<endl;

    aho_corasick();
//    //cout<<"trie ::::::::\n";
//    visit_trie(0,'\0');
//    //cout<<":::::::: trie\n";
    Time = 1;
//    //cout<<"dfs ::::::::\n";
    dfs(0);
//    //cout<<":::::::: dfs\n";
    Time--;
    visit(0);
    for(int i = 1; i<=m; i++) printf("%d\n",ans[i]);
    return 0;
}

//7
//1 a
//2 1 c
//2 1 b
//1 b
//2 1 b
//2 4 a
//2 6 c
//10
//1 d
//7 d
//2 bac
//6 bac
//7 bac
//2 ac
//7 ac
//4 ba
//5 ba
//6 ba


#include<bits/stdc++.h>
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#define MAX ((ll)(1e18))
#define pi (2.0*acos(0))
#define M ((int)(998244353))
#define NN ((int)(1e5 + 5))
#define N ((int)(8e5 + 5))
#define eps ((double)(1e-12))
#define logn 20

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
typedef unsigned long long ull;

typedef tree < ll,  null_type,  less < ll >,  rb_tree_tag,  tree_order_statistics_node_update > o_set;
/// o_set s;
/// s.order_of_key(k) : Number of items strictly smaller than k .
/// *(s.find_by_order(k)) : K-th element in a set (counting from zero).

char s[N];

int arr[N], ans[N], tr[N<<2], to[N], from[N], Time;

vector < pair < int , int > > qr[N];

///trie
int node[27][N];
vector < int > mark[N], v[N]; /// mark = to mark endpoint
void init(int n){ /// creating new node
    for(int i = 0; i<26; i++) node[i][n] = -1;
    mark[n].clear();
}
int Insert(char s[], int tot, int cur, int j){  /// inserting a string
    for(int i = 0; s[i]!='\0'; i++){
        if(node[s[i]-'a'][cur]==-1){
            init(tot);
            node[s[i]-'a'][cur] = tot++;
            if(tot>=N) exit(-1);
        }
        cur = node[s[i]-'a'][cur];
    }

    mark[cur].push_back(j);
    arr[j] = cur;

    return tot;
}
void visit_trie(int n, char c){ /// utility function to check the trie
    printf("%d %c start\n",n,c);
    //for(int a:mark[n]) cout<<a<<" ";
    //cout<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit_trie(node[i][n],'a'+i);
    }
    printf("%d %c end\n",n,c);
}
///aho_corasick...build trie first
int sfx_link[N];
void aho_corasick(){
    sfx_link[0] = -1;
    queue < int > q;
    q.push(0);
    while(!q.empty()){
        int a = q.front();
        q.pop();
        for(int i = 0; i<26; i++){
            if(node[i][a]==-1) continue;
            q.push(node[i][a]);
            int cur = sfx_link[a];
            while(cur!=-1 && node[i][cur]==-1) cur = sfx_link[cur];
            if(cur==-1) cur = 0;
            else cur = node[i][cur];
            sfx_link[node[i][a]] = cur;
            v[cur].push_back(node[i][a]);
        }
    }
}

void update(int n , int b , int e , int i, int v)
{
    if(i<b || i>e) return;
    if(b==e){
        tr[n] += v;
        return;
    }

    int l = n<<1, m = (b+e)>>1;
    update(l,b,m,i,v);
    update(l+1,m+1,e,i,v);
    tr[n] = tr[l]+tr[l+1];
}

int get(int n , int b  , int e , int i , int j)
{
    if(e<i || j<b) return 0;
    if(i<=b && j>=e) return tr[n];
    int l = n<<1, m = (b+e)>>1;
    return get(l,b,m,i,j)+get(l+1,m+1,e,i,j);
}

void visit(int n)
{
    //cout<<n<<" :::\n";
    update(1,1,Time,from[n],1);
    for(int a:mark[n]){
        //cout<<a<<" :\n";
        for(auto p:qr[a]){
            int b = arr[p.second];
            //cout<<p.first<<" "<<p.second<<" "<<b<<"\n";
            ans[p.first] = get(1,1,Time,from[b],to[b]);
        }
    }
    //cout<<"::: "<<n<<endl;
    for(int i = 0; i<26; i++){
        if(node[i][n]!=-1) visit(node[i][n]);
    }
    update(1,1,Time,from[n],-1);
}

void dfs(int n)
{
    ////cout<<n<<" ::::\n";
    from[n] = Time++;
    for(int a:v[n]){
        dfs(a);
    }
    to[n] = Time-1;
    ////cout<<":::: "<<n<<endl;
}

int main()
{
    int n;
    scanf("%d",&n);
    int tot = 1;
    init(0);
    for(int i = 1; i<=n; i++){
        int t;
        scanf("%d",&t);
        if(t==1){
            scanf("%s",s);
            tot = Insert(s,tot,0,i);
        }
        else{
            int j;
            scanf("%d %s",&j,s);
            tot = Insert(s,tot,arr[j],i);
        }
    }
    int m;
    scanf("%d",&m);
    for(int i = 1; i<=m; i++){
        int j;
        scanf("%d %s",&j,s);
        tot = Insert(s,tot,0,n+i);
        qr[j].push_back(make_pair(i,n+i));
    }
//    //cout<<"bug:\n";
//    for(int i = 1; i<=n+m; i++){
//        //cout<<i<<" "<<arr[i]<<endl;
//    }
//    //cout<<endl;

    aho_corasick();
//    //cout<<"trie ::::::::\n";
//    visit_trie(0,'\0');
//    //cout<<":::::::: trie\n";
    Time = 1;
//    //cout<<"dfs ::::::::\n";
    dfs(0);
//    //cout<<":::::::: dfs\n";
    Time--;
    visit(0);
    for(int i = 1; i<=m; i++) printf("%d\n",ans[i]);
    return 0;
}

//7
//1 a
//2 1 c
//2 1 b
//1 b
//2 1 b
//2 4 a
//2 6 c
//10
//1 d
//7 d
//2 bac
//6 bac
//7 bac
//2 ac
//7 ac
//4 ba
//5 ba
//6 ba


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
#ifdef enable_ll
    #define int long long
#endif
#ifdef DEBUG
    #define out(u) cout<<u<<" "
    #define outln(u) cout<<u<<endl
    #define see(u) cout<<#u<<"="<<u<<" "
    #define seeln(u) cout<<#u<<"="<<u<<endl
    #define line cout<<"---------------------\n"
#else
    #define out(u)
    #define outln(u)
    #define see(u)
    #define seeln(u)
    #define line
#endif
#define m_p make_pair
#define pii pair<int,int>
#define piii pair<int,pii>
#define sz(x) x.size()
template <class T> void read(T &u)
{
    u=0; char c=getchar(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=getchar();
    while (c>='0'&&c<='9') u=(u<<3)+(u<<1)+(c^48),c=getchar();
    if (flag) u=-u;
}
bool checkmin(int &a,int b){return (b<a ? a=b,1 : 0);}
bool checkmax(int &a,int b){return (b>a ? a=b,1 : 0);}
const int N=400100;
int n,q;
namespace Fenwick
{
    int C[N+29];
    int lowbit(int x)
    {
        return x & (-x);
    }

    void modify(int x,int num,int lim=N)
    {
        for (;x<=lim;x+=lowbit(x))
        {
            C[x]+=num;
        }
    }

    int query(int x)
    {
        int ans=0;
        for (;x;x-=lowbit(x))
        {
            ans+=C[x];
        }
        return ans;
    }

    int range(int l,int r)
    {
        return query(r)-query(l-1);
    }
}

int sz[N+29],dfn[N+29],dfs_clock=0,End[N+29];
int ch[N+29][26],fail[N+29];
namespace AhoCorasick
{
    int root=0,tot_sz=0;
    vector <int> g[N+29];
    void insert(char *s,int pos)
    {
        int len=strlen(s),tmp=0;
        //cout<<s<<endl;
        for (int i=0;i<len;++i)
        {
            if (ch[tmp][s[i]-'a']==0)
            {
                ch[tmp][s[i]-'a']=++tot_sz;
            }
            tmp=ch[tmp][s[i]-'a'];
            //cout<<tmp<<" ";
        }//cout<<endl;
        End[pos]=tmp;
    }

    void pre_dfs(int x)
    {
        //cout<<x<<endl;
        sz[x]=1;
        dfn[x]=++dfs_clock;
        for (int i=0;i<sz(g[x]);++i)
        {
            int to=g[x][i];
            pre_dfs(to);
            sz[x]+=sz[to];
        }
    }

    void build()
    {
        queue <int> q;
        fail[root]=root;
        for (int i=0;i<=25;++i)
        {
            if (ch[root][i]==0) ch[root][i]=root;
            else
            {
                fail[ch[root][i]]=root;
                q.push(ch[root][i]);
            }
        }

        while (!q.empty())
        {
            int now=q.front(); q.pop();
            g[fail[now]].push_back(now);
            for (int i=0;i<=25;++i)
            {
                if (ch[now][i]==0) ch[now][i]=ch[fail[now]][i];
                else
                {
                    fail[ch[now][i]]=ch[fail[now]][i];
                    q.push(ch[now][i]);
                }
            }
        }
        /*cout<<"fail ";
        for (int i=1;i<=12;++i)
        {
            cout<<fail[i]<<' ';
            for (int j=0;j<26;++j)
            {
                //if (son[i][j])cout<<i<<' '<<son[i][j]<<" "<<(char)('a'+j)<<endl;
            }
        }
        cout<<endl;*/
    }
}

int ans[N+29],opt[N+29];
char cc[N+29],temp[2];
char typ[N+29];
vector <pii> Q[N+29];
vector <int> G[N+29];
void init()
{
    scanf("%d",&n);
    int x;
    for (int i=1;i<=n;++i)
    {
        scanf("%d",&opt[i]);
        if (opt[i]==2)
        {
            scanf("%d",&x);
            G[x].push_back(i);
        }
        scanf("%s",temp);
        typ[i]=temp[0];
    }
    scanf("%d",&q);
    for (int i=1,pos;i<=q;++i)
    {
        scanf("%d%s",&pos,cc);
        AhoCorasick::insert(cc,i);
        //cout<<End[i]<<' ';
        Q[pos].push_back(m_p(i,End[i]));
        //cout<<pos<<" "<<i<<" "<<End[i]<<endl;
    }//cout<<endl;
    AhoCorasick::build();
    AhoCorasick::pre_dfs(0);
}

void dfs(int x,int link)
{
    link=ch[link][typ[x]-'a'];
    //cout<<x<<" "<<link<<endl;
    Fenwick::modify(dfn[link],1);
    for (int i=0;i<sz(G[x]);++i)
    {
        dfs(G[x][i],link);
    }
    for (int i=0;i<sz(Q[x]);++i)
    {
        ans[Q[x][i].first]=Fenwick::range(dfn[Q[x][i].second],dfn[Q[x][i].second]+sz[Q[x][i].second]-1);
        //cout<<x<<" "<<Q[x][i].first<<" "<<Q[x][i].second<<" "<<ans[Q[x][i].first]<<endl;
    }
    Fenwick::modify(dfn[link],-1);
}

void solve()
{
    /*for (int i=1;i<=n;++i)
    {
        cout<<typ[i]<<" ";
    }cout<<endl;*/
    for (int i=1;i<=q;++i)
    {
        if (opt[i]==1)
        {
            dfs(i,0);
        }
    }
    for (int i=1;i<=q;++i)
    {
        printf("%d\n",ans[i]);
    }
}

#undef int
int main()
{
    init();
    solve();
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
#ifdef enable_ll
    #define int long long
#endif
#ifdef DEBUG
    #define out(u) cout<<u<<" "
    #define outln(u) cout<<u<<endl
    #define see(u) cout<<#u<<"="<<u<<" "
    #define seeln(u) cout<<#u<<"="<<u<<endl
    #define line cout<<"---------------------\n"
#else
    #define out(u)
    #define outln(u)
    #define see(u)
    #define seeln(u)
    #define line
#endif
#define m_p make_pair
#define pii pair<int,int>
#define piii pair<int,pii>
#define sz(x) x.size()
template <class T> void read(T &u)
{
    u=0; char c=getchar(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=getchar();
    while (c>='0'&&c<='9') u=(u<<3)+(u<<1)+(c^48),c=getchar();
    if (flag) u=-u;
}
bool checkmin(int &a,int b){return (b<a ? a=b,1 : 0);}
bool checkmax(int &a,int b){return (b>a ? a=b,1 : 0);}
const int N=400000;
int n,q;
namespace Fenwick
{
    int C[N+29];
    int lowbit(int x)
    {
        return x & (-x);
    }

    void modify(int x,int num,int lim=N)
    {
        for (;x<=lim;x+=lowbit(x))
        {
            C[x]+=num;
        }
    }

    int query(int x)
    {
        int ans=0;
        for (;x;x-=lowbit(x))
        {
            ans+=C[x];
        }
        return ans;
    }

    int range(int l,int r)
    {
        return query(r)-query(l-1);
    }
}

int sz[N+29],dfn[N+29],dfs_clock=0,End[N+29];
int ch[N+29][26],fail[N+29];
namespace AhoCorasick
{
    int root=0,tot_sz=0;
    vector <int> g[N+29];
    void insert(char *s,int pos)
    {
        int len=strlen(s),tmp=0;
        //cout<<s<<endl;
        for (int i=0;i<len;++i)
        {
            if (ch[tmp][s[i]-'a']==0)
            {
                ch[tmp][s[i]-'a']=++tot_sz;
            }
            tmp=ch[tmp][s[i]-'a'];
            //cout<<tmp<<" ";
        }//cout<<endl;
        End[pos]=tmp;
    }

    void pre_dfs(int x)
    {
        //cout<<x<<endl;
        sz[x]=1;
        dfn[x]=++dfs_clock;
        for (int i=0;i<sz(g[x]);++i)
        {
            int to=g[x][i];
            pre_dfs(to);
            sz[x]+=sz[to];
        }
    }

    void build()
    {
        queue <int> q;
        fail[root]=root;
        for (int i=0;i<=25;++i)
        {
            if (ch[root][i]==0) ch[root][i]=root;
            else
            {
                fail[ch[root][i]]=root;
                q.push(ch[root][i]);
            }
        }

        while (!q.empty())
        {
            int now=q.front(); q.pop();
            g[fail[now]].push_back(now);
            for (int i=0;i<=25;++i)
            {
                if (ch[now][i]==0) ch[now][i]=ch[fail[now]][i];
                else
                {
                    fail[ch[now][i]]=ch[fail[now]][i];
                    q.push(ch[now][i]);
                }
            }
        }
        for (int i=1;i<=tot_sz;++i)
        {
            //g[fail[i]].push_back(i);
        }
        /*cout<<"fail ";
        for (int i=1;i<=12;++i)
        {
            cout<<fail[i]<<' ';
            for (int j=0;j<26;++j)
            {
                //if (son[i][j])cout<<i<<' '<<son[i][j]<<" "<<(char)('a'+j)<<endl;
            }
        }
        cout<<endl;*/
    }
}

int ans[N+29],opt[N+29];
char cc[N+29],temp[2];
char typ[N+29];
vector <pii> Q[N+29];
vector <int> G[N+29];
void init()
{
    scanf("%d",&n);
    int x;
    for (int i=1;i<=n;++i)
    {
        scanf("%d",&opt[i]);
        if (opt[i]==2)
        {
            scanf("%d",&x);
            G[x].push_back(i);
        }
        scanf("%s",temp);
        typ[i]=temp[0];
    }
    scanf("%d",&q);
    for (int i=1,pos;i<=q;++i)
    {
        scanf("%d%s",&pos,cc);
        AhoCorasick::insert(cc,i);
        //cout<<End[i]<<' ';
        Q[pos].push_back(m_p(i,End[i]));
        //cout<<pos<<" "<<i<<" "<<End[i]<<endl;
    }//cout<<endl;
    AhoCorasick::build();
    AhoCorasick::pre_dfs(0);
}

void dfs(int x,int link)
{
    link=ch[link][typ[x]-'a'];
    //cout<<x<<" "<<link<<endl;
    Fenwick::modify(dfn[link],1);
    for (int i=0;i<sz(G[x]);++i)
    {
        dfs(G[x][i],link);
    }
    for (int i=0;i<sz(Q[x]);++i)
    {
        ans[Q[x][i].first]=Fenwick::range(dfn[Q[x][i].second],dfn[Q[x][i].second]+sz[Q[x][i].second]-1);
        //cout<<x<<" "<<Q[x][i].first<<" "<<Q[x][i].second<<" "<<ans[Q[x][i].first]<<endl;
    }
    Fenwick::modify(dfn[link],-1);
}

void solve()
{
    /*for (int i=1;i<=n;++i)
    {
        cout<<typ[i]<<" ";
    }cout<<endl;*/
    for (int i=1;i<=q;++i)
    {
        if (opt[i]==1)
        {
            dfs(i,0);
        }
    }
    for (int i=1;i<=q;++i)
    {
        printf("%d\n",ans[i]);
    }
}

#undef int
int main()
{
    init();
    solve();
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
#ifdef enable_ll
    #define int long long
#endif
#ifdef DEBUG
    #define out(u) cout<<u<<" "
    #define outln(u) cout<<u<<endl
    #define see(u) cout<<#u<<"="<<u<<" "
    #define seeln(u) cout<<#u<<"="<<u<<endl
    #define line cout<<"---------------------\n"
#else
    #define out(u)
    #define outln(u)
    #define see(u)
    #define seeln(u)
    #define line
#endif
#define m_p make_pair
#define pii pair<int,int>
#define piii pair<int,pii>
#define sz(x) x.size()
template <class T> void read(T &u)
{
    u=0; char c=getchar(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=getchar();
    while (c>='0'&&c<='9') u=(u<<3)+(u<<1)+(c^48),c=getchar();
    if (flag) u=-u;
}
bool checkmin(int &a,int b){return (b<a ? a=b,1 : 0);}
bool checkmax(int &a,int b){return (b>a ? a=b,1 : 0);}
const int N=400000;
int n,q;
namespace Fenwick
{
    int C[N+29];
    int lowbit(int x)
    {
        return x & (-x);
    }

    void modify(int x,int num,int lim=N)
    {
        for (;x<=lim;x+=lowbit(x))
        {
            C[x]+=num;
        }
    }

    int query(int x)
    {
        int ans=0;
        for (;x;x-=lowbit(x))
        {
            ans+=C[x];
        }
        return ans;
    }

    int range(int l,int r)
    {
        return query(r)-query(l-1);
    }
}

int sz[N+29],dfn[N+29],dfs_clock=0,End[N+29];
int ch[N+29][26],fail[N+29];
namespace AhoCorasick
{
    int root=0,tot_sz=0;
    vector <int> g[N+29];
    void insert(char *s,int pos)
    {
        int len=strlen(s),tmp=0;
        //cout<<s<<endl;
        for (int i=0;i<len;++i)
        {
            if (ch[tmp][s[i]-'a']==0)
            {
                ch[tmp][s[i]-'a']=++tot_sz;
            }
            tmp=ch[tmp][s[i]-'a'];
            //cout<<tmp<<" ";
        }//cout<<endl;
        End[pos]=tmp;
    }

    void pre_dfs(int x)
    {
        //cout<<x<<endl;
        sz[x]=1;
        dfn[x]=++dfs_clock;
        for (int i=0;i<sz(g[x]);++i)
        {
            int to=g[x][i];
            pre_dfs(to);
            sz[x]+=sz[to];
        }
    }

    void build()
    {
        queue <int> q;
        fail[root]=root;
        for (int i=0;i<=25;++i)
        {
            if (ch[root][i]==0) ch[root][i]=root;
            else
            {
                fail[ch[root][i]]=root;
                q.push(ch[root][i]);
            }
        }

        while (!q.empty())
        {
            int now=q.front(); q.pop();
            for (int i=0;i<=25;++i)
            {
                if (ch[now][i]==0) ch[now][i]=ch[fail[now]][i];
                else
                {
                    fail[ch[now][i]]=ch[fail[now]][i];
                    q.push(ch[now][i]);
                }
            }
        }
        for (int i=1;i<=tot_sz;++i)
        {
            g[fail[i]].push_back(i);
        }
        /*cout<<"fail ";
        for (int i=1;i<=12;++i)
        {
            cout<<fail[i]<<' ';
            for (int j=0;j<26;++j)
            {
                //if (son[i][j])cout<<i<<' '<<son[i][j]<<" "<<(char)('a'+j)<<endl;
            }
        }
        cout<<endl;*/
    }
}

int ans[N+29],opt[N+29];
char cc[N+29],temp[2];
char typ[N+29];
vector <pii> Q[N+29];
vector <int> G[N+29];
void init()
{
    scanf("%d",&n);
    int x;
    for (int i=1;i<=n;++i)
    {
        scanf("%d",&opt[i]);
        if (opt[i]==2)
        {
            scanf("%d",&x);
            G[x].push_back(i);
        }
        scanf("%s",temp);
        typ[i]=temp[0];
    }
    scanf("%d",&q);
    for (int i=1,pos;i<=q;++i)
    {
        scanf("%d%s",&pos,cc);
        AhoCorasick::insert(cc,i);
        //cout<<End[i]<<' ';
        Q[pos].push_back(m_p(i,End[i]));
        //cout<<pos<<" "<<i<<" "<<End[i]<<endl;
    }//cout<<endl;
    AhoCorasick::build();
    AhoCorasick::pre_dfs(0);
}

void dfs(int x,int link)
{
    link=ch[link][typ[x]-'a'];
    //cout<<x<<" "<<link<<endl;
    Fenwick::modify(dfn[link],1);
    for (int i=0;i<sz(G[x]);++i)
    {
        dfs(G[x][i],link);
    }
    for (int i=0;i<sz(Q[x]);++i)
    {
        ans[Q[x][i].first]=Fenwick::range(dfn[Q[x][i].second],dfn[Q[x][i].second]+sz[Q[x][i].second]-1);
        //cout<<x<<" "<<Q[x][i].first<<" "<<Q[x][i].second<<" "<<ans[Q[x][i].first]<<endl;
    }
    Fenwick::modify(dfn[link],-1);
}

void solve()
{
    /*for (int i=1;i<=n;++i)
    {
        cout<<typ[i]<<" ";
    }cout<<endl;*/
    for (int i=1;i<=n;++i)
    {
        if (opt[i]==1)
        {
            dfs(i,0);
        }
    }
    for (int i=1;i<=q;++i)
    {
        printf("%d\n",ans[i]);
    }
}

#undef int
int main()
{
    init();
    solve();
    return 0;
}


#include <cstdio>
#include <iostream>
#include <cstdlib>
#include <cstring>
#include <string>
#include <algorithm>
#include <ctime>
#include <vector>
#include <map>
#include <set>
#include <queue>
#include <cmath>
using namespace std;
#ifdef enable_ll
    #define int long long
#endif
#ifdef DEBUG
    #define out(u) cout<<u<<" "
    #define outln(u) cout<<u<<endl
    #define see(u) cout<<#u<<"="<<u<<" "
    #define seeln(u) cout<<#u<<"="<<u<<endl
    #define line cout<<"---------------------\n"
#else
    #define out(u)
    #define outln(u)
    #define see(u)
    #define seeln(u)
    #define line
#endif
#define m_p make_pair
#define pii pair<int,int>
#define piii pair<int,pii>
#define sz(x) x.size()
template <class T> void read(T &u)
{
    u=0; char c=getchar(); int flag=0;
    while (c<'0'||c>'9') flag|=(c=='-'),c=getchar();
    while (c>='0'&&c<='9') u=(u<<3)+(u<<1)+(c^48),c=getchar();
    if (flag) u=-u;
}
bool checkmin(int &a,int b){return (b<a ? a=b,1 : 0);}
bool checkmax(int &a,int b){return (b>a ? a=b,1 : 0);}
const int N=400000;
int n,q;
namespace Fenwick
{
    int C[N+29];
    int lowbit(int x)
    {
        return x & (-x);
    }

    void modify(int x,int num,int lim=N)
    {
        for (;x<=lim;x+=lowbit(x))
        {
            C[x]+=num;
        }
    }

    int query(int x)
    {
        int ans=0;
        for (;x;x-=lowbit(x))
        {
            ans+=C[x];
        }
        return ans;
    }

    int range(int l,int r)
    {
        return query(r)-query(l-1);
    }
}

int sz[N+29],dfn[N+29],dfs_clock=0,End[N+29];
int ch[N+29][26],fail[N+29];
namespace AhoCorasick
{
    int root=0,tot_sz=0;
    vector <int> g[N+29];
    void insert(char *s,int pos)
    {
        int len=strlen(s),tmp=0;
        //cout<<s<<endl;
        for (int i=0;i<len;++i)
        {
            if (ch[tmp][s[i]-'a']==0)
            {
                ch[tmp][s[i]-'a']=++tot_sz;
            }
            tmp=ch[tmp][s[i]-'a'];
            //cout<<tmp<<" ";
        }//cout<<endl;
        End[pos]=tmp;
    }

    void pre_dfs(int x)
    {
        //cout<<x<<endl;
        sz[x]=1;
        dfn[x]=++dfs_clock;
        for (int i=0;i<sz(g[x]);++i)
        {
            int to=g[x][i];
            pre_dfs(to);
            sz[x]+=sz[to];
        }
    }

    void build()
    {
        queue <int> q;
        fail[root]=root;
        for (int i=0;i<=25;++i)
        {
            if (ch[root][i]==0) ch[root][i]=root;
            else
            {
                fail[ch[root][i]]=root;
                q.push(ch[root][i]);
            }
        }

        while (!q.empty())
        {
            int now=q.front(); q.pop();
            for (int i=0;i<=25;++i)
            {
                if (ch[now][i]==0) ch[now][i]=ch[fail[now]][i];
                else
                {
                    fail[ch[now][i]]=ch[fail[now]][i];
                    q.push(ch[now][i]);
                }
            }
        }
        for (int i=1;i<=tot_sz;++i)
        {
            g[fail[i]].push_back(i);
        }
        /*cout<<"fail ";
        for (int i=1;i<=12;++i)
        {
            cout<<fail[i]<<' ';
            for (int j=0;j<26;++j)
            {
                //if (son[i][j])cout<<i<<' '<<son[i][j]<<" "<<(char)('a'+j)<<endl;
            }
        }
        cout<<endl;*/
    }
}

int ans[N+29],opt[N+29];
char cc[N+29],temp[2];
char typ[N+29];
vector <pii> Q[N+29];
vector <int> G[N+29];
void init()
{
    scanf("%d",&n);
    int x;
    for (int i=1;i<=n;++i)
    {
        scanf("%d",&opt[i]);
        if (opt[i]==2)
        {
            scanf("%d",&x);
            G[x].push_back(i);
        }
        scanf("%s",temp);
        typ[i]=temp[0];
    }
    scanf("%d",&q);
    for (int i=1,pos;i<=q;++i)
    {
        scanf("%d%s",&pos,cc);
        AhoCorasick::insert(cc,i);
        //cout<<End[i]<<' ';
        Q[pos].push_back(m_p(i,End[i]));
        //cout<<pos<<" "<<i<<" "<<End[i]<<endl;
    }//cout<<endl;
    AhoCorasick::build();
    AhoCorasick::pre_dfs(0);
}

void dfs(int x,int link)
{
    link=ch[link][typ[x]-'a'];
    //cout<<x<<" "<<link<<endl;
    Fenwick::modify(dfn[link],1);
    for (int i=0;i<sz(G[x]);++i)
    {
        dfs(G[x][i],link);
    }
    for (int i=0;i<sz(Q[x]);++i)
    {
        ans[Q[x][i].first]=Fenwick::range(dfn[Q[x][i].second],dfn[Q[x][i].second]+sz[Q[x][i].second]-1);
        //cout<<x<<" "<<Q[x][i].first<<" "<<Q[x][i].second<<" "<<ans[Q[x][i].first]<<endl;
    }
    Fenwick::modify(dfn[link],-1);
}

void solve()
{
    /*for (int i=1;i<=n;++i)
    {
        cout<<typ[i]<<" ";
    }cout<<endl;*/
    for (int i=1;i<=q;++i)
    {
        if (opt[i]==1)
        {
            dfs(i,0);
        }
    }
    for (int i=1;i<=q;++i)
    {
        printf("%d\n",ans[i]);
    }
}

#undef int
int main()
{
    init();
    solve();
    return 0;
}


#include<bits/stdc++.h>
#define mx 400005
using namespace std;
int tr[mx][26],suffix[mx],ed[mx],node,len;
void init()
{
    node=0, len=0;
    memset(tr[0],-1,sizeof tr[0]);
    memset(suffix,0,sizeof suffix);
}
inline int New()
{
    node++;
    memset(tr[node],-1,sizeof tr[node]);
    return node;
}
inline void insert(string &s, int pos)
{
    int cur = 0;
    for(int i=0; i<s.size(); i++)
    {
        int c = s[i]-'a';
        if(tr[cur][c]==-1)tr[cur][c]=New();
        cur = tr[cur][c];
    }
    ed[pos]=cur;
}
void reverse_link()
{
    queue<int>qu;
    for(int i=0; i<26; i++)
    {
        if(tr[0][i]!=-1)
        {
            qu.push(tr[0][i]);
        }
        else tr[0][i]=0;
    }
    while(!qu.empty())
    {
        int u=qu.front();
        qu.pop();
        for(int i=0;i<26;i++)
        {
            int v = tr[u][i];
            if(v==-1)
            {
                tr[u][i]=tr[suffix[u]][i];
                continue;
            }
            suffix[v]=tr[suffix[u]][i];
            qu.push(v);
        }
    }
}
//Make tree with reverse suffix link
vector<int>rtr[mx];
void makeTree()
{
    for(int i=1;i<=node;i++)
    {
        rtr[suffix[i]].push_back(i);
    }
}
int st[mx],en[mx],tim;
void timing(int u)
{
    st[u]=++tim;
    for(auto v : rtr[u])
    {
        timing(v);
    }
    en[u] = tim;
}
int bit[mx];
void up(int i, int val)
{
    for( ; i<mx; i+=(i&(-i)))
    {
        bit[i]+=val;
    }
}
int qry(int i)
{
    int sm = 0;
    for( ; i>0; i-=(i&(-i)))
    {
        sm+=bit[i];
    }
    return sm;
}

vector<pair<int,int>>adj[mx],qr[mx];
int ans[mx];
void search(int u, int nd)
{
    for(auto pr : qr[u])
    {
        ans[pr.second]=qry(en[pr.first])-qry(st[pr.first]-1);
    }
    for(auto pr : adj[u])
    {
        int c = pr.first;
        int cur = tr[nd][c];
        if(cur)up(st[cur],1);
        search(pr.second,cur);
        if(cur)up(st[cur],-1);
    }
}
string s,s2;
int main()
{
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int m;
    cin >> m;
    for(int i=1;i<=m;i++)
    {
        int type;
        cin >> type;
        if(type==1)
        {
            cin >>  s;
            adj[0].push_back({s[0]-'a', i});
        }
        else
        {
            int id;
            cin >> id >> s;
            adj[id].push_back({s[0]-'a', i});
        }
    }
    int n;
    cin >> n;
    init();
    for(int i=1;i<=n;i++)
    {
        int id;
        cin >> id >> s;
        insert(s,i);
        qr[id].push_back({ed[i],i});
    }
    reverse_link();
    makeTree();
    timing(0);
    search(0,0);
    for(int i=1;i<=n;i++)
    {
        cout << ans[i] << "\n";
    }
    return 0;
}


#include<bits/stdc++.h>
#define mx 4000
using namespace std;
int tr[mx][26],suffix[mx],ed[mx],node,len;
void init()
{
    node=0, len=0;
    memset(tr[0],-1,sizeof tr[0]);
    memset(suffix,0,sizeof suffix);
}
inline int New()
{
    node++;
    memset(tr[node],-1,sizeof tr[node]);
    return node;
}
inline void insert(string &s, int pos)
{
    int cur = 0;
    for(int i=0; i<s.size(); i++)
    {
        int c = s[i]-'a';
        if(tr[cur][c]==-1)tr[cur][c]=New();
        cur = tr[cur][c];
    }
    ed[pos]=cur;
}
void reverse_link()
{
    queue<int>qu;
    for(int i=0; i<26; i++)
    {
        if(tr[0][i]!=-1)
        {
            qu.push(tr[0][i]);
        }
        else tr[0][i]=0;
    }
    while(!qu.empty())
    {
        int u=qu.front();
        qu.pop();
        for(int i=0;i<26;i++)
        {
            int v = tr[u][i];
            if(v==-1)
            {
                tr[u][i]=tr[suffix[u]][i];
                continue;
            }
            suffix[v]=tr[suffix[u]][i];
            qu.push(v);
        }
    }
}
//Make tree with reverse suffix link
vector<int>rtr[mx];
void makeTree()
{
    for(int i=1;i<=node;i++)
    {
        rtr[suffix[i]].push_back(i);
    }
}
int st[mx],en[mx],tim;
void timing(int u)
{
    st[u]=++tim;
    for(auto v : rtr[u])
    {
        timing(v);
    }
    en[u] = tim;
}
int bit[mx];
void up(int i, int val)
{
    for( ; i<mx; i+=(i&(-i)))
    {
        bit[i]+=val;
    }
}
int qry(int i)
{
    int sm = 0;
    for( ; i>0; i-=(i&(-i)))
    {
        sm+=bit[i];
    }
    return sm;
}

vector<pair<int,int>>adj[mx],qr[mx];
int ans[mx];
//void search(int u, int cur = 0)
//{
//    for(auto pr : qr[u])
//    {
//        ans[pr.second]=qry(st[pr.first]);
//    }
//    for(auto pr : adj[u])
//    {
//        int c = pr.first;
//        cur = tr[cur][c];
//        if(cur)up(st[cur],1),up(en[cur]+1,-1);
//        search(pr.second);
//        if(cur)up(st[cur],-1),up(en[cur]+1,1);
//    }
//}

void search(int u, int cur)
{
    for(auto pr : qr[u])
    {
        ans[pr.second]=qry(en[pr.first])-qry(st[pr.first]-1);
    }
    for(auto pr : adj[u])
    {
        int c = pr.first;
        cur = tr[cur][c];
        if(cur)up(st[cur],1);
        search(pr.second,cur);
        if(cur)up(st[cur],-1);
    }
}
string s,s2;
int main()
{
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int m;
    cin >> m;
    for(int i=1;i<=m;i++)
    {
        int type;
        cin >> type;
        if(type==1)
        {
            cin >>  s;
            adj[0].push_back({s[0],i});
        }
        else
        {
            int id;
            cin >> id >> s;
            adj[id].push_back({s[0],i});
        }
    }
    int n;
    cin >> n;
    init();
    for(int i=1;i<=n;i++)
    {
        int id;
        cin >> id >> s;
        insert(s,i);
        qr[id].push_back({ed[i],i});
    }
    reverse_link();
    makeTree();
    timing(0);
    search(0,0);
    //search(0);
    for(int i=1;i<=n;i++)
    {
        cout << ans[i] << "\n";
    }
    return 0;
}


#include<bits/stdc++.h>
#define mx 400005
using namespace std;
int tr[mx][26],suffix[mx],ed[mx],node,len;
void init()
{
    node=0, len=0;
    memset(tr[0],-1,sizeof tr[0]);
    memset(suffix,0,sizeof suffix);
}
inline int New()
{
    node++;
    memset(tr[node],-1,sizeof tr[node]);
    return node;
}
inline void insert(string &s, int pos)
{
    int cur = 0;
    for(int i=0; i<s.size(); i++)
    {
        int c = s[i]-'a';
        if(tr[cur][c]==-1)tr[cur][c]=New();
        cur = tr[cur][c];
    }
    ed[pos]=cur;
}
void reverse_link()
{
    queue<int>qu;
    for(int i=0; i<26; i++)
    {
        if(tr[0][i]!=-1)
        {
            qu.push(tr[0][i]);
        }
        else tr[0][i]=0;
    }
    while(!qu.empty())
    {
        int u=qu.front();
        qu.pop();
        for(int i=0;i<26;i++)
        {
            int v = tr[u][i];
            if(v==-1)
            {
                tr[u][i]=tr[suffix[u]][i];
                continue;
            }
            suffix[v]=tr[suffix[u]][i];
            qu.push(v);
        }
    }
}
//Make tree with reverse suffix link
vector<int>rtr[mx];
void makeTree()
{
    for(int i=1;i<=node;i++)
    {
        rtr[suffix[i]].push_back(i);
    }
}
int st[mx],en[mx],tim;
void timing(int u)
{
    st[u]=++tim;
    for(auto v : rtr[u])
    {
        timing(v);
    }
    en[u] = tim;
}
int bit[mx];
void up(int i, int val)
{
    for( ; i<mx; i+=(i&(-i)))
    {
        bit[i]+=val;
    }
}
int qry(int i)
{
    int sm = 0;
    for( ; i>0; i-=(i&(-i)))
    {
        sm+=bit[i];
    }
    return sm;
}

vector<pair<int,int>>adj[mx],qr[mx];
int ans[mx];
void search(int u, int nd)
{
    for(auto pr : qr[u])
    {
        ans[pr.second]=qry(st[pr.first]);
    }
    for(auto pr : adj[u])
    {
        int c = pr.first;
        int cur = tr[nd][c];
        if(cur)up(st[cur],1),up(en[cur]+1,-1);
        search(pr.second,cur);
        if(cur)up(st[cur],-1),up(en[cur]+1,1);
    }
}
string s,s2;
int main()
{
    ios_base::sync_with_stdio(0),cin.tie(0),cout.tie(0);
    int m;
    cin >> m;
    for(int i=1;i<=m;i++)
    {
        int type;
        cin >> type;
        if(type==1)
        {
            cin >>  s;
            adj[0].push_back({s[0]-'a', i});
        }
        else
        {
            int id;
            cin >> id >> s;
            adj[id].push_back({s[0]-'a', i});
        }
    }
    int n;
    cin >> n;
    init();
    for(int i=1;i<=n;i++)
    {
        int id;
        cin >> id >> s;
        insert(s,i);
        qr[id].push_back({ed[i],i});
    }
    reverse_link();
    makeTree();
    timing(0);
    search(0,0);
    for(int i=1;i<=n;i++)
    {
        cout << ans[i] << "\n";
    }
    return 0;
}


#include <bits/stdc++.h>
#ifdef Manari
#include "debug.hpp"
#else
#define debug(...) 0
#endif
using namespace std;

typedef long long ll;

const int N = 8e5 + 5;

vector<int> G[N], tG[N];
vector<pair<int, int>> query[N];
int tot, to[N][26], pos[N], fail[N];
int dfn, in[N], out[N];
int sum[N], ans[N];

void upd(int at, int diff) {
  for (int i = at; i < N; i += (i & -i)) sum[i] += diff;
}

int get(int at) {
  int res = 0;
  for (int i = at; i; i -= (i & -i)) res += sum[i];
  return res;
}

void dfs(int u) {
  in[u] = ++dfn;
  for (auto& v : G[u]) dfs(v);
  out[u] = dfn;
}

void build() {
  queue<int> Q;
  for (int i = 0; i < 26; i++) {
    if (to[0][i]) Q.push(to[0][i]);
  }
  while (!Q.empty()) {
    int u = Q.front(); Q.pop();
    G[fail[u]].push_back(u);
    for (int i = 0; i < 26; i++) {
      if (to[u][i]) {
        fail[to[u][i]] = to[fail[u]][i];
        Q.push(to[u][i]);
      } else {
        to[u][i] = to[fail[u]][i];
      }
    }
  }
  dfs(0);
}

int push(int id, char c) {
  int &cur = to[id][c - 'a'];
  if (cur == 0) cur = ++tot;
  return cur;
}

void solve(int u) {
  upd(in[u], 1);
  for (auto& v : tG[u]) solve(v);
  for (auto& v : query[u]) {
    ans[v.second] = get(out[v.first]) - get(in[v.first] - 1);
  }
  upd(in[u], -1);
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

  int n; cin >> n;
  for (int i = 1; i <= n; i++) {
    int op; cin >> op;
    if (op == 1) {
      char c; cin >> c;
      pos[i] = push(0, c);
      tG[0].push_back(pos[i]);
    } else {
      int j; cin >> j;
      char c; cin >> c;
      pos[i] = push(pos[j], c);
      tG[pos[j]].push_back(pos[i]);
    }
  }
  int m; cin >> m;
  for (int i = 1; i <= m; i++) {
    int id; cin >> id;
    string s; cin >> s;
    int cur = 0;
    for (auto& c : s) cur = push(cur, c);
    query[pos[id]].push_back({ cur, i });
  }
  build();
  for (auto& v : tG[0]) solve(v);
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << "\n";
  }
}


#include <bits/stdc++.h>
#ifdef Manari
#include "debug.hpp"
#else
#define debug(...) 0
#endif
using namespace std;

typedef long long ll;

const int N = 4e5 + 5;

namespace acam {
  vector<int> G[N];
  int tot, son[N][26], fail[N];
  int tag, dfn[N], sz[N];

  int insert(char *s) {
    int cur = 0;
    for (int i = 0; s[i]; i++) {
      int &to = son[cur][s[i] - 'a'];
      if (to == 0) to = ++tot;
      cur = to;
    }
    return cur;
  }

  void dfs(int u) {
    dfn[u] = ++tag, sz[u] = 1;
    for (auto& v : G[u]) dfs(v), sz[u] += sz[v];
  }

  void build() {
    queue<int> Q;
    for (int i = 0; i < 26; i++) {
      if (son[0][i]) Q.push(son[0][i]);
    }
    while (!Q.empty()) {
      int u = Q.front(); Q.pop();
      for (int i = 0; i < 26; i++) {
        if (son[u][i]) {
          fail[son[u][i]] = son[fail[u]][i];
          Q.push(son[u][i]);
        } else {
          son[u][i] = son[fail[u]][i];
        }
      }
    }
    for (int i = 1; i <= tot; i++) {
      G[fail[i]].push_back(i);
    }
    dfs(0);
  }
}

int sum[N];

void upd(int at, int diff) {
  for (int i = at; i < N; i += (i & -i)) sum[i] += diff;
}

int get(int at) {
  int res = 0;
  for (int i = at; i; i -= (i & -i)) res += sum[i];
  return res;
}

int getans(int l, int r) {
  return get(r) - get(l - 1);
}

vector<int> G[N];
vector<pair<int, int>> query[N];
int op[N], ans[N];
char s[N];

void dfs(int cur, int id) {
  int u = acam::son[cur][s[id] - 'a'];
  upd(acam::dfn[u], 1);
  for (auto& v : G[id]) dfs(u, v);
  for (auto& q : query[id]) {
    ans[q.second] = getans(acam::dfn[q.first], acam::dfn[q.first] + acam::sz[q.first] - 1);
  }
  upd(acam::dfn[u], -1);
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

  int n; cin >> n;
  for (int i = 1; i <= n; i++) {
    int j; cin >> op[i];
    if (op[i] == 2) cin >> j, G[j].push_back(i);
    cin >> s[i];
  }
  int m; cin >> m;
  for (int i = 1; i <= m; i++) {
    int id; cin >> id;
    static char t[N]; cin >> t;
    query[id].push_back({ acam::insert(t), i });
  }
  acam::build();
  for (int i = 1; i <= n; i++) {
    if (op[i] == 1) dfs(0, i);
  }
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << "\n";
  }
}


#include <bits/stdc++.h>
#ifdef Manari
#include "debug.hpp"
#else
#define debug(...) 0
#endif
using namespace std;

typedef long long ll;

const int N = 4e5 + 5;

vector<int> G[N], tG[N];
vector<pair<int, int>> query[N];
int tot, to[N][26], pos[N], fail[N];
int dfn, in[N], out[N];
int sum[N], ans[N];

void upd(int at, int diff) {
  for (int i = at; i < N; i += (i & -i)) sum[i] += diff;
}

int get(int at) {
  int res = 0;
  for (int i = at; i; i -= (i & -i)) res += sum[i];
  return res;
}

void dfs(int u) {
  in[u] = ++dfn;
  for (auto& v : G[u]) dfs(v);
  out[u] = dfn;
}

void build() {
  queue<int> Q;
  for (int i = 0; i < 26; i++) {
    if (to[0][i]) Q.push(to[0][i]);
  }
  while (!Q.empty()) {
    int u = Q.front(); Q.pop();
    G[fail[u]].push_back(u);
    for (int i = 0; i < 26; i++) {
      if (to[u][i]) {
        fail[to[u][i]] = to[fail[u]][i];
        Q.push(to[u][i]);
      } else {
        to[u][i] = to[fail[u]][i];
      }
    }
  }
  dfs(0);
}

int push(int id, char c) {
  int &cur = to[id][c - 'a'];
  if (cur == 0) cur = ++tot;
  return cur;
}

void solve(int u) {
  upd(in[u], 1);
  for (auto& v : tG[u]) solve(v);
  for (auto& v : query[u]) {
    ans[v.second] = get(out[v.first]) - get(in[v.first] - 1);
  }
  upd(in[u], -1);
}

int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0);

  int n; cin >> n;
  for (int i = 1; i <= n; i++) {
    int op; cin >> op;
    if (op == 1) {
      char c; cin >> c;
      pos[i] = push(0, c);
      tG[0].push_back(pos[i]);
    } else {
      int j; cin >> j;
      char c; cin >> c;
      pos[i] = push(pos[j], c);
      tG[pos[j]].push_back(pos[i]);
    }
  }
  int m; cin >> m;
  for (int i = 1; i <= m; i++) {
    int id; cin >> id;
    string s; cin >> s;
    int cur = 0;
    for (auto& c : s) cur = push(cur, c);
    query[pos[id]].push_back({ cur, i });
  }
  build();
  for (auto& v : tG[0]) solve(v);
  for (int i = 1; i <= m; i++) {
    cout << ans[i] << "\n";
  }
}


#include <map>
#include <vector>
#include <queue>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 400003
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
char S[N];
int n,m,rt[N<<1];
namespace Trie {
    int id[N],tim;
    struct Node {
        map<int,int>ch;
        int siz,dfn,top,son,fa;
    }t[N];
    void dfs1(int u) {
        t[u].siz=1;
        for(int i=0;i<27;++i)
            if(t[u].ch.count(i)) {
                int v=t[u].ch[i];
                t[v].fa=u,dfs1(v),t[u].siz+=t[v].siz;
                if(!t[u].son||t[v].siz>t[t[u].son].siz) t[u].son=v;
            }
    }
    void dfs2(int u,int tp) {
        t[u].top=tp;
        t[u].dfn=++tim;
        if(t[u].son) dfs2(t[u].son,tp);
        for(int i=0;i<27;++i)
            if(t[u].ch.count(i)) {
                int v=t[u].ch[i];
                if(v!=t[u].son)
                    dfs2(v,v);
            }
    }
    void build_tree() {
        dfs1(0), dfs2(0,0);
    }
};
namespace seg {
    #define ls t[x].lson
    #define rs t[x].rson
    int tot;
    struct Node {
        int lson,rson,sum;
    }t[N*50];
    void pushup(int x) {
        t[x].sum=t[ls].sum+t[rs].sum;
    }
    void update(int &x,int l,int r,int p,int v) {
        if(!x)
            x=++tot;
        if(l==r) {
            t[x].sum=v;
            return;
        }
        int mid=(l+r)>>1;
        if(p<=mid) update(ls,l,mid,p,v);
        else update(rs,mid+1,r,p,v);
        pushup(x);
    }
    int query(int x,int l,int r,int L,int R) {
        if(!x) return 0;
        if(l>=L&&r<=R) return t[x].sum;
        int mid=(l+r)>>1,re=0;
        if(L<=mid) re+=query(ls,l,mid,L,R);
        if(R>mid) re+=query(rs,mid+1,r,L,R);
        return re;
    }
    int merge(int l,int r,int x,int y,int tt) {
        if(!x||!y)
            return x+y;
        int oo=++tot;
        if(l==r)
            t[oo].sum=1;
        else {
            int mid=(l+r)>>1;
            t[oo].lson=merge(l,mid,t[x].lson,t[y].lson,tt);
            t[oo].rson=merge(mid+1,r,t[x].rson,t[y].rson,tt);
            pushup(oo);
        }
        return oo;
    }
    #undef ls
    #undef rs
};
namespace SAM {
    int tot,id[N<<1],tax[N<<1],rk[N<<1];
    struct Node {
        map<int,int>ch;
        int len,pre;
    }t[N<<1];
    struct Edge {
        int from,c;
        Edge(int from=0,int c=0):from(from),c(c){}
    };
    queue<int>q;
    int extend(int lst,int c,int i) {
        int p=lst;
        if(t[p].ch.count(c)) {
            int q=t[p].ch[c];
            if(t[q].len==t[p].len+1) seg::update(rt[q],1,Trie::tim,i,1),lst=q;
            else {
                int nq=++tot;
                t[nq].len=t[p].len+1;
                t[nq].pre=t[q].pre,t[q].pre=nq;
                t[nq].ch=t[q].ch;
                seg::update(rt[nq],1,Trie::tim,i,1);
                for(;p&&t[p].ch.count(c)&&t[p].ch[c]==q;p=t[p].pre) t[p].ch[c]=nq;
                lst=nq;
            }
        }
        else {
            int np=++tot;
            t[np].len=t[p].len+1;
            seg::update(rt[np],1,Trie::tim,i,1);
            for(;p&&!t[p].ch.count(c);p=t[p].pre) t[p].ch[c]=np;
            if(!p) t[np].pre=1;
            else {
                int q=t[p].ch[c];
                if(t[q].len==t[p].len+1) t[np].pre=q;
                else {
                    int nq=++tot;
                    t[nq].len=t[p].len+1;
                    t[nq].pre=t[q].pre,t[q].pre=t[np].pre=nq;
                    t[nq].ch=t[q].ch;
                    for(;p&&t[p].ch.count(c)&&t[p].ch[c]==q;p=t[p].pre) t[p].ch[c]=nq;
                }
            }
            lst=np;
        }
        return lst;
    }
    void construct() {
        int i,j;
        id[0]=tot=1;
        q.push(0);
        while(!q.empty()) {
            int u=q.front();q.pop();
            for(i=0;i<27;++i) {
                if(Trie::t[u].ch.count(i)) {
                    int v=Trie::t[u].ch[i];
                    q.push(v);
                    id[v]=extend(id[u],i,Trie::t[v].dfn);
                }
            }
        }
        for(i=1;i<=tot;++i) tax[i]=0;
        for(i=1;i<=tot;++i) ++tax[t[i].len];
        for(i=1;i<=tot;++i) tax[i]+=tax[i-1];
        for(i=1;i<=tot;++i) rk[tax[t[i].len]--]=i;
        for(i=tot;i>1;--i) {
            int u=rk[i];
            int ff=t[u].pre;
            if(ff>1)
                rt[ff]=seg::merge(1,Trie::tim,rt[u],rt[ff],0);
        }
    }
};
void solve(int x) {
    int p=1,i,len=strlen(S+1),re=0;
    for(i=1;i<=len;++i) {
        int c=S[i]-'a';
        if(SAM::t[p].ch.count(c))
            p=SAM::t[p].ch[c];
        else {
            printf("0\n");
            return;
        }
    }
    for(x=Trie::id[x];x;x=Trie::t[Trie::t[x].top].fa) {
        re+=seg::query(rt[p],1,Trie::tim,Trie::t[Trie::t[x].top].dfn,Trie::t[x].dfn);
    }
    printf("%d\n",re);
}
int main() {
    int i,j;
    // setIO("input");
    scanf("%d",&n);
    for(i=1;i<=n;++i) {
        int op,lst=0;
        char str[3];
        scanf("%d",&op);
        if(op==2) scanf("%d",&lst),lst=Trie::id[lst];
        scanf("%s",str);
        if(!Trie::t[lst].ch.count(str[0]-'a')) {
            Trie::t[lst].ch[str[0]-'a']=i;
            Trie::id[i]=i;
        }
        else Trie::id[i]=Trie::t[lst].ch[str[0]-'a'];
    }
    Trie::build_tree();
    SAM::construct();
    scanf("%d",&m);
    for(i=1;i<=m;++i)
        scanf("%d%s",&j,S+1), solve(j);
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 5e5;
typedef long long ll;

int trie[N][26], tot = 1;
vector<int> g[N];
int in[N], out[N], cur;

void dfsAC(int u) {
    in[u] = ++cur;
    for (auto v:g[u])dfsAC(v);
    out[u] = cur;
}

int insert(string &s) {
    int p = 1;
    for (char k : s) {
        int ch = k - 'a';
        if (trie[p][ch] == 0) trie[p][ch] = ++tot;
        p = trie[p][ch];
    }
    return p;
}

int fail[N];

void build() {
    for (int i = 0; i < 26; ++i) trie[0][i] = 1;
    queue<int> q;
    q.push(1);
    int u;
    while (!q.empty()) {
        u = q.front(), q.pop();
        for (int i = 0; i < 26; ++i) {
            if (trie[u][i])fail[trie[u][i]] = trie[fail[u]][i], q.push(trie[u][i]);
            else trie[u][i] = trie[fail[u]][i];
        }
    }
    for (int i = 2; i <= tot; i++)g[fail[i]].push_back(i);
    dfsAC(1);
}

string t[N];
ll cnt[N];
int match[N];

int n, q;
int op[N], x;
char a[N];
vector<int> g1[N];
vector<int> g2[N];

ll BIT[N];

ll sum(int x) {
    ll sum = 0;
    for (; x != 0; x -= x & (-x))sum += BIT[x];
    return sum;
}

void update(int x, int n, int num) {
    for (; x <= n; x += x & (-x)) BIT[x] += num;
}

void dfs(int u, char k, int p) {
    p = trie[p][k - 'a'];
    update(in[p], cur, 1);
    for (auto v:g1[u])dfs(v, a[v], p);
    for (auto v:g2[u])cnt[v] += sum(out[match[v]]) - sum(in[match[v]] - 1);
    update(in[p], N - 1, -1);
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> op[i];
        if (op[i] == 2) {
            cin >> x;
            g1[x].push_back(i);
        }
        cin >> a[i];
    }
    cin >> q;
    for (int i = 1; i <= q; i++) {
        cin >> x >> t[i];
        match[i] = insert(t[i]);
        g2[x].push_back(i);
    }
    build();
    for (int i = 1; i <= n; i++)
        if (op[i] == 1)dfs(i, a[i], 1);
    for (int i = 1; i <= q; i++)cout << cnt[i] << endl;
}


#include <bits/stdc++.h>

using namespace std;
const int N = 5e5;
typedef long long ll;

int trie[N][26], tot = 1;
vector<int> g[N];
int in[N], out[N], cur;

void dfsAC(int u) {
    in[u] = ++cur;
    for (auto v:g[u])dfsAC(v);
    out[u] = cur;
}

int insert(string &s) {
    int p = 1;
    for (char k : s) {
        int ch = k - 'a';
        if (trie[p][ch] == 0) trie[p][ch] = ++tot;
        p = trie[p][ch];
    }
    return p;
}

int fail[N];

void build() {
    for (int i = 0; i < 26; ++i) trie[0][i] = 1;
    queue<int> q;
    q.push(1);
    int u;
    while (!q.empty()) {
        u = q.front(), q.pop();
        for (int i = 0; i < 26; ++i) {
            if (trie[u][i])fail[trie[u][i]] = trie[fail[u]][i], q.push(trie[u][i]);
            else trie[u][i] = trie[fail[u]][i];
        }
    }
    for (int i = 2; i <= tot; i++)g[fail[i]].push_back(i);
    dfsAC(1);
}

string t[N];
ll cnt[N];
int match[N];

int n, q;
int op[N], x;
char a[N];
vector<int> g1[N];
vector<int> g2[N];

ll BIT[N];

ll sum(int x) {
    ll sum = 0;
    for (; x != 0; x -= x & (-x))sum += BIT[x];
    return sum;
}

void update(int x, int n, int num) {
    for (; x <= n; x += x & (-x)) BIT[x] += num;
}

void dfs(int u, char k, int p) {
    p = trie[p][k - 'a'];
    update(in[p], cur, 1);
    for (auto v:g1[u])dfs(v, a[v], p);
    for (auto v:g2[u])cnt[v] += sum(out[match[v]]) - sum(in[match[v]] - 1);
    update(in[p], N - 1, -1);
}

int main() {
    ios::sync_with_stdio(0), cin.tie(0);
    cin >> n;
    for (int i = 1; i <= n; i++) {
        cin >> op[i];
        if (op[i] == 2) {
            cin >> x;
            g1[x].push_back(i);
        }
        cin >> a[i];
    }
    cin >> q;
    for (int i = 1; i <= q; i++) {
        cin >> x >> t[i];
        match[i] = insert(t[i]);
        g2[x].push_back(i);
    }
    build();
    for (int i = 1; i <= n; i++)
        if (op[i] == 1)dfs(i, a[i], 1);
    for (int i = 1; i <= q; i++)cout << cnt[i] << "\n";
}


/*input

*/

#include <iostream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cassert>
#include <algorithm>
#include <cstdlib>
#include <numeric>
#include <climits>
#include <fstream>
#include <bitset>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>

using namespace std;

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORA(i, a) for (auto &i : a)
#define FORB(i, a, b) for (int i = a; i >= b; --i)
#define SZ(a) ((int) a.size())
#define ALL(a) begin(a), end(a)

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define fi first
#define se second

// start of code

const int MAXN = 400050;

int strTrie[MAXN][26];
int strNode[MAXN], strPtr = 1;

int patTrie[MAXN][26];
bool hasQuery[MAXN];
vector<int> flags[MAXN];
int prv[MAXN], prvPtr = 1;

int queryMap[MAXN];
vector<int> queries[MAXN];

int N, M, ans[MAXN];

int addStr(string str)
{
	int cur = 1;
	FORA(_, str) {
		int ch = _ - 'a';
		cur = (patTrie[cur][ch] ? patTrie[cur][ch] : (patTrie[cur][ch] = ++prvPtr));
	}
	return cur;
}

pii tmp[MAXN << 1];
int qu[MAXN], fr, rr;
void initPrv()
{
	fr = 0, rr = 0;
	qu[++rr] = 1;
	while (fr < rr) {
		int u = qu[++fr];
		FOR(ch, 0, 25) if (patTrie[u][ch]) {
			int v = prv[u], child = patTrie[u][ch];
			for (; v > 1 && !patTrie[v][ch]; v = prv[v]);
			prv[child] = (patTrie[v][ch] ? patTrie[v][ch] : 1);
			qu[++rr] = child;

			flags[child] = flags[prv[child]];
			// cout << u << " -> " << child << ": " << char(ch + 'a') << " - ";
			if (hasQuery[child]) flags[child].push_back(child);

			// cout << endl;
			// FORA(x, flags[child]) cout << '(' << x.fi << ", " << x.se << ") ";
			// cout << endl;
		}
	}
}

int curCnt[MAXN];
void dfs(int strU, int patU)
{
	// cout << "dfs + " << strU << ' ' << patU << endl;
	FORA(x, flags[patU]) ++curCnt[x];

	FORA(q, queries[strU]) {
		ans[q] = curCnt[queryMap[q]];
		// cout << q << ": " << queryMap[q] << ' ' << ans[q] << endl;
	}

	int pending = 0;
	FOR(ch, 0, 25) if (strTrie[strU][ch]) pending ^= (1 << ch);
	for (; pending > 0 && patU > 0; patU = prv[patU]) {
		FOR(ch, 0, 25) if (((pending >> ch) & 1) && patTrie[patU][ch]) {
			dfs(strTrie[strU][ch], patTrie[patU][ch]);
			pending ^= (1 << ch);
		}
	}
	FOR(ch, 0, 25) if ((pending >> ch) & 1) dfs(strTrie[strU][ch], 1);

	FORA(x, flags[patU]) --curCnt[x];
	// cout << "dfs - " << strU << ' ' << patU << endl;
}

signed main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> N;
	FOR(i, 1, N) {
		int type; cin >> type;
		char ch;
		int u;
		if (type == 1) {
			cin >> ch;
			u = 1;
		} else {
			cin >> u >> ch;
			u = strNode[u];
		}
		int id = ch - 'a';
		strNode[i] = (strTrie[u][id] ? strTrie[u][id] : (strTrie[u][id] = ++strPtr));

	}

	cin >> M;
	FOR(q, 1, M) {
		int i; string str;
		cin >> i >> str;
		hasQuery[queryMap[q] = addStr(str)] = 1;
		queries[strNode[i]].emplace_back(q);
	}

	initPrv();
	dfs(1, 1);
	FOR(q, 1, M) cout << ans[q] << '\n';

	return 0;
}


/*input

*/

#include <iostream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cassert>
#include <algorithm>
#include <cstdlib>
#include <numeric>
#include <climits>
#include <fstream>
#include <bitset>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>

using namespace std;

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORA(i, a) for (auto &i : a)
#define FORB(i, a, b) for (int i = a; i >= b; --i)
#define SZ(a) ((int) a.size())
#define ALL(a) begin(a), end(a)

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define fi first
#define se second

// start of code

const int MAXN = 400050;

int strTrie[MAXN][26];
int strNode[MAXN], strPtr = 1;

int patTrie[MAXN][26];
bool hasQuery[MAXN];
vector<pii> flags[MAXN];
int prv[MAXN], prvPtr = 1;

int queryMap[MAXN];
vector<int> queries[MAXN];

int N, M, ans[MAXN];

int addStr(string str)
{
	int cur = 1;
	FORA(_, str) {
		int ch = _ - 'a';
		cur = (patTrie[cur][ch] ? patTrie[cur][ch] : (patTrie[cur][ch] = ++prvPtr));
	}
	return cur;
}

pii tmp[MAXN << 1];
int qu[MAXN], fr, rr;
void initPrv()
{
	fr = 0, rr = 0;
	qu[++rr] = 1;
	while (fr < rr) {
		int u = qu[++fr];
		FOR(ch, 0, 25) if (patTrie[u][ch]) {
			int v = prv[u], child = patTrie[u][ch];
			for (; v > 1 && !patTrie[v][ch]; v = prv[v]);
			prv[child] = (patTrie[v][ch] ? patTrie[v][ch] : 1);
			qu[++rr] = child;

			flags[child] = flags[prv[child]];
			// cout << u << " -> " << child << ": " << char(ch + 'a') << " - ";
			if (hasQuery[child]) {
				auto it = lower_bound(flags[child].begin(), flags[child].end(), pii(child, 1));
				if (it != flags[child].end() && it->fi == child) ++(it->se);
				else flags[child].insert(it, pii(child, 1));
			}

			// cout << endl;
			// FORA(x, flags[child]) cout << '(' << x.fi << ", " << x.se << ") ";
			// cout << endl;
		}
	}
}

int curCnt[MAXN];
void dfs(int strU, int patU)
{
	// cout << "dfs + " << strU << ' ' << patU << endl;
	FORA(x, flags[patU]) curCnt[x.fi] += x.se;

	FORA(q, queries[strU]) {
		ans[q] = curCnt[queryMap[q]];
		// cout << q << ": " << queryMap[q] << ' ' << ans[q] << endl;
	}

	int doneMask = 0;
	FOR(ch, 0, 25) if (!strTrie[strU][ch]) doneMask ^= (1 << ch);
	for (; doneMask != (1 << 26) - 1 && patU > 0; patU = prv[patU]) {
		FOR(ch, 0, 25) if (!((doneMask >> ch) & 1) && patTrie[patU][ch]) {
			dfs(strTrie[strU][ch], patTrie[patU][ch]);
			doneMask ^= (1 << ch);
		}
	}
	FOR(ch, 0, 25) if (!((doneMask >> ch) & 1)) dfs(strTrie[strU][ch], 1);

	FORA(x, flags[patU]) curCnt[x.fi] -= x.se;
	// cout << "dfs - " << strU << ' ' << patU << endl;
}

signed main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> N;
	FOR(i, 1, N) {
		int type; cin >> type;
		char ch;
		int cur, u;
		if (type == 1) {
			cin >> ch;
			u = 1;
		} else {
			cin >> u >> ch;
			u = strNode[u];
		}
		int id = ch - 'a';
		cur = (strTrie[u][id] ? strTrie[u][id] : (strTrie[u][id] = ++strPtr));
		strNode[i] = cur;
	}

	cin >> M;
	FOR(q, 1, M) {
		int i; string str;
		cin >> i >> str;
		int j = addStr(str);
		hasQuery[queryMap[q] = j] = 1;
		queries[strNode[i]].emplace_back(q);
	}

	initPrv();
	dfs(1, 1);
	FOR(q, 1, M) cout << ans[q] << '\n';

	return 0;
}


/*input

*/

#include <iostream>
#include <vector>
#include <cstdio>
#include <cmath>
#include <cstring>
#include <string>
#include <cassert>
#include <algorithm>
#include <cstdlib>
#include <numeric>
#include <climits>
#include <fstream>
#include <bitset>
#include <map>
#include <unordered_map>
#include <set>
#include <unordered_set>
#include <queue>

using namespace std;

#define FOR(i, a, b) for (int i = a; i <= b; ++i)
#define FORA(i, a) for (auto &i : a)
#define FORB(i, a, b) for (int i = a; i >= b; --i)
#define SZ(a) ((int) a.size())
#define ALL(a) begin(a), end(a)

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<ll> vl;
#define fi first
#define se second

// start of code

const int MAXN = 400050;

int strTrie[MAXN][26];
int strNode[MAXN], strPtr = 1;

int patTrie[MAXN][26];
bool hasQuery[MAXN];
vector<int> flags[MAXN];
int prv[MAXN], prvPtr = 1;

int queryMap[MAXN];
vector<int> queries[MAXN];

int N, M, ans[MAXN];

int addStr(string str)
{
	int cur = 1;
	FORA(_, str) {
		int ch = _ - 'a';
		cur = (patTrie[cur][ch] ? patTrie[cur][ch] : (patTrie[cur][ch] = ++prvPtr));
	}
	return cur;
}

pii tmp[MAXN << 1];
int qu[MAXN], fr, rr;
void initPrv()
{
	fr = 0, rr = 0;
	qu[++rr] = 1;
	while (fr < rr) {
		int u = qu[++fr];
		FOR(ch, 0, 25) if (patTrie[u][ch]) {
			int v = prv[u], child = patTrie[u][ch];
			for (; v > 1 && !patTrie[v][ch]; v = prv[v]);
			prv[child] = (patTrie[v][ch] ? patTrie[v][ch] : 1);
			qu[++rr] = child;

			flags[child] = flags[prv[child]];
			// cout << u << " -> " << child << ": " << char(ch + 'a') << " - ";
			if (hasQuery[child]) flags[child].push_back(child);

			// cout << endl;
			// FORA(x, flags[child]) cout << '(' << x.fi << ", " << x.se << ") ";
			// cout << endl;
		}
	}
}

int curCnt[MAXN];
void dfs(int strU, int patU)
{
	// cout << "dfs + " << strU << ' ' << patU << endl;
	FORA(x, flags[patU]) ++curCnt[x];

	FORA(q, queries[strU]) {
		ans[q] = curCnt[queryMap[q]];
		// cout << q << ": " << queryMap[q] << ' ' << ans[q] << endl;
	}

	int pending = 0;
	FOR(ch, 0, 25) if (strTrie[strU][ch]) pending ^= (1 << ch);
	for (int u = patU; pending > 0 && u > 0; u = prv[u]) {
		FOR(ch, 0, 25) if (((pending >> ch) & 1) && patTrie[u][ch]) {
			dfs(strTrie[strU][ch], patTrie[u][ch]);
			pending ^= (1 << ch);
		}
	}
	FOR(ch, 0, 25) if ((pending >> ch) & 1) dfs(strTrie[strU][ch], 1);

	FORA(x, flags[patU]) --curCnt[x];
	// cout << "dfs - " << strU << ' ' << patU << endl;
}

signed main()
{
	ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	cin >> N;
	FOR(i, 1, N) {
		int type; cin >> type;
		char ch;
		int u;
		if (type == 1) {
			cin >> ch;
			u = 1;
		} else {
			cin >> u >> ch;
			u = strNode[u];
		}
		int id = ch - 'a';
		strNode[i] = (strTrie[u][id] ? strTrie[u][id] : (strTrie[u][id] = ++strPtr));

	}

	cin >> M;
	FOR(q, 1, M) {
		int i; string str;
		cin >> i >> str;
		hasQuery[queryMap[q] = addStr(str)] = 1;
		queries[strNode[i]].emplace_back(q);
	}

	initPrv();
	dfs(1, 1);
	FOR(q, 1, M) cout << ans[q] << '\n';

	return 0;
}


#include <bits/stdc++.h>
#define long long long
#define left(i) (2*(i)+1)
#define right(i) (2*(i)+2)
#define parent(i) (((i)-1)/2)

using namespace std;

const int segSize = 1 << 19;
const int segArraySize = 2*segSize-1;
int seg[segArraySize];

int segQuery(int a, int b, int i = 0, int l = 0, int r = segSize-1) {
    if (a > r || b < l) return 0;
    if (a <= l && b >= r) return seg[i];
    int m = (l + r) / 2;
    return segQuery(a, b, left(i), l, m) + segQuery(a, b, right(i), m+1, r);
}

void segUpdate(int i) {
    seg[i] = seg[left(i)] + seg[right(i)];
    if (i != 0) segUpdate(parent(i));
}

int n, m;
map<char, vector<int>> tri[400001];
vector<map<char,int>> trie { map<char,int>() };
vector<map<char,int>> fail { map<char,int>() };
vector<int> mark { -1 };
vector<string> v;
vector<pair<string, int>> q[400001];
int res[400000];

int getFail(int ac, char c) {
    if (fail[ac].count(c)) return fail[ac][c];
    fail[ac][c] = ac;
    while (trie[fail[ac][c]].count(c) == 0 && fail[ac][c])
        fail[ac][c] = trie[fail[ac][c]]['*'];
    if (trie[fail[ac][c]].count(c)) fail[ac][c] = trie[fail[ac][c]][c];
    return fail[ac][c];
}

void search(int i, int cur) {
    //cout << i << " " << cur << "\n";
    int r = mark[cur] != -1 ? mark[cur] : mark[trie[cur]['+']];
    if (r != -1) {
        seg[segSize-1+r]++;
        segUpdate(parent(segSize-1+r));
    }
    if (i) for (auto a : q[i]) {
        string t = a.first; int pos = a.second;
        int s = lower_bound(v.begin(), v.end(), t)-v.begin();
        t.back()++;
        int e = lower_bound(v.begin(), v.end(), t)-v.begin()-1;
        res[pos] = segQuery(s, e);
    }
    for (auto a : tri[i]) for (int j : a.second) {
        search(j, getFail(cur, a.first));
    }
    if (r != -1) {
        seg[segSize-1+r]--;
        segUpdate(parent(segSize-1+r));
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        int t; cin >> t;
        if (t == 1) {
            char c; cin >> c;
            tri[0][c].push_back(i);
        } else {
            int j; char c; cin >> j >> c;
            tri[j][c].push_back(i);
        }
    }
    cin >> m;
    for (int i = 0; i < m; ++i) {
        int j; string t; cin >> j >> t;
        reverse(t.begin(), t.end());
        v.push_back(t);
        q[j].push_back({t, i});
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    for (int i = 0; i < v.size(); ++i) {
        string t = v[i];
        reverse(t.begin(), t.end());

        int cn = 0;
        for( int j = 0; j < t.size(); ++j ) {
            if( !trie[ cn ].count( t[ j ] ) ) {
                trie[ cn ][ t[ j ] ] = mark.size();
                trie.push_back( map<char,int>() );
                fail.push_back( map<char,int>() );
                mark.push_back( -1 );
            }
            cn = trie[ cn ][ t[ j ] ];
        }
        mark[ cn ] = i;
    }
    trie[0]['*'] = 0;
    trie[0]['+'] = 0;
	queue<int> q;
	for( auto i : trie[ 0 ] )
		if( i.first != '*' && i.first != '+' ) {
			q.push( i.second );
			trie[ i.second ][ '*' ] = 0;
            trie[i.second]['+'] = 0;
		}
	while( !q.empty() ) {
		int ac = q.front(); q.pop();
		for( auto i : trie[ ac ] ) {
			if( i.first == '*' || i.first == '+' ) continue;
			q.push( i.second );

			int v = trie[ ac ][ '*' ];
			while( !trie[ v ].count( i.first ) && v )
				v = trie[ v ][ '*' ];
			trie[ i.second ][ '*' ] = trie[ v ][ i.first ];

            v = trie[ac]['+'];
            while ((!trie[v].count(i.first) || mark[trie[v][i.first]] == -1) && v)
                v = trie[v]['+'];
            trie[i.second]['+'] = trie[v][i.first];
		}
	}

    search(0, 0);

    for (int i = 0; i < m; ++i) cout << res[i] << "\n";
}


#include <bits/stdc++.h>
#define long long long
#define left(i) (2*(i)+1)
#define right(i) (2*(i)+2)
#define parent(i) (((i)-1)/2)

using namespace std;

const int segSize = 8;
const int segArraySize = 2*segSize-1;
int seg[segArraySize];

int segQuery(int a, int b, int i = 0, int l = 0, int r = segSize-1) {
    if (a > r || b < l) return 0;
    if (a <= l && b >= r) return seg[i];
    int m = (l + r) / 2;
    return segQuery(a, b, left(i), l, m) + segQuery(a, b, right(i), m+1, r);
}

void segUpdate(int i) {
    seg[i] = seg[left(i)] + seg[right(i)];
    if (i != 0) segUpdate(parent(i));
}

int n, m;
map<char, vector<int>> tri[400001];
vector<map<char,int>> trie { map<char,int>() };
vector<map<char,int>> fail { map<char,int>() };
vector<int> mark { -1 };
vector<string> v;
vector<pair<string, int>> q[400001];
int res[400000];

void search(int i, int cur) {
    //cout << i << " " << cur << "\n";
    int r = mark[cur] != -1 ? mark[cur] : mark[trie[cur]['+']];
    if (r != -1) {
        seg[segSize-1+r]++;
        segUpdate(parent(segSize-1+r));
    }
    if (i) for (auto a : q[i]) {
        string t = a.first; int pos = a.second;
        int s = lower_bound(v.begin(), v.end(), t)-v.begin();
        t.back()++;
        int e = lower_bound(v.begin(), v.end(), t)-v.begin()-1;
        res[pos] = segQuery(s, e);
    }
    for (auto a : tri[i]) for (int j : a.second) {
        search(j, fail[cur][a.first]);
    }
    if (r != -1) {
        seg[segSize-1+r]--;
        segUpdate(parent(segSize-1+r));
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        int t; cin >> t;
        if (t == 1) {
            char c; cin >> c;
            tri[0][c].push_back(i);
        } else {
            int j; char c; cin >> j >> c;
            tri[j][c].push_back(i);
        }
    }
    cin >> m;
    for (int i = 0; i < m; ++i) {
        int j; string t; cin >> j >> t;
        reverse(t.begin(), t.end());
        v.push_back(t);
        q[j].push_back({t, i});
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    for (int i = 0; i < v.size(); ++i) {
        string t = v[i];
        reverse(t.begin(), t.end());

        int cn = 0;
        for( int j = 0; j < t.size(); ++j ) {
            if( !trie[ cn ].count( t[ j ] ) ) {
                trie[ cn ][ t[ j ] ] = mark.size();
                trie.push_back( map<char,int>() );
                fail.push_back( map<char,int>() );
                mark.push_back( -1 );
            }
            cn = trie[ cn ][ t[ j ] ];
        }
        mark[ cn ] = i;
    }
    trie[0]['*'] = 0;
    trie[0]['+'] = 0;
	queue<int> q;
	for( auto i : trie[ 0 ] )
		if( i.first != '*' && i.first != '+' ) {
			q.push( i.second );
			trie[ i.second ][ '*' ] = 0;
            trie[i.second]['+'] = 0;
		}
	while( !q.empty() ) {
		int ac = q.front(); q.pop();
		for( auto i : trie[ ac ] ) {
			if( i.first == '*' || i.first == '+' ) continue;
			q.push( i.second );

			int v = trie[ ac ][ '*' ];
			while( !trie[ v ].count( i.first ) && v )
				v = trie[ v ][ '*' ];
			trie[ i.second ][ '*' ] = trie[ v ][ i.first ];

            v = trie[ac]['+'];
            while ((!trie[v].count(i.first) || mark[trie[v][i.first]] == -1) && v)
                v = trie[v]['+'];
            trie[i.second]['+'] = trie[v][i.first];
		}
	}
    for (int ac = 0; ac < trie.size(); ++ac)
        for (char c = 'a'; c <= 'z'; ++c) {
            fail[ac][c] = ac;
            while (trie[fail[ac][c]].count(c) == 0 && fail[ac][c])
                fail[ac][c] = trie[fail[ac][c]]['*'];
            if (trie[fail[ac][c]].count(c)) fail[ac][c] = trie[fail[ac][c]][c];
        }

    search(0, 0);

    for (int i = 0; i < m; ++i) cout << res[i] << "\n";
}


#include <bits/stdc++.h>
#define long long long
#define left(i) (2*(i)+1)
#define right(i) (2*(i)+2)
#define parent(i) (((i)-1)/2)

using namespace std;

const int segSize = 1 << 19;
const int segArraySize = 2*segSize-1;
int seg[segArraySize];

int segQuery(int a, int b, int i = 0, int l = 0, int r = segSize-1) {
    if (a > r || b < l) return 0;
    if (a <= l && b >= r) return seg[i];
    int m = (l + r) / 2;
    return segQuery(a, b, left(i), l, m) + segQuery(a, b, right(i), m+1, r);
}

void segUpdate(int i) {
    seg[i] = seg[left(i)] + seg[right(i)];
    if (i != 0) segUpdate(parent(i));
}

int n, m;
map<char, vector<int>> tri[400001];
vector<map<char,int>> trie { map<char,int>() };
vector<map<char,int>> fail { map<char,int>() };
vector<int> mark { -1 };
vector<string> v;
vector<pair<string, int>> q[400001];
int res[400000];

int getFail(int ac, char c) {
    if (fail[ac].count(c)) return fail[ac][c];
    fail[ac][c] = ac;
    while (trie[fail[ac][c]].count(c) == 0 && fail[ac][c])
        fail[ac][c] = trie[fail[ac][c]]['*'];
    if (trie[fail[ac][c]].count(c)) fail[ac][c] = trie[fail[ac][c]][c];
    return fail[ac][c];
}

void search(int i, int cur) {
    //cout << i << " " << cur << "\n";
    int r = mark[trie[cur]['+']];
    if (r != -1) {
        seg[segSize-1+r]++;
        segUpdate(parent(segSize-1+r));
    }
    if (i) for (auto a : q[i]) {
        string t = a.first; int pos = a.second;
        int s = lower_bound(v.begin(), v.end(), t)-v.begin();
        t.back()++;
        int e = lower_bound(v.begin(), v.end(), t)-v.begin()-1;
        res[pos] = segQuery(s, e);
    }
    for (auto a : tri[i]) for (int j : a.second) {
        search(j, getFail(cur, a.first));
    }
    if (r != -1) {
        seg[segSize-1+r]--;
        segUpdate(parent(segSize-1+r));
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        int t; cin >> t;
        if (t == 1) {
            char c; cin >> c;
            tri[0][c].push_back(i);
        } else {
            int j; char c; cin >> j >> c;
            tri[j][c].push_back(i);
        }
    }
    cin >> m;
    for (int i = 0; i < m; ++i) {
        int j; string t; cin >> j >> t;
        reverse(t.begin(), t.end());
        v.push_back(t);
        q[j].push_back({t, i});
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    for (int i = 0; i < v.size(); ++i) {
        string t = v[i];
        reverse(t.begin(), t.end());

        int cn = 0;
        for( int j = 0; j < t.size(); ++j ) {
            if( !trie[ cn ].count( t[ j ] ) ) {
                trie[ cn ][ t[ j ] ] = mark.size();
                trie.push_back( map<char,int>() );
                fail.push_back( map<char,int>() );
                mark.push_back( -1 );
            }
            cn = trie[ cn ][ t[ j ] ];
        }
        mark[ cn ] = i;
    }
    trie[0]['*'] = 0;
    trie[0]['+'] = 0;
	queue<int> q;
	for( auto i : trie[ 0 ] )
		if( i.first != '*' && i.first != '+' ) {
			q.push( i.second );
			trie[ i.second ][ '*' ] = 0;
		}
	while( !q.empty() ) {
		int ac = q.front(); q.pop();
		for( auto i : trie[ ac ] ) {
			if( i.first == '*' || i.first == '+' ) continue;
			q.push( i.second );

			int v = trie[ ac ][ '*' ];
			while( !trie[ v ].count( i.first ) && v )
				v = trie[ v ][ '*' ];
			trie[ i.second ][ '*' ] = trie[ v ][ i.first ];
		}
        if (mark[ac] != -1) trie[ac]['+'] = ac;
        else trie[ac]['+'] = trie[trie[ac]['*']]['+'];
	}

    search(0, 0);

    for (int i = 0; i < m; ++i) cout << res[i] << "\n";
}


#include <bits/stdc++.h>
#define long long long
#define left(i) (2*(i)+1)
#define right(i) (2*(i)+2)
#define parent(i) (((i)-1)/2)

using namespace std;

const int segSize = 1 << 19;
const int segArraySize = 2*segSize-1;
int seg[segArraySize];

int segQuery(int a, int b, int i = 0, int l = 0, int r = segSize-1) {
    if (a > r || b < l) return 0;
    if (a <= l && b >= r) return seg[i];
    int m = (l + r) / 2;
    return segQuery(a, b, left(i), l, m) + segQuery(a, b, right(i), m+1, r);
}

void segUpdate(int i) {
    seg[i] = seg[left(i)] + seg[right(i)];
    if (i != 0) segUpdate(parent(i));
}

int n, m;
map<char, vector<int>> tri[400001];
vector<map<char,int>> trie { map<char,int>() };
vector<map<char,int>> fail { map<char,int>() };
vector<int> mark { -1 };
vector<string> v;
vector<pair<string, int>> q[400001];
int res[400000];

void search(int i, int cur) {
    //cout << i << " " << cur << "\n";
    int r = mark[cur] != -1 ? mark[cur] : mark[trie[cur]['+']];
    if (r != -1) {
        seg[segSize-1+r]++;
        segUpdate(parent(segSize-1+r));
    }
    if (i) for (auto a : q[i]) {
        string t = a.first; int pos = a.second;
        int s = lower_bound(v.begin(), v.end(), t)-v.begin();
        t.back()++;
        int e = lower_bound(v.begin(), v.end(), t)-v.begin()-1;
        res[pos] = segQuery(s, e);
    }
    for (auto a : tri[i]) for (int j : a.second) {
        search(j, fail[cur][a.first]);
    }
    if (r != -1) {
        seg[segSize-1+r]--;
        segUpdate(parent(segSize-1+r));
    }
}

int main() {
    cin >> n;
    for (int i = 1; i <= n; ++i) {
        int t; cin >> t;
        if (t == 1) {
            char c; cin >> c;
            tri[0][c].push_back(i);
        } else {
            int j; char c; cin >> j >> c;
            tri[j][c].push_back(i);
        }
    }
    cin >> m;
    for (int i = 0; i < m; ++i) {
        int j; string t; cin >> j >> t;
        reverse(t.begin(), t.end());
        v.push_back(t);
        q[j].push_back({t, i});
    }
    sort(v.begin(), v.end());
    v.erase(unique(v.begin(), v.end()), v.end());

    for (int i = 0; i < v.size(); ++i) {
        string t = v[i];
        reverse(t.begin(), t.end());

        int cn = 0;
        for( int j = 0; j < t.size(); ++j ) {
            if( !trie[ cn ].count( t[ j ] ) ) {
                trie[ cn ][ t[ j ] ] = mark.size();
                trie.push_back( map<char,int>() );
                fail.push_back( map<char,int>() );
                mark.push_back( -1 );
            }
            cn = trie[ cn ][ t[ j ] ];
        }
        mark[ cn ] = i;
    }
    trie[0]['*'] = 0;
    trie[0]['+'] = 0;
	queue<int> q;
	for( auto i : trie[ 0 ] )
		if( i.first != '*' && i.first != '+' ) {
			q.push( i.second );
			trie[ i.second ][ '*' ] = 0;
            trie[i.second]['+'] = 0;
		}
	while( !q.empty() ) {
		int ac = q.front(); q.pop();
		for( auto i : trie[ ac ] ) {
			if( i.first == '*' || i.first == '+' ) continue;
			q.push( i.second );

			int v = trie[ ac ][ '*' ];
			while( !trie[ v ].count( i.first ) && v )
				v = trie[ v ][ '*' ];
			trie[ i.second ][ '*' ] = trie[ v ][ i.first ];

            v = trie[ac]['+'];
            while ((!trie[v].count(i.first) || mark[trie[v][i.first]] == -1) && v)
                v = trie[v]['+'];
            trie[i.second]['+'] = trie[v][i.first];
		}
	}
    for (int ac = 0; ac < trie.size(); ++ac)
        for (char c = 'a'; c <= 'z'; ++c) {
            fail[ac][c] = ac;
            while (trie[fail[ac][c]].count(c) == 0 && fail[ac][c])
                fail[ac][c] = trie[fail[ac][c]]['*'];
            if (trie[fail[ac][c]].count(c)) fail[ac][c] = trie[fail[ac][c]][c];
        }

    search(0, 0);

    for (int i = 0; i < m; ++i) cout << res[i] << "\n";
}


#include <algorithm>
// #include <cstdlib>
#include <cstring>
#include <cstdio>
#include <string>
#include <queue>
#include <cmath>
#include <set>
#include <map>
#include <bitset>
#include <ctime>
using namespace std;
typedef long long LL;
typedef double db;
const int oo=2139063143;
const int N=1010000;
const int P=1000000007;
const db eps=1e-7;
#define pritnf printf
//char buf[1<<20|1],*p1=buf,*p2=buf,obuf[1<<20|1],*O=obuf;
//#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<20,stdin),p1==p2)?EOF:*p1++)
template <typename T>
inline void sc (T &x)
{
    x=0; static int p; p=1; static char c; c=getchar();
    while (!isdigit(c)) { if (c=='-') p=-1; c=getchar(); }
    while ( isdigit(c)) { x=(x<<1)+(x<<3)+(c-48); c=getchar(); }
    x*=p;
}
template <typename T>
inline void print (T x)
{
    if (x< 0) putchar('-'),x=-x;
    if (x>=10) print(x/10);
    putchar(x%10+'0');
}
template <typename T>
inline void pr (T x) { print(x),putchar('\n'); }
template <typename T1,typename T2>
void chkmax (T1 &A,T2 B) { A=A>=B?A:B; }
template <typename T1,typename T2>
void chkmin (T1 &A,T2 B) { A=A<=B?A:B; }
struct ACAM { int son[27],fa; }t[N]; int totp=1;
#define son(p) t[p].son
#define fa(p) t[p].fa
int pos[N];
void ins (char *s,int n,int id)
{
	int p=1;
	for (int i=1; i<=n; i++)
	{
		int &v=son(p)[s[i]-'a'];
		if (!v) v=++totp;
		p=v;
	}
	pos[id]=p;
}
#define pb push_back
vector <int> F[N];
void build ()
{
	queue <int> q;
	for (int c=0; c< 26; c++)
	{
		int &v=son(1)[c];
		if (!v) v=1;
		else fa(v)=1,q.push (v);
	}
	while (q.size ())
	{
		int u=q.front (),f=fa(u); q.pop ();
		F[f].pb (u);
		for (int c=0; c< 26; c++)
		{
			int &v=son(u)[c];
			if (!v) v=son(f)[c];
			else fa(v)=son(f)[c],q.push (v);
		}
	}
}
int dfn[N],low[N];
void dfs0 (int u)
{
	dfn[u]=++dfn[0];
	for (int v:F[u])
		dfs0 (v);
	low[u]=dfn[0];
}
struct EDGE { int v,w,nx; }lb[N]; int top[N],tote=1;
void adde (int u,int v,int w) { lb[++tote]=(EDGE){v,w,top[u]},top[u]=tote; }
int bit[N];
void add (int x,int d) { for (; x<=totp; x+=x&-x) bit[x]+=d; }
int query (int x) { int ans=0; for (; x; x-=x&-x) ans+=bit[x]; return ans; }
vector <int> Q[N];
int ans[N];
void dfs1 (int u,int p)
{
	add (dfn[p],1);
	for (int i:Q[u])
		ans[i]=query (low[pos[i]])-query (dfn[pos[i]]-1);
	for (int kb=top[u]; kb; kb=lb[kb].nx)
		dfs1 (lb[kb].v,son(p)[lb[kb].w]);
	add (dfn[p],-1);
}
char s[N];
int main ()
{
    // freopen (".in","r",stdin);
    // freopen (".out","w",stdout);
	int n; sc(n);
	for (int i=1; i<=n; i++)
	{
		int op,f=n+1; sc(op);
		if (op==2) sc(f);
		char w[3]; scanf ("%s",w);
		adde (f,i,w[0]-'a');
	}
	int m; sc(m);
	for (int i=1; i<=m; i++)
	{
		int id; sc(id);
		scanf ("%s",s+1);
		ins (s,strlen (s+1),i);
		Q[id].pb (i);
	}
	build ();
	dfs0 (1);
	dfs1 (n+1,1);
	for (int i=1; i<=m; i++)
		pr(ans[i]);

    return 0;
}


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

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

	Node(void): path(26,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<bits/stdc++.h>
using namespace std;

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

	Node(void): path(26,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+5);

	solve(0,0);

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

	return 0;
}


#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(ah.t.size());
	for(int v=1;v<ah.t.size();v++)
		g[ah.t[v].s].path.push_back(v);

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

	solve(0,0);

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

	return 0;
}