#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
vector <pair <int, string>> child[MAXN];
struct node {
    vector <pair <node * , char>> child;
} * pointer[MAXN];
node * add(node * v, string & s) {
    if (s.empty())
        return v;
    node * next = new node;
    v -> child.push_back({next, s.back()});
    s.pop_back();
    return add(next, s);
}
void build(int v) {
    for (auto i : child[v]) {
        reverse(i.second.begin(), i.second.end());
        pointer[i.first] = add(pointer[v], i.second);
        build(i.first);
    }
}
string t;
int ts;
int f[MAXN], cnt;
void dfs(node * v, char now, int p) {
    while(~p && t[p] != now)
        p = (p ? f[p - 1] : -1);
    ++p;
    cnt += p == ts;
    for (auto i : v -> child)
        dfs(i.first, i.second, p);
}
int main () {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    pointer[1] = new node;
    int n, a1;
    string a2;
    cin >> n;
    for (int i = 2; i <= n; ++i) {
        cin >> a1 >> a2;
        child[a1].push_back({i, a2});
    }
    build(1);
    cin >> t;
    ts = t.size();
    t += "!";
    int p = f[0] = 0;
    for (int i = 1; i <= ts; ++i) {
        while(~p && t[p] != t[i])
            p = (p ? f[p - 1] : -1);
        f[i] = ++p;
    }
    dfs(pointer[1], '?', 0);
    cout << cnt;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
const int MAXN = 3e5 + 10;
struct node {
    vector <node *> child[30];
};
node * point[MAXN];
vector <pair <int, string>>child[MAXN];
node * make(node * now, string& s) {
    if (s.empty())
        return now;
    node * next = new node;
    now -> child[s.back() - 'a'].push_back(next);
    s.pop_back();
    return make(next, s);
}
void build (int v) {
    for (auto i : child[v]) {
        reverse(i.second.begin(), i.second.end());
        point[i.first] = make(point[v], i.second);
        build(i.first);
    }
}
int f[MAXN], cnt, ps;
string pattern;
void dfs(node * v, int now) {
    // cout << now << ' ';
    cnt += (now == ps);
    for (int i = 0; i + 'a' <= 'z'; ++i)
        if (!v -> child[i].empty()) {
            int p = now;
            while(~p && pattern[p] != i + 'a')
                p = (p ? f[p - 1] : -1);
            ++p;
            for (auto j : v -> child[i])
                dfs(j, p);
        }
}
int main () {
    ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
    int n, a1;
    string a2;
    cin >> n;
    for (int i = 2; i <= n; ++i) {
        cin >> a1 >> a2;
        child[a1].push_back({i, a2});
    }
    point[1] = new node;
    build(1);
    cin >> pattern;
    ps = pattern.size();
    pattern.push_back('!');
    int p = 0;
    for (int i = 1; i < ps; ++i) {
        while(~p && pattern[i] != pattern[p])
            p = (p ? f[p - 1] : -1);
        f[i] = ++p;
    }
    dfs(point[1], 0);
    cout << cnt;
    return 0;
}


#include<bits/stdc++.h>
using namespace std ;
const int maxn = 3* 1e5 + 10 , D = 313 , mod = 1e9 + 7;
#define se second
#define fi first
#define ll long long
ll hsh[maxn] ,  n , ht, ans, tz , p[maxn]  ;
string t , s[maxn]  ;
vector < pair < int , int > > nei[maxn] ;
void find_p()
{
	p[0] = 1 ;
	for ( int i = 1 ;i<maxn ; i++)
		p[i] = (p[i-1] * D) % mod ;
}
ll get_hash ( int st , int en )
{
	return ( (hsh[en] - hsh[st] * p[en-st])%mod + mod ) %mod ;
}
void st_hash()
{
	for ( int i= 0; i<tz ; i++)
		hsh[i+1] =	( (hsh[i] * D )+ t[i] )% mod ;
	ht = hsh[tz] ;
	memset ( hsh , 0 , sizeof hsh );
}
void dfs(int v , int par , int ptr  )
{
	//cout << " v par ptr " << v << "  " << par << " " << ptr << endl;
   	for ( auto u : nei[v] )
		if ( u.fi != par )
		{
			for ( auto i : s[u.se] )
			{
				hsh[ptr+1] = ((hsh[ptr]*D)+ i ) %mod ;
				ptr++ ;
				if ( ptr-tz >= 0 &&   get_hash ( ptr- tz, ptr ) == ht )
					ans ++ ;
			}
			dfs ( u.fi , v , ptr ) ;
			ptr -= (int)s[u.se].size() ;
		}
}
int main()
{
	ios::sync_with_stdio(0) , cout.tie(0) , cin.tie(0) ;
	int a ; string b ;
	cin >> n ;
	for ( int i = 1 ; i<n ; i++)
	{
		cin >> a >> b ;
		a-- ;
		s[i] = b ;
	   	nei[i].push_back ( { a , i } ) ;
		nei[a].push_back ( { i , i } ) ;

	}
	cin >> t ;
	tz = (int)t.size() ;
	find_p () ;
	st_hash() ;
	dfs ( 0 , -1 , 0 ) ;
	cout << ans << endl;
}


#include<bits/stdc++.h>
using namespace std ;
const int maxn = 3* 1e5 + 10 , D = 313 , mod = 1e9 + 7;
#define se second
#define fi first
#define ll long long
ll hsh[maxn] ,  n , ht, ans, tz , p[maxn]  ;
string t , s[maxn]  ;
vector < pair < int , int > > nei[maxn] ;
void find_p()
{
	p[0] = 1 ;
	for ( int i = 1 ;i<=n ; i++)
		p[i] = (p[i-1] * D) % mod ;
}
ll get_hash ( int st , int en )
{
	return ( (hsh[en] - hsh[st] * p[en-st])%mod + mod ) %mod ;
}
void st_hash()
{
	for ( int i= 0; i<tz ; i++)
		hsh[i+1] =	( (hsh[i] * D )+ t[i] )% mod ;
	ht = hsh[tz] ;
	memset ( hsh , 0 , sizeof hsh );
}
void dfs(int v , int par , int ptr  )
{
	//cout << " v par ptr " << v << "  " << par << " " << ptr << endl;
   	for ( auto u : nei[v] )
		if ( u.fi != par )
		{
			for ( auto i : s[u.se] )
			{
				hsh[ptr+1] = ((hsh[ptr]*D)+ i ) %mod ;
				ptr++ ;
				if ( ptr-tz >= 0 &&   get_hash ( ptr- tz, ptr ) == ht )
					ans ++ ;
			}
			dfs ( u.fi , v , ptr ) ;
			ptr -= (int)s[u.se].size() ;
		}
}
int main()
{
	ios::sync_with_stdio(0) , cout.tie(0) , cin.tie(0) ;
	int a ; string b ;
	cin >> n ;
	for ( int i = 1 ; i<n ; i++)
	{
		cin >> a >> b ;
		a-- ;
		s[i] = b ;
	   	nei[i].push_back ( { a , i } ) ;
		nei[a].push_back ( { i , i } ) ;

	}
	cin >> t ;
	tz = (int)t.size() ;
	find_p () ;
	st_hash() ;
	dfs ( 0 , -1 , 0 ) ;
	cout << ans << endl;
}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include <unordered_map>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define pb push_back
long long ans=0;
vector<int>vc[400000];
vector<string>cost;
int M;
int dp[400000][27];
int lps[500000];
char pat[500000],cross[5000000];
int dp_func(int k,char ch)
{
    if(dp[k][ch]!=-1)return dp[k][ch];
    int l=k;
    while(k>0&&pat[k]!=ch)k=lps[k-1];
    if(pat[k]==ch)k++;
    return dp[l][ch-'a']=k;
}
void arrlps()
{
    int len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}
void dfs(int v,int par,int prepat)
{
    int carry=prepat;
    for(int i=0;i<cost[v].size();i++){
        carry=dp_func(carry,cost[v][i]);
        if(carry==M){
                ans++;
                carry=lps[carry-1];
        }
    }
    for(int i=0;i<vc[v].size();i++){
        int w=vc[v][i];
        if(w==par)continue;
        dfs(w,v,carry);
    }
}
char str[500000];
int main()
{
    int i,j,k,l,m,n;
    memset(dp,-1,sizeof dp);
    scanf("%d",&n);
    cost.pb("");
    cost.pb("");

    for(i=2;i<=n;i++){
        scanf("%d",&k);
       scanf("%s",str);
       vc[k].pb(i);
       cost.pb(str);
    }
    scanf("%s",pat);
    M=strlen(pat);
    arrlps();
    dfs(1,0,0);
    printf("%d\n",ans);

}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include <unordered_map>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define pb push_back
long long ans=0;
vector<int>vc[400000];
vector<string>cost;
int M;
int dp[400000][27];
int lps[500000];
char pat[500000],cross[5000000];
int dp_func(int k,char ch)
{
    if(dp[k][ch-'a']!=-1)return dp[k][ch-'a'];
    int l=k;
    while(k>0&&pat[k]!=ch)k=lps[k-1];
    if(pat[k]==ch)k++;
    return dp[l][ch-'a']=k;
}
void arrlps()
{
    int len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}
void dfs(int v,int par,int prepat)
{
    int carry=prepat;
    for(int i=0;i<cost[v].size();i++){
        carry=dp_func(carry,cost[v][i]);
        if(carry==M){
                ans++;
                carry=lps[carry-1];
        }
    }
    for(int i=0;i<vc[v].size();i++){
        int w=vc[v][i];
        if(w==par)continue;
        dfs(w,v,carry);
    }
}
char str[500000];
int main()
{
    int i,j,k,l,m,n;
    memset(dp,-1,sizeof dp);
    scanf("%d",&n);
    cost.pb("");
    cost.pb("");

    for(i=2;i<=n;i++){
        scanf("%d",&k);
       scanf("%s",str);
       vc[k].pb(i);
       cost.pb(str);
    }
    scanf("%s",pat);
    M=strlen(pat);
    arrlps();
    dfs(1,0,0);
    printf("%d\n",ans);

}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include <unordered_map>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define pb push_back
long long ans=0;
vector<int>vc[400000];
vector<string>cost;
int M;
int dp[400000][27];
bool vis[400000][27];
int lps[500000];
char pat[500000],cross[5000000];
int dp_func(int k,char ch)
{
    if(vis[k][ch-'a']!=0)return dp[k][ch-'a'];
    vis[k][ch-'a']=1;
    int l=k;
    while(k>0&&pat[k]!=ch)k=lps[k-1];
    if(pat[k]==ch)k++;
    return dp[l][ch-'a']=k;
}
void arrlps()
{
    int len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}
void dfs(int v,int par,int prepat)
{
    int carry=prepat;
    for(int i=0;i<cost[v].size();i++){
        carry=dp_func(carry,cost[v][i]);
        if(carry==M){
                ans++;
                carry=lps[carry-1];
        }
    }
    for(int i=0;i<vc[v].size();i++){
        int w=vc[v][i];
        if(w==par)continue;
        dfs(w,v,carry);
    }
}
char str[500000];
int main()
{
    int i,j,k,l,m,n;
  //  memset(dp,-1,sizeof dp);
    scanf("%d",&n);
    cost.pb("");
    cost.pb("");

    for(i=2;i<=n;i++){
        scanf("%d",&k);
       scanf("%s",str);
       vc[k].pb(i);
       cost.pb(str);
    }
    scanf("%s",pat);
    M=strlen(pat);
    arrlps();
    dfs(1,0,0);
    printf("%d\n",ans);

}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include <unordered_map>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define pb push_back
long long ans=0;
vector<int>vc[400000];
vector<string>cost;
int M;
int lps[500000];
char pat[500000],cross[5000000];
int kmpsearch(int pre,int N,int prepat)
{
    int i = pre;
    int j  = prepat;
    while (i < N)
    {
        if (pat[j] == cross[i])
        {
            j++;
            i++;
        }

        if (j == M)
        {
          ans++;
            j = lps[j-1];
        }
        else if (i < N && pat[j] != cross[i])
        {
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    return j;
}
void arrlps()
{
    int len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}
void dfs(int v,int par,int pre,int prepat)
{
    int carry=pre;
    for(int i=0;i<cost[v].size();i++){
        cross[carry++]=cost[v][i];
    }
    int l=kmpsearch(pre,carry,prepat);
    for(int i=0;i<vc[v].size();i++){
        int w=vc[v][i];
        if(w==par)continue;
        dfs(w,v,carry,l);
    }
}
char str[5000000];
int main()
{
    int i,j,k,l,m,n;
    scanf("%d",&n);
    cost.pb("");
    cost.pb("");

    for(i=2;i<=n;i++){
        scanf("%d",&k);
       scanf("%s",str);
       vc[k].pb(i);
       cost.pb(str);
    }
    scanf("%s",pat);
    M=strlen(pat);
    arrlps();
    dfs(1,0,0,0);
    printf("%d\n",ans);

}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include <unordered_map>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define pb push_back
long long ans=0;
vector<int>vc[400000];
vector<string>cost[400000];
int M;
int lps[500000];
char pat[500000],cross[5000000];
int kmpsearch(int pre,int N,int prepat)
{
    int i = pre;
    int j  = prepat;
    while (i < N)
    {
        if (pat[j] == cross[i])
        {
            j++;
            i++;
        }

        if (j == M)
        {
          ans++;
            j = lps[j-1];
        }
        else if (i < N && pat[j] != cross[i])
        {
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    return j;
}
void arrlps()
{
    int len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}
void dfs(int v,int par,int pre,string str,int prepat)
{
    int carry=pre;
    for(int i=0;i<str.size();i++){
        cross[carry++]=str[i];
    }
    int l=kmpsearch(pre,carry,prepat);
    for(int i=0;i<vc[v].size();i++){
        int w=vc[v][i];
        if(w==par)continue;
        dfs(w,v,carry,cost[v][i],l);
    }
}
int main()
{
    int i,j,k,l,m,n;
    scanf("%d",&n);
    string str;
    for(i=2;i<=n;i++){
        scanf("%d",&k);
       cin>>str;
       vc[k].pb(i);
       cost[k].pb(str);
    }
    scanf("%s",pat);
    M=strlen(pat);
    arrlps();
    dfs(1,-1,0,"",0);
    cout<<ans<<endl;

}


#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<string>
#include<map>
#include<list>
#include<queue>
#include<utility>
#include<sstream>
#include<cstdlib>
#include<cctype>
#include <unordered_map>
#include<math.h>
#include<set>
#include<stack>
#include<fstream>
#include<numeric>
#include<string>
#include<vector>
#include<iterator>
using namespace std;
#define pb push_back
long long ans=0;
vector<int>vc[400000];
vector<string>cost[400000];
int M;
int lps[500000];
char pat[500000],cross[5000000];
int kmpsearch(int pre,int N,int prepat)
{
    int i = pre;
    int j  = prepat;
    while (i < N)
    {
        if (pat[j] == cross[i])
        {
            j++;
            i++;
        }

        if (j == M)
        {
          ans++;
            j = lps[j-1];
        }
        else if (i < N && pat[j] != cross[i])
        {
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    return j;
}
void arrlps()
{
    int len = 0;
    lps[0] = 0;
    int i = 1;
    while (i < M)
    {
        if (pat[i] == pat[len])
        {
            len++;
            lps[i] = len;
            i++;
        }
        else
        {
            if (len != 0)
            {
                len = lps[len-1];
            }
            else
            {
                lps[i] = 0;
                i++;
            }
        }
    }
}
void dfs(int v,int par,int pre,string str,int prepat)
{
    int carry=pre;
    for(int i=0;i<str.size();i++){
        cross[carry++]=str[i];
    }
    int l=kmpsearch(pre,carry,prepat);
    for(int i=0;i<vc[v].size();i++){
        int w=vc[v][i];
        if(w==par)continue;
        dfs(w,v,carry,cost[v][i],l);
    }
}
char str[5000000];
int main()
{
    int i,j,k,l,m,n;
    scanf("%d",&n);

    for(i=2;i<=n;i++){
        scanf("%d",&k);
       scanf("%s",str);
       vc[k].pb(i);
       cost[k].pb(str);
    }
    scanf("%s",pat);
    M=strlen(pat);
    arrlps();
    dfs(1,-1,0,"",0);
    cout<<ans<<endl;

}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define clr(a, x) memset(a, x, sizeof(a))
#define pii pair<int, int>
#define pb push_back
#define pis pair<int, string>

const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;

string s;
int nex[300015];
int n, L;
vector<int> e[300015];
string str[300015];
void pre_kmp() {
	cin >> s;
	L = s.length();
	nex[0] = -1;
	int i = -1, j = 0;
	for (; j < L; ++j) {
		while (~i && s[i] != s[j]) {
			i = nex[i];
		}
		nex[j + 1] = ++i;
	}
}
int pos[300015], ans;
void dfs(int u) {
	for (auto p : e[u]) {
		int v = p;
		string t = str[v];
		int x = pos[u];
		for (int i = 0; i < t.length(); ++i) {
			while (~x && t[i] != s[x]) {
				x = nex[x];
			}
			++x;
			if (x == L) {
				++ans;
				x = nex[x];
			}
		}
		pos[v] = x;
		dfs(v);
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; ++i) {
		int p; string s;
		cin >> p >> s;
		e[p].pb(i);
		str[i] = s;
	}
	pre_kmp();
	dfs(1);
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define clr(a, x) memset(a, x, sizeof(a))
#define pii pair<int, int>
#define pb push_back
#define pis pair<int, string>

const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;

string s;
int nex[300015];
int fuck[300015][26];
int n, L;
vector<int> e[300015];
string str[300015];
void pre_kmp() {
	cin >> s;
	L = s.length();
	nex[0] = -1;
	int i = -1, j = 0;
	for (; j < L; ++j) {
		while (~i && s[i] != s[j]) {
			i = nex[i];
		}
		nex[j + 1] = ++i;
	}
	for (i = 0; i < L; ++i) {
		if (~nex[i] && s[nex[i]] == s[i]) {
			nex[i] = nex[nex[i]];
		}
	}
	/*
	for (int i = 0; i <= L; ++i) {
		cout << nex[i] << ' ';
	}
	cout << endl;
	*/
}
int pos[300015], ans;
void dfs(int u) {
	for (auto p : e[u]) {
		int v = p;
		string t = str[v];
		int x = pos[u];
		for (int i = 0; i < t.length(); ++i) {
			while (~x && t[i] != s[x]) {
				x = nex[x];
			}
			++x;
			if (x == L) {
				++ans;
				x = nex[x];
			}
		}
		pos[v] = x;
		dfs(v);
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; ++i) {
		int p; string s;
		cin >> p >> s;
		e[p].pb(i);
		str[i] = s;
	}
	pre_kmp();
	dfs(1);
	cout << ans << endl;
	return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define ll long long
#define clr(a, x) memset(a, x, sizeof(a))
#define pii pair<int, int>
#define pb push_back
#define pis pair<int, string>

const int INF = 0x3f3f3f3f;
const double EPS = 1e-9;

string s;
int nex[300015];
int n, L;
vector<pis> e[300015];
void pre_kmp() {
	cin >> s;
	L = s.length();
	s += '#';
	nex[0] = -1;
	int i = -1, j = 0;
	for (; j < L; ++j) {
		while (~i && s[i] != s[j]) {
			i = nex[i];
		}
		nex[j + 1] = ++i;
	}
}
int pos[300015], ans;
void dfs(int u) {
	for (auto p : e[u]) {
		int v = p.first;
		string t = p.second;
		int x = pos[u];
		for (int i = 0; i < t.length(); ++i) {
			while (~x && t[i] != s[x]) {
				x = nex[x];
			}
			++x;
			if (x == L) {
				++ans;
				x = nex[x];
			}
		}
		pos[v] = x;
		dfs(v);
	}
}
int main() {
	ios::sync_with_stdio(false);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; ++i) {
		int p; string s;
		cin >> p >> s;
		e[p].pb(pis(i, s));
	}
	pre_kmp();
	dfs(1);
	cout << ans << endl;
	return 0;
}


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

#define F first
#define S second
#define int long long
#define ull  unsigned long long
#define pb push_back

using namespace std;
using namespace __gnu_pbds;
typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int N = 600000;
vector < pair < int, char > > g[N];
pair < int, int > h[N];
int p[N][21];
string s[N];
const int mod1 = 1e9 + 7;
const int mod2 = 1e9 + 9;
const int base = 427;
void dfs(int v, pair < int, int > hsh){
    h[v] = hsh;
    for (auto u: g[v]){
        int x = (hsh.F * base + u.S) % mod1;
        int y = (hsh.S * base + u.S) % mod2;
        dfs(u.F, {x, y});
        p[u.F][0] = v;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt","w", stdout);
    int n;
    cin >> n;
    int l = n + 1;
    for (int i = 2; i <= n; i++){
        int x;
        cin >> x;
        cin >> s[i];
        if (s[i].length() == 1){
            g[x].pb({i, s[i][0]});
        } else{
            g[x].pb({l, s[i][0]});
            for (int j = l; j < l + s[i].length() - 2; j++){
                g[j].pb({j + 1, s[i][j - l + 1]});
            }
            g[l + s[i].length() - 2].pb({i, s[i][s[i].length() - 1]});
            l += s[i].length() - 1;
        }
    }
    dfs(1, {0, 0});
    string t;
    cin >> t;
    int m = t.length();
    int M1 = 1;
    int M2 = 1;
    int H1 = 0;
    int H2 = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++){
        H1 = (H1 * base + t[i - 1]) % mod1;
        H2 = (H2 * base + t[i - 1]) % mod2;
        M1 = M1 * base % mod1;
        M2 = M2 * base % mod2;
    }
    for (int i = 1; i <= 20; i++){
        for (int j = 1; j < l; j++){
            int v = p[j][i - 1];
            p[j][i] = p[v][i - 1];
        }
    }
    for (int i = 1; i < l; i++){
        int v = i;
        int x = m;
        for (int j = 20; j >= 0; j--){
            if ((1 << j) <= x){
                x -= (1 << j);
                v = p[v][j];
            }
        }
        if (v == 0) continue;
        int v1 = (h[i].F - h[v].F * M1 % mod1 + mod1) % mod1;
        int v2 = (h[i].S - h[v].S * M2 % mod2 + mod2) % mod2;
        if (v1 == H1 && v2 == H2) ans++;
    }
    cout << ans;
}


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

#define F first
#define S second
#define int long long
#define ull  unsigned long long
#define pb push_back

using namespace std;
using namespace __gnu_pbds;
typedef  tree< int , null_type, less<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;
const int N = 600000;
vector < pair < int, char > > g[N];
pair < int, int > h[N];
int p[N][21];
string s[N];
const int mod1 = 1e9 + 7;
const int mod2 = 1e9 + 9;
const int base = 427;
void dfs(int v, pair < int, int > hsh){
    h[v] = hsh;
    for (auto u: g[v]){
        int x = (hsh.F * base + u.S) % mod1;
        int y = (hsh.S * base + u.S) % mod2;
        dfs(u.F, {x, y});
        p[u.F][0] = v;
    }
}
main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt","w", stdout);
    int n;
    cin >> n;
    int l = n + 1;
    for (int i = 2; i <= n; i++){
        int x;
        cin >> x;
        cin >> s[i];
        if (s[i].length() == 1){
            g[x].pb({x, s[i][0]});
        } else{
            g[x].pb({l, s[i][0]});
            for (int j = l; j < l + s[i].length() - 2; j++){
                g[j].pb({j + 1, s[i][j - l + 1]});
            }
            g[l + s[i].length() - 2].pb({i, s[i][s[i].length() - 1]});
            l += s[i].length() - 1;
        }
    }
    dfs(1, {0, 0});
    string t;
    cin >> t;
    int m = t.length();
    int M1 = 1;
    int M2 = 1;
    int H1 = 0;
    int H2 = 0;
    int ans = 0;
    for (int i = 1; i <= m; i++){
        H1 = (H1 * base + t[i - 1]) % mod1;
        H2 = (H2 * base + t[i - 1]) % mod2;
        M1 = M1 * base % mod1;
        M2 = M2 * base % mod2;
    }
    for (int i = 1; i <= 20; i++){
        for (int j = 1; j < l; j++){
            int v = p[j][i - 1];
            p[j][i] = p[v][i - 1];
        }
    }
    for (int i = 1; i < l; i++){
        int v = i;
        int x = m;
        for (int j = 20; j >= 0; j--){
            if ((1 << j) <= x){
                x -= (1 << j);
                v = p[v][j];
            }
        }
        if (v == 0) continue;
        int v1 = (h[i].F - h[v].F * M1 % mod1 + mod1) % mod1;
        int v2 = (h[i].S - h[v].S * M2 % mod2 + mod2) % mod2;
        if (v1 == H1 && v2 == H2) ans++;
    }
    cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define ull unsigned ll
#define f first
#define s second
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) for (int i=(n-1); i>=0; --i)
#define REP1(i,n) FOR(i,1,n+1)
#define ALL(x) x.begin(),x.end()
#define SZ(x) (int)x.size()
#define SQ(x) (x)*(x)
#define MN(a,b) a = min(a,(__typeof__(a))(b))
#define MX(a,b) a = max(a,(__typeof__(a))(b))
#define pb push_back
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#ifdef BALBIT
#define IOS()
#define bug(...) fprintf(stderr,"#%d (%s) = ",__LINE__,#__VA_ARGS__),_do(__VA_ARGS__);
template<typename T> void _do(T &&x){cerr<<x<<endl;}
template<typename T, typename ...S> void _do(T &&x, S &&...y){cerr<<x<<", ";_do(y...);}
#else
#define IOS() ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define bug(...)
#endif

const int iinf = 1<<29;
const ll inf = 1ll<<60;
const ll mod = 1e9+7;

void GG(){cout<<"-1\n"; exit(0);}

ll mpow(ll a, ll n, ll mo = mod){ // a^n % mod
    ll re=1;
    while (n>0){
        if (n&1) re = re*a %mo;
        a = a*a %mo;
        n>>=1;
    }
    return re;
}

ll inv (ll b, ll mo = mod){
    if (b==1) return b;
    return (mo-mo/b) * inv(mo%b) % mo;
}

const int maxn = 1e5+5;

vector<int> g[maxn];
string sat[maxn];
string s = "";
int f[400005];
int ansfor[maxn][26];
ll re = 0;
int ORG;

void dfs(int v, int par) {
    int n = sat[v].length();
    int start = 0;
    if (par!=-100 && ansfor[par][sat[v][0]-'a']!=-100) {
        bug("Used Trick!");
        s += sat[v][0];
        f[s.length()-1] = ansfor[par][sat[v][0]-'a'];
        if (f[s.length()-1] == ORG-1) re++;
        start = 1;
    }
    FOR(i,start, n ){
        s += sat[v][i];
        int j = s.length()-1;
        f[j] = f[j-1];
        while (f[j]!=-1 && s[f[j]+1]!=s[j]) {
            f[j] = f[f[j]];
        }
        if (s[f[j]+1] == s[j]) f[j]++;
        if (i==0) ansfor[par][s.back()-'a'] = f[j];
        if (f[j] == ORG-1) re++;
    }

    bug(v,s);
    for (int u : g[v]) {
        dfs(u, v);
    }
    REP(i,n) s.pop_back();
}

signed main(){
    IOS();
    int n; cin>>n;
    REP1(i,n-1) {
        int p; cin>>p; --p;
        g[p].pb(i);
        cin>>sat[i];
    }
    cin>>s; ORG = s.length(); s+="#";
    f[0] = -1;
    REP1(i, s.length()-1) {
        f[i] = f[i-1];
        while (f[i]!=-1 && s[f[i]+1]!=s[i]) f[i] = f[f[i]];
        if (s[f[i]+1]==s[i]) f[i]++;
        bug(i,f[i]);
    }
    REP(i,maxn) REP(j,26) ansfor[i][j] = -100;
    dfs(0,-100);
    cout<<re<<endl;
}


#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int, int>
#define ull unsigned ll
#define f first
#define s second
#define FOR(i,a,b) for (int i=(a); i<(b); ++i)
#define REP(i,n) FOR(i,0,n)
#define RREP(i,n) for (int i=(n-1); i>=0; --i)
#define REP1(i,n) FOR(i,1,n+1)
#define ALL(x) x.begin(),x.end()
#define SZ(x) (int)x.size()
#define SQ(x) (x)*(x)
#define MN(a,b) a = min(a,(__typeof__(a))(b))
#define MX(a,b) a = max(a,(__typeof__(a))(b))
#define pb push_back
#define SORT_UNIQUE(c) (sort(c.begin(),c.end()), c.resize(distance(c.begin(),unique(c.begin(),c.end()))))
#ifdef BALBIT
#define IOS()
#define bug(...) fprintf(stderr,"#%d (%s) = ",__LINE__,#__VA_ARGS__),_do(__VA_ARGS__);
template<typename T> void _do(T &&x){cerr<<x<<endl;}
template<typename T, typename ...S> void _do(T &&x, S &&...y){cerr<<x<<", ";_do(y...);}
#else
#define IOS() ios_base::sync_with_stdio(0);cin.tie(0);
#define endl '\n'
#define bug(...)
#endif

const int iinf = 1<<29;
const ll inf = 1ll<<60;
const ll mod = 1e9+7;

void GG(){cout<<"-1\n"; exit(0);}

ll mpow(ll a, ll n, ll mo = mod){ // a^n % mod
    ll re=1;
    while (n>0){
        if (n&1) re = re*a %mo;
        a = a*a %mo;
        n>>=1;
    }
    return re;
}

ll inv (ll b, ll mo = mod){
    if (b==1) return b;
    return (mo-mo/b) * inv(mo%b) % mo;
}

const int maxn = 1e5+5;

vector<int> g[maxn];
string sat[maxn];
string s = "";
int f[400005];
ll re = 0;
int ORG;

void dfs(int v) {
    int n = sat[v].length();
    REP(i,n ){
        s += sat[v][i];
        int j = s.length()-1;
        f[j] = f[j-1];
        while (f[j]!=-1 && s[f[j]+1]!=s[j]) {
            f[j] = f[f[j]];
        }
        if (s[f[j]+1] == s[j]) f[j]++;
        if (f[j] == ORG-1) re++;
    }
    bug(v,s);
    for (int u : g[v]) {
        dfs(u);
    }
    REP(i,n) s.pop_back();
}

signed main(){
    IOS();
    int n; cin>>n;
    REP1(i,n-1) {
        int p; cin>>p; --p;
        g[p].pb(i);
        cin>>sat[i];
    }
    cin>>s; ORG = s.length(); s+="#";
    f[0] = -1;
    REP1(i, s.length()-1) {
        f[i] = f[i-1];
        while (f[i]!=-1 && s[f[i]+1]!=s[i]) f[i] = f[f[i]];
        if (s[f[i]+1]==s[i]) f[i]++;
        bug(i,f[i]);
    }
    dfs(0);
    cout<<re<<endl;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100;
int n,state[N];
string s[N];
vector<int> tr[N];

char t[3*N];
int ft[3*N],acc,ans;

void dfs(int x=1){
  for(auto&it:tr[x]){
    int j = state[x];
    for(auto&c:s[it]){
      for(;j>0 and t[j+1]!=c;j=ft[j]);
      if(t[j+1]==c)j++;
      if(j==acc)ans++;
    }
    state[it] = j;
    dfs(it);
  }
}

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

  cin>>n;
  for(int p,i=2;i<=n;i++){
    cin>>p>>s[i];
    tr[p].emplace_back(i);
  }
  cin>>1+t;
  acc=strlen(1+t);
  t[acc+1]='$';

  ft[1]=0;
  for(int j=0,i=2;i<=n;i++){
    for(;j>0 and t[j+1]!=t[i];j=ft[j]);
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  ans=state[1]=0;
  dfs();
  cout<<ans<<nl;

  return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100,L=300100;
int n,l,state[N];
vector<int> tr[N];
string s[N],t;

int ft[L],cur;
ll ans;

void dfs(int x=1){
  for(auto&it:tr[x]){
    cur = state[x];
    for(auto&c:s[it]){
      while(cur>0 and t[cur+1]!=c)cur=ft[cur];
      if(t[cur+1]==c)cur++;
      if(cur==l)ans++;
    }
    state[it]=cur;
    dfs(it);
  }
}

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

  cin>>n;
  for(int i=2;i<=n;i++){
    int par;cin>>par>>s[i];
    tr[par].emplace_back(i);
  }
  cin>>t;l=t.length();
  t='$'+t;t+="\0";

  ft[1]=0;
  for(int j=0,i=2;i<=l;i++){
    while(j>0 and t[i]!=t[j+1])j=ft[j];
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  ans=0;
  state[1]=0;
  dfs();
  cout<<ans<<nl;

  return 0;
}


//#COPIED
#include<queue>
#include<vector>
#include<cstdio>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N = 100005, L = 300005;
int n, m, ans, fa[N], st[N], nxt[N];
char tmp[L], t[L];
string s[N];
vector<int> edge[N];

void getFail(char *t) {
	nxt[0] = -1;
	for (int i = 1; i <= m; ++i) {
		nxt[i] = nxt[i - 1];
		while (nxt[i] != -1 && t[nxt[i]] != t[i - 1]) {
			nxt[i] = nxt[nxt[i]];
		}
		++nxt[i];
	}
}

void cal(int u) {
	int p = st[fa[u]];
	for (int i = 0; i < s[u].size(); ++i) {
		++p;
		while (p != -1 && s[u][i] != t[p]) {
			p = nxt[p];
		}
		if (p == m - 1) {
			++ans;
		}
	}
	st[u] = p;
}

int main() {
	scanf("%d", &n);
	for (int i = 1; i < n; ++i) {
		scanf("%d%s", fa + i, tmp);
		--fa[i];
		edge[fa[i]].push_back(i);
		s[i] = tmp;
	}
	scanf("%s", t);
	m = strlen(t);
	getFail(t);
	st[0] = -1;
	ans = 0;
	queue<int> q;
	for (int i = 0; i < (int)edge[0].size(); ++i) {
		q.push(edge[0][i]);
	}
	while (q.size()) {
		int i = q.front();
		cal(i);
		q.pop();
		for (int j = 0; j < (int)edge[i].size(); ++j) {
			q.push(edge[i][j]);
		}
	}
	printf("%d\n", ans);
	return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100,L=300100;
int n,l,state[N];
vector<int> tr[N];
string s[N],t;

int dfa[L][26],ft[L],cur;
ll ans;

void dfs(int x=1){
  for(auto&it:tr[x]){
    cur = state[x];
    for(auto&c:s[it]){
      cur = dfa[cur][c-'a'];
      if(cur==l)ans++;
    }
    state[it]=cur;
    dfs(it);
  }
}

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

  cin>>n;
  for(int i=2;i<=n;i++){
    int par;cin>>par>>s[i];
    tr[par].emplace_back(i);
  }
  cin>>t;l=t.length();
  t='$'+t;

  ft[1]=0;
  for(int j=0,i=2;i<=l;i++){
    while(j>0 and t[i]!=t[j+1])j=ft[j];
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  memset(dfa,0,sizeof dfa);
  dfa[0][t[1]-'a']=1;

  t[l+1]=0;//
  for(int i=1;i<=l;i++){
    for(char c=0;c<26;c++){
      int j=i;
      while(j>0 and t[j+1]-'a'!=c)j=ft[j];
      if(t[j+1]-'a'==c)j++;
      dfa[i][c] = j;
    }
  }

  ans=0;
  state[1]=0;////////////////////
  dfs();
  cout<<ans<<nl;

  return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100;
int n,state[N];
string s[N];
vector<int> tr[N];

char t[3*N];
int ft[3*N],acc,ans;

void dfs(int x=1){
  for(auto&it:tr[x]){
    int j = state[x];
    for(auto&c:s[it]){
      for(;j>0 and t[j+1]!=c;j=ft[j]);
      if(t[j+1]==c)j++;
      if(j==acc){
	ans++;
	j=ft[j];//
      }
    }
    state[it] = j;
    dfs(it);
  }
}

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

  cin>>n;
  for(int p,i=2;i<=n;i++){
    cin>>p>>s[i];
    tr[p].emplace_back(i);
  }
  cin>>1+t;
  acc=strlen(1+t);

  ft[1]=0;
  for(int j=0,i=2;i<=n;i++){
    for(;j>0 and t[j+1]!=t[i];j=ft[j]);
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  ans=state[1]=0;
  dfs();
  cout<<ans<<nl;

  return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100,L=300100;
int n,l,state[N];
vector<int> tr[N];
string s[N],t;

int dfa[L][26],ft[L],cur,ans;

void dfs(int x=1){
  for(auto&it:tr[x]){
    cur = state[x];
    for(auto&c:s[it]){
      cur = dfa[cur][c-'a'];
      if(cur==l)ans++;
    }
    state[it]=cur;
    dfs(it);
  }
}

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

  cin>>n;
  for(int i=2;i<=n;i++){
    int par;cin>>par>>s[i];
    tr[par].emplace_back(i);
  }
  cin>>t;l=t.length();
  t='$'+t;

  ft[1]=0;
  for(int j=0,i=2;i<=l;i++){
    while(j>0 and t[i]!=t[j+1])j=ft[j];
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  memset(dfa[0],0,sizeof dfa[0]);
  dfa[0][t[1]-'a']=1;

  t[l+1]=0;//
  for(int i=1;i<=l;i++){
    for(char c=0;c<26;c++){
      int j=i;
      while(j>0 and t[j+1]-'a'!=c)j=ft[j];
      if(t[j+1]-'a'==c)j++;
      dfa[i][c] = j;
    }
  }

  ans=0;
  state[1]=1;
  dfs();
  cout<<ans<<nl;

  return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100;
int n,state[N];
string s[N];
vector<int> g[N];

char t[3*N];
int ft[3*N],dfa[3*N][26],l;
int ans;

void dfs(int x=1){
  for(auto&it:g[x]){
    int j = state[x];
    for(auto&c:s[it]){
      j=dfa[j][c-'a'];
      if(j==l)ans++;
    }
    state[it]=j;
    dfs(it);
  }
}

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

  cin>>n;
  for(int p,i=2;i<=n;i++){
    cin>>p>>s[i];
    g[p].emplace_back(i);
  }

  cin>>1+t;
  l=strlen(1+t);

  ft[1]=0;
  for(int j=0,i=2;i<=l;i++){
    for(;j>0 and t[j+1]!=t[i];j=ft[j]);
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  memset(dfa,0,sizeof dfa);
  dfa[0][t[1]-'a']=1;
  for(int i=1;i<=l;i++){
    for(int c=0;c<26;c++){
      if(i<l and c==t[i+1]-'a'){
	dfa[i][c]=i+1;
      }else{
	dfa[i][c] = dfa[ ft[i] ][c];
      }
    }
  }

  ans=state[1]=0;
  dfs();
  cout<<ans<<nl;

  return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100 ;
vector< pair<int,string> > tr[N];
int n,l;
char t[3*N];
int ft[3*N],ans;

void dfs(int x=1,int state=0){
  for(auto&it:tr[x]){
    int j = state;
    for(auto&c:it.ss){
      for(;j>0 and t[j+1]!=c;j=ft[j]);
      if(t[j+1]==c)j++;
      if(j==l)ans++;
    }
    dfs(it.ff,j);
  }
}

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

  cin>>n;
  string temp;
  for(int p,i=2;i<=n;i++){
    cin>>p>>temp;
    tr[p].emplace_back(i,temp);
  }
  cin>>1+t;l=strlen(1+t);t[l+1]='$';

  ft[1] = 0;
  for(int j=0,i=2;i<=l;i++){
    for(;j>0 and t[i]!=t[j+1];j=ft[j]);
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  ans=0;
  dfs();
  cout<<ans<<nl;

  return 0;
}


//g++ -std=c++14 -g -O2 -o ./a ./A.cpp
#include <bits/stdc++.h>
using namespace std;
#define ff first
#define ss second
#define nl '\n'
typedef long long ll;
//////////////////////////////////////////////////////////////////////

const int N = 100100;
int n,state[N];
string s[N];
vector<int> tr[N];

char t[3*N];
int ft[3*N],acc,ans;

void dfs(int x=1){
  for(auto&it:tr[x]){
    int j = state[x];
    for(auto&c:s[it]){
      for(;j>0 and t[j+1]!=c;j=ft[j]);
      if(t[j+1]==c)j++;
      if(j==acc){
	ans++;
	j=ft[j];/////
      }
    }
    state[it] = j;
    dfs(it);
  }
}

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

  cin>>n;
  for(int p,i=2;i<=n;i++){
    cin>>p>>s[i];
    tr[p].emplace_back(i);
  }
  cin>>1+t;
  acc=strlen(1+t);
  t[acc+1]='$';

  ft[1]=0;
  for(int j=0,i=2;i<=acc;i++){//////
    for(;j>0 and t[j+1]!=t[i];j=ft[j]);
    if(t[j+1]==t[i])j++;
    ft[i]=j;
  }

  ans=state[1]=0;
  dfs();
  cout<<ans<<nl;

  return 0;
}


#include<bits/stdc++.h>
using namespace std;
const int N = 2e5+1;
const int M = 5e5+1;
int n;

string str[N*2];
string s1;
int tot;
int tail[M],nxt[M],to[M];

inline void add_edge(int x,int y,string s){
   to[++tot] = y; nxt[tot] = tail[x]; tail[x] = tot;
   str[tot] = s;
}
int fail[M],tr[M][26];

class kmp{
public:
   void init(){
      memset(fail,0,sizeof(fail));
      for(unsigned int i = 2;i < s1.size(); ++i){
         int cur = fail[i-1];
         while(cur && s1[cur+1] != s1[i])cur = fail[cur];
         if(s1[cur+1] == s1[i])fail[i] = cur+1;
         else fail[i] = 0;
      }
      for(unsigned int i = 0;i < s1.size()-1; ++i){
         for(int j = 0;j < 26; ++j){
            if(s1[i+1]-'a' == j)tr[i][j] = i+1;
            else tr[i][j] = tr[fail[i]][j];
         }
      }
   }
}S;

int ans;
void dfs(int x,int p,int f){
   for(int i = tail[x];i;i = nxt[i]){
      int cur = p;
      int y = to[i];
      if(y == f)continue ;
      for(int j = 0;j < str[i].size(); ++j){
         cur = tr[cur][str[i][j]-'a'];
         if(cur == s1.size()-1)ans ++,cur = fail[cur];
      }
      dfs(y,cur,x);
   }
}

int main(){
   ios::sync_with_stdio(false);
   cin >> n;
   for(int i = 2;i <= n; ++i){
      int x;
      string s2;
      cin >> x >> s2;
      add_edge(x,i,s2);
      add_edge(i,x,s2);
   }
   cin >> s1;
   s1 = ' ' + s1;
   S.init();
   dfs(1,0,0);
   cout << ans << endl;
   return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define pb emplace_back
#define mp make_pair

using namespace std;

string s[100002];
int rl;
int cn = 0;
string t;
std::vector<int> adj[100002];
std::vector<int> lps[100001];

void lpsdfs(int u, int p, int tlps) {
	lps[u].resize(s[u].size());
	for (int i = !(!(!u)); i < s[u].size(); cn += (tlps == rl), ++i) {
		while (tlps > 0 && s[0][tlps] != s[u][i]) tlps = lps[0][tlps - 1];
		if (s[0][tlps] == s[u][i]) tlps++;
		lps[u][i] = tlps;
	}
	for (int v : adj[u])
		if (v != p)
			lpsdfs(v, u, tlps);
}

int32_t main()
{
	ios::sync_with_stdio(false); cin.tie(NULL);
	int n; cin >> n;
	for (int i = 1; i < n; ++i) {
		int u; cin >> u; u--;
		cin >> s[i];
		adj[i].pb(u);
		adj[u].pb(i);
	}
	cin >> s[0];
	rl = s[0].size();
	s[0] += "$";
	lpsdfs(0, 0, 0);
	cout << cn;
}


#pragma GCC optimize("Ofast")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#include <bits/stdc++.h>
#define pb emplace_back
#define mp make_pair

using namespace std;

string s[100002];
int rl;
int cn = 0;
std::vector<int> adj[100002];
std::vector<int> lps[100001];

const int K = 26;

struct Vertex {
    int next[K];
    bool leaf = false;
    int p = -1;
    char pch;
    int link = -1;
    int go[K];

    Vertex(int p=-1, char ch='$') : p(p), pch(ch) {
        fill(begin(next), end(next), -1);
        fill(begin(go), end(go), -1);
    }
};

vector<Vertex> t(1);

void add_string(string const& s) {
    int v = 0;
    for (char ch : s) {
        int c = ch - 'a';
        if (t[v].next[c] == -1) {
            t[v].next[c] = t.size();
            t.emplace_back(v, ch);
        }
        v = t[v].next[c];
    }
    t[v].leaf = true;
}

int go(int v, char ch);

int get_link(int v) {
    if (t[v].link == -1) {
        if (v == 0 || t[v].p == 0)
            t[v].link = 0;
        else
            t[v].link = go(get_link(t[v].p), t[v].pch);
    }
    return t[v].link;
}

int go(int v, char ch) {
    int c = ch - 'a';
    if (t[v].go[c] == -1) {
        if (t[v].next[c] != -1)
            t[v].go[c] = t[v].next[c];
        else
            t[v].go[c] = v == 0 ? 0 : go(get_link(v), ch);
    }
    return t[v].go[c];
}

void lpsdfs(int u, int p, int v) {
	if (u)
		for (char ch : s[u])
			cn += (t[(v = go(v, ch))].leaf);
	for(int V : adj[u])
		if (V != p)
			lpsdfs(V, u, v);
}

int32_t main()
{
	ios::sync_with_stdio(false); cin.tie(NULL);
	int n; cin >> n;
	for (int i = 1; i < n; ++i) {
		int u; cin >> u; u--;
		cin >> s[i];
		adj[i].pb(u);
		adj[u].pb(i);
	}
	cin >> s[0];
	rl = s[0].size();
	add_string(s[0]);
	lpsdfs(0, 0, 0);
	cout << cn;
}


#include <bits/stdc++.h>
#define pb emplace_back
#define mp make_pair

using namespace std;

string s[500002];
int rl;
int cn = 0;
string t;
std::vector<int> adj[500002];
std::vector<int> lps[500001];

void lpsdfs(int u, int p, int l) {
	lps[u].resize(s[u].size());
	int tlps = l;
	for (int i = !(!(!u)); i < s[u].size(); cn += (tlps == rl), ++i) {
		while (tlps > 0 && s[0][tlps] != s[u][i]) tlps = lps[0][tlps - 1];
		if (s[0][tlps] == s[u][i]) tlps++;
		lps[u][i] = tlps;
	}
	for (int v : adj[u])
		if (v != p)
			lpsdfs(v, u, tlps);
}

int32_t main()
{
	ios::sync_with_stdio(false); cin.tie(NULL); cout.precision(10);
	int n; cin >> n;
	for (int i = 1; i < n; ++i) {
		int u; cin >> u; u--;
		cin >> s[i];
		adj[i].pb(u);
		adj[u].pb(i);
	}
	cin >> s[0];
	rl = s[0].size();
	s[0] += "$";
	lpsdfs(0, 0, 0);
	cout << cn;
}


#include<bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define ll long long
#define int long long
const int INF = 1LL * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
const int inf = 1000 * 1000 * 1000 + 1000;
#define next nex
/* _________________________________________
 / You don't become a failure until you're \
 \ satisfied with being one.               /
   -----------------------------------------
  \
   \
		 .--.
		|o_o |
		|:_/ |
   	       //   \ \
              (|     | )
	     /'\_   _/`\
	     \___)=(___/

*/

const int N = 300 * 1000 + 1000,
            K = 27;
vector<pair<int, string> > adj[N];
int f[N], next[N][K],
    sz = 0, m, ans;
void dfs(int p, int curr = 0, int par = 1){
    int c = curr;
    for(auto q : adj[p])
        if(q.F != par){
            //cout << p << ' ' << q.F << ' ' << q.S << '\n';
            curr = c;
            for(int i = 0; i < q.S.size(); i++){
                //cout << curr << ' ';
                if(curr == m)
                    ans++;
                curr = next[curr][q.S[i] - 'a'];
            }
            if(curr == m)
                ans++;
            //cout << curr << '\n';
            dfs(q.F, curr, p);
        }

}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    for(int i = 0; i < n - 1; i++){
        int p;
        string s;
        cin >> p >> s;
        adj[i + 2].pb({p, s});
        adj[p].pb({i + 2, s});
    }
    string t;
    cin >> t;
    m = t.size();

    //cout << t << endl;
    //cout << t[0] - 'a' << endl;

    for(int i = 0; i <= m; i++){
        for(int j = 0; j < K; j++){
            if(i != m && t[i] - 'a' == j){
      //          cout << i << ' ' << j << '\n';
                next[i][j] = i + 1;
                if(i != 0)
                    f[i + 1] = next[f[i]][t[i] - 'a'];
            }
            else{
                if(i != 0){
                    //if(i == 3 && j == 1)
                        //cout << f[i - 1] << ' ' << next[f[i - 1]][j] << "****\n";
                    next[i][j] = next[f[i]][j];
                }
            }
        }
    }

    dfs(1);
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define ll long long
#define int long long
const int INF = 1LL * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
const int inf = 1000 * 1000 * 1000 + 1000;
#define next nex
/* _________________________________________
 / You don't become a failure until you're \
 \ satisfied with being one.               /
   -----------------------------------------
  \
   \
		 .--.
		|o_o |
		|:_/ |
   	       //   \ \
              (|     | )
	     /'\_   _/`\
	     \___)=(___/

*/

const int N = 800 * 1000 + 1000,
            K = 30;
vector<pair<int, string> > adj[N];
int f[N], next[N][K],
    m, ans;

void dfs(int p, int curr = 0){
    int c = curr;
    for(auto q : adj[p]){
        curr = c;
        for(int i = 0; i < q.S.size(); i++){
            curr = next[curr][q.S[i] - 'a'];
            if(curr == m)
                ans++;
        }
        dfs(q.F, curr);
    }
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    for(int i = 0; i < n - 1; i++){
        int p;
        string s;
        cin >> p >> s;
        adj[p].pb({i + 2, s});
    }

    string t;
    cin >> t;
    m = t.size();

    for(int i = 0; i <= m; i++){
        for(int j = 0; j < K; j++){
            if(i != m && t[i] - 'a' == j){
                next[i][j] = i + 1;
                if(i != 0)
                    f[i + 1] = next[f[i]][t[i] - 'a'];
            }
            else{
                if(i != 0){
                    next[i][j] = next[f[i]][j];
                }
            }
        }
    }

    dfs(1);
    cout << ans << '\n';
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define F first
#define S second
#define pb push_back
#define ll long long
#define int long long
const int INF = 1LL * 1000 * 1000 * 1000 * 1000 * 1000 * 1000;
const int inf = 1000 * 1000 * 1000 + 1000;
#define next nex
/* _________________________________________
 / You don't become a failure until you're \
 \ satisfied with being one.               /
   -----------------------------------------
  \
   \
		 .--.
		|o_o |
		|:_/ |
   	       //   \ \
              (|     | )
	     /'\_   _/`\
	     \___)=(___/

*/

const int N = 800 * 1000 + 1000,
            K = 30;
vector<pair<int, string> > adj[N];
int f[N], next[N][K],
    m, ans;
void dfs(int p, int curr = 0){
    int c = curr;
    for(auto q : adj[p]){
        curr = c;
        for(int i = 0; i < q.S.size(); i++){
            if(curr == m)
                ans++;
            curr = next[curr][q.S[i] - 'a'];
        }
        if(curr == m)
            ans++;
        dfs(q.F, curr);
    }
}

int32_t main() {
    ios::sync_with_stdio(false);
    cin.tie(0);

    int n;
    cin >> n;
    for(int i = 0; i < n - 1; i++){
        int p;
        string s;
        cin >> p >> s;
        adj[p].pb({i + 2, s});
    }

    string t;
    cin >> t;
    m = t.size();

    for(int i = 0; i <= m; i++){
        for(int j = 0; j < K; j++){
            if(i != m && t[i] - 'a' == j){
                next[i][j] = i + 1;
                if(i != 0)
                    f[i + 1] = next[f[i]][t[i] - 'a'];
            }
            else{
                if(i != 0){
                    next[i][j] = next[f[i]][j];
                }
            }
        }
    }

    dfs(1);
    cout << ans << '\n';
    return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#define LL long long

char inp[300005];
int n,m;
vector < int > son[300005], nex[300005];
string str[300005];
string pat;
int mo = 1e9 + 7;
int base = 999999937;
int po[300005];
int ipo[300005];
int pa[20][300005];
int idx = 0, go[27][300005];
int HashTable[300005];
int HashPattern;

int expo( int a, int b ){
	if ( b == 0 ) return 1;
	if ( b == 1 ) return a % mo;
	int half = expo(a,b/2);
	half = ( 1LL * half * half ) % mo;
	if ( b & 1 ) half = ( 1LL * half * a ) % mo;
	return half;
}

void dfs( int u , int cur,  int H , int dep){
	for ( int v : son[u] ){
		int len = str[v].size();
		int Hash = H;
		int Next = cur;
		for ( int i = 0; i < len; i++ ){
			Hash = ( Hash + ((1LL * po[dep+i] * str[v][i])%mo) ) % mo;
			++idx;
			pa[0][idx] = Next;
			nex[Next].push_back(idx);
			HashTable[idx] = Hash;
			for ( int j = 1; j < 20; j++ ){
				if ( pa[j-1][idx] != -1 ){
					pa[j][idx] = pa[j-1][pa[j-1][idx]];
				}
			}
			Next = idx;
		}
		dfs(v, Next, Hash, dep + len);
	}
}

int recursive( int cur, int dep ){
	int ans = 0;
	for ( int v : nex[cur] ){
		if ( dep >= m ){
			int Hash = HashTable[v];
			int u = v;
			int diff = m;
			for ( int i = 0; i < 20; i++ ){
				if ( (diff>>i) & 1 ){
					u = pa[i][u];
				}
			}

			int HashU = HashTable[u];
			Hash = ( Hash - HashU + mo )%mo;
			Hash = ( Hash * 1LL * ipo[dep-m+1] ) % mo;
			if ( Hash == HashPattern ) ans++;
		}
		if ( dep == m-1 ){
			int Hash = HashTable[v];
			if ( Hash == HashPattern ) ans++;
		}
		ans += recursive(v, dep + 1);
	}
	return ans;
}

int main(){

	po[0] = ipo[0] = 1;
	int invbase = expo(base,mo-2);
	for ( int i = 1; i <= 300000; i++ ){
		po[i] = ( 1LL * po[i-1] * base ) % mo;
		ipo[i] = ( 1LL * ipo[i-1] * invbase ) % mo;
	}
	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 2; i <= n; i++ ){
		int p;
		scanf("%d%s",&p,&inp);
		str[i] = inp;
		son[p].push_back(i);
	}
	scanf("%s",&inp);
	pat = inp;
	m = strlen(inp);
	HashPattern = 0;
	for ( int i = 0; i < m; i++ ){
		HashPattern = ( HashPattern + ((1LL * po[i] * pat[i])%mo) ) %mo;
	}

	dfs(1,0,0,0);
	printf("%d\n",recursive(0,0));
	return 0;
}


#include <cstdio>
#include <cstring>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
#define LL long long

char inp[300005];
int n,m;
vector < int > son[300005], nex[300005];
string str[300005];
string pat;
int mo = 1e9 + 7;
int base = 999999937;
int po[300005];
int ipo[300005];
int pa[20][300005];
int idx = 0, go[27][300005];
int HashTable[300005];
int HashPattern;

int expo( int a, int b ){
	if ( b == 0 ) return 1;
	if ( b == 1 ) return a % mo;
	int half = expo(a,b/2);
	half = ( 1LL * half * half ) % mo;
	if ( b & 1 ) half = ( 1LL * half * a ) % mo;
	return half;
}

void dfs( int u , int cur,  int H , int dep){
	for ( int v : son[u] ){
		int len = str[v].size();
		int Hash = H;
		int Next = cur;
		for ( int i = 0; i < len; i++ ){
			Hash = ( Hash + ((1LL * po[dep+i] * str[v][i])%mo) ) % mo;
			++idx;
			pa[0][idx] = Next;
			nex[Next].push_back(idx);
			HashTable[idx] = Hash;
			for ( int j = 1; j < 20; j++ ){
				if ( pa[j-1][idx] != -1 ){
					pa[j][idx] = pa[j-1][pa[j-1][idx]];
				}
			}
			Next = idx;
		}
		dfs(v, Next, Hash, dep + len);
	}
}

int recursive( int cur, int dep ){
	int ans = 0;
	for ( int v : nex[cur] ){
		if ( dep >= m ){
			int Hash = HashTable[v];
			int u = v;
			int diff = m;
			for ( int i = 0; i < 20; i++ ){
				if ( (diff>>i) & 1 ){
					u = pa[i][u];
				}
			}

			int HashU = HashTable[u];
			Hash = ( Hash - HashU + mo )%mo;
			Hash = ( Hash * 1LL * ipo[dep-m+1] ) % mo;
			if ( Hash == HashPattern ) ans++;
		}
		if ( dep == m-1 ){
			int Hash = HashTable[v];
			if ( Hash == HashPattern ) ans++;
		}
		ans += recursive(v, dep + 1);
	}
	return ans;
}

int main(){

	po[0] = ipo[0] = 1;
	int invbase = expo(base,mo-2);
	for ( int i = 1; i <= 300000; i++ ){
		po[i] = ( 1LL * po[i-1] * base ) % mo;
		ipo[i] = ( 1LL * ipo[i-1] * invbase ) % mo;
	}
	memset(pa,-1,sizeof(pa));
	scanf("%d",&n);
	for ( int i = 2; i <= n; i++ ){
		int p;
		scanf("%d%s",&p,&inp);
		str[i] = inp;
		son[p].push_back(i);
	}
	scanf("%s",&inp);
	pat = inp;
	m = strlen(inp);
	HashPattern = 0;
	for ( int i = 0; i < m; i++ ){
		HashPattern = ( HashPattern + ((1LL * po[i] * pat[i])%mo) ) %mo;
	}

	dfs(1,0,0,0);
	// cout << idx << endl;
	printf("%d\n",recursive(0,0));
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = q;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i < st.size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i < st.size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i + 1 < st.size() && !v[x].size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i + 1 < st.size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
#define f first
#define s second
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, string s, int sz)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        for(int i=s.size()-sz+1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0) q = pi[q];
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, string st, int sz)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p = get_ans(q,st,sz);
        answ += p.first;
        for(int i=0; i<v[x].size(); i++)
        {
                string s1 = st + v[x][i].second;
                dfs(v[x][i].f,p.second,s1,v[x][i].second.size());
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,1,"",1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0) q = pi[q];
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,1,0,0);
        cout << answ;
}


#include<bits/stdc++.h>
#define f first
#define s second
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
int get_ans(int sz,string s)
{
        int q = 1,ans = 0;
        for(int i=1; i<=sz; i++)
        {
                while(s[i-1] - st[q] && q > 0) q = pi[q];
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans ++,q = pi[q];
        }
        //cout << sz << " " << s << endl << ans << endl;
        return ans;
}
void dfs(int x, string st2)
{
        if(fix[x]) return;
        fix[x] = 1;
        //cout << x << " " << st2 << endl;
        if(!v[x].size())
        {
                //cout << x << endl;
                answ += get_ans(st2.size(),st2);
        }
        for(int i=0; i<v[x].size(); i++)
        {
                string s1 = st2 + v[x][i].s;
                dfs(v[x][i].f,s1);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,"");
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i + 1 < st.size() || !v[x].size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = q;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i - 1 < st.size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i - 1 < st.size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0) q = pi[q];
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include<bits/stdc++.h>
using namespace std;
int answ,n,x,q,pi[1000001],fix[2000001];
string st1,st;
vector<pair<int,string>> v[2000001];
pair <int,int> get_ans(int q, int pr, int x)
{
        pair <int,int> ans;
        ans.first = 0;
        ans.second = 0;
        string s = v[pr][x].second;
        for(int i=1; i<=s.size(); i++)
        {
                while(s[i-1] - st[q] && q > 0){ q = pi[q]; if(q + s.size() - i + 1 < st.size() && !v[v[pr][x].first].size()) break; }
                if(st[q] == s[i-1]) q ++;
                if(q == st.size()) ans.first ++,q = pi[q];
        }
        ans.second = q;
        return ans;
}
void dfs(int x, int q, int pr, int idx)
{
        if(fix[x]) return;
        fix[x] = 1;
        pair<int,int> p;
        if(pr)
        {
                p = get_ans(q,pr,idx);
                answ += p.first;
        }
        else p.second = q;
        for(int i=0; i<v[x].size(); i++)
        {
                dfs(v[x][i].first,p.second,x,i);
        }
}
int main()
{
        cin >> n;
        for(int i=1; i<n; i++)
        {
                cin >> x >> st1;
                v[x].push_back({i+1,st1});
        }
        cin >> st;
        pi[1] = 0, q = 0;
        for(int i=2; i<=st.size(); i++)
        {
                while(st[i-1] - st[q] && q > 0)
                        q = pi[q];
                if(st[q] == st[i-1]) q ++;
                pi[i] = q;
        }
        dfs(1,0,0,1);
        cout << answ;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int MAXN = 3e5 + 10;
vector<pair<string, int> > ch[MAXN];
int nxt[MAXN][27], n, gp, ans;
string t;
void adds(string &tmp) {
	for (int i = 0; i < tmp.size(); i++) {
		if (gp == t.size() - 1 && tmp[i] == t.back())
			ans++;
		gp = nxt[gp][tmp[i] - 'a'];
	}
}

void dfs(int v, int p) {
	for (int i = 0; i < ch[v].size(); i++) {
		gp = p;
		adds(ch[v][i].first);
		dfs(ch[v][i].second, gp);
	}
}

int main() {
	cin >> n;
	for (int i = 2; i <= n; i++) {
		string tmp;
		int r;
		cin >> r >> tmp;
		ch[r].push_back({ tmp, i });
	}
	cin >> t;
	nxt[0][t[0] - 'a'] = 1;
	int cp = 0;
	for (int i = 1; i <= t.size(); i++) {
		for (char c = 'a'; c <= 'z'; c++) {
			if (t[cp] == c)
				nxt[i][c - 'a'] = cp + 1;
			else
				nxt[i][c - 'a'] = nxt[cp][c - 'a'];
		}
		if (i < t.size()) {
			nxt[i][t[i] - 'a'] = i + 1;
			if (t[cp] == t[i])
				cp++;
			else
				cp = nxt[cp][t[i] - 'a'];
		}
	}
	dfs(1, 0);
	cout << ans;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int MAXN = 3e5 + 10;
vector<pair<string, int> > ch[MAXN];
int nxt[MAXN][27], n, gp, ans;
string t;
void adds(string &tmp) {
	for (int i = 0; i < tmp.size(); i++) {
		if (gp == t.size() - 1 && tmp[i] == t.back())
			ans++;
		gp = nxt[gp][tmp[i] - 'a'];
	}
}

void dfs(int v, int p) {
	for (int i = 0; i < ch[v].size(); i++) {
		gp = p;
		adds(ch[v][i].first);
		dfs(ch[v][i].second, gp);
	}
}

int main() {
	cin >> n;
	for (int i = 2; i <= n; i++) {
		string tmp;
		int r;
		cin >> r >> tmp;
		ch[r].push_back({ tmp, i });
	}
	cin >> t;
	nxt[0][t[0] - 'a'] = 1;
	int cp = 0;
	for (int i = 1; i <= t.size(); i++) {
		for (char c = 'a'; c <= 'z'; c++) {
			if (t[cp] == c)
				nxt[i][c - 'a'] = cp + 1;
			else
				nxt[i][c - 'a'] = nxt[cp][c - 'a'];
		}
		if (i < t.size()) {
			nxt[i][t[i] - 'a'] = i + 1;
			if (t[cp] == t[i] - 'a')
				cp++;
			else
				cp = nxt[cp][t[i] - 'a'];
		}
	}
	dfs(1, 0);
	cout << ans;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int MAXN = 3e5 + 10;
vector<pair<string, int> > ch[MAXN];
int nxt[MAXN][27], n, gp, ans;
string t;
void adds(string &tmp) {
	for (int i = 0; i < tmp.size(); i++) {
		gp = nxt[gp][tmp[i] - 'a'];
		if (gp == t.size())
			ans++;
	}
}

void dfs(int v, int p) {
	for (int i = 0; i < ch[v].size(); i++) {
		gp = p;
		adds(ch[v][i].first);
		dfs(ch[v][i].second, gp);
	}
}

int main() {
	cin >> n;
	for (int i = 2; i <= n; i++) {
		string tmp;
		int r;
		cin >> r >> tmp;
		ch[r].push_back({ tmp, i });
	}
	cin >> t;
	nxt[0][t[0] - 'a'] = 1;
	int cp = 0;
	for (int i = 1; i <= t.size(); i++) {
		for (char c = 'a'; c <= 'z'; c++) {
			if (t[cp] == c)
				nxt[i][c - 'a'] = cp + 1;
			else
				nxt[i][c - 'a'] = nxt[cp][c - 'a'];
		}
		if (i < t.size()) {
			nxt[i][t[i] - 'a'] = i + 1;
			if (t[cp] == t[i])
				cp++;
			else
				cp = nxt[cp][t[i] - 'a'];
		}
	}
	dfs(1, 0);
	cout << ans;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

const int MAXN = 1e5 + 10;
vector<pair<string, int> > ch[MAXN];
int nxt[MAXN][30], n, gp, ans;
string t;
void adds(string &tmp) {
	for (int i = 0; i < tmp.size(); i++) {
		if (gp == t.size() - 1 && tmp[i] == t.back())
			ans++;
		gp = nxt[gp][tmp[i] - 'a'];
	}
}

void dfs(int v, int p) {
	for (int i = 0; i < ch[v].size(); i++) {
		gp = p;
		adds(ch[v][i].first);
		dfs(ch[v][i].second, gp);
	}
}

int main() {
	cin >> n;
	for (int i = 2; i <= n; i++) {
		string tmp;
		int r;
		cin >> r >> tmp;
		ch[r].push_back({ tmp, i });
	}
	cin >> t;
	nxt[0][t[0] - 'a'] = 1;
	int cp = 0;
	for (int i = 1; i <= t.size(); i++) {
		for (char c = 'a'; c <= 'z'; c++) {
			if (t[cp] == c)
				nxt[i][c - 'a'] = cp + 1;
			else
				nxt[i][c - 'a'] = nxt[cp][c - 'a'];
		}
		if (i < t.size()) {
			nxt[i][t[i] - 'a'] = i + 1;
			if (t[cp] == t[i] - 'a')
				cp++;
			else
				cp = nxt[cp][t[i] - 'a'];
		}
	}
	dfs(1, 0);
	cout << ans;
}


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

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
	ost<<"{"<<p.first<<","<<p.second<<"}";
	return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
	ost<<"{";
	for(int i=0;i<v.size();i++){
		if(i)ost<<",";
		ost<<v[i];
	}
	ost<<"}";
	return ost;
}

struct ModX{
	using ull=uint64_t;
	static const ull mod=(1ll<<61)-1;
	static const ull MASK30=(1ll<<30)-1;
	static const ull MASK31=(1ll<<31)-1;

	ull a;

	ModX& s(ull vv){
		a=vv<mod?vv:vv-mod;
		return *this;
	}
	ModX(ull a=0):a(a%mod){}

	ModX& operator+=(const ModX& x){return s(a+x.a);}
	ModX& operator-=(const ModX& x){return s(a+mod-x.a);}
	ModX& operator*=(const ModX& x){
		const ull au=a>>31;
		const ull ad=a&MASK31;
		const ull bu=x.a>>31;
		const ull bd=x.a&MASK31;
		const ull mid=ad*bu+au*bd;
		const ull midu=mid>>30;
		const ull midd=mid&MASK30;
		const ull z=au*bu*2+midu+(midd<<31)+ad*bd;
		return s((z&mod)+(z>>61));
	}

	ModX operator+(const ModX &x)const{return ModX(*this)+=x;}
	ModX operator-(const ModX &x)const{return ModX(*this)-=x;}
	ModX operator*(const ModX &x)const{return ModX(*this)*=x;}

	bool operator==(const ModX &x)const{return a==x.a;}
	bool operator!=(const ModX &x)const{return a!=x.a;}
	bool operator<(const ModX &x)const{return a<x.a;}

	ModX operator-()const{return ModX()-*this;}
};

istream& operator>>(istream& in,const ModX& a){
	return (in>>a.a);
}

ostream& operator<<(ostream& out,const ModX& a){
	return (out<<a.a);
}
using xint=ModX;
const xint base(119);
const int RHSIZE=1111111;
xint basepow[RHSIZE];
struct RHInit{
	RHInit(){
		basepow[0]=1;
		for(int i=1;i<RHSIZE;i++)basepow[i]=basepow[i-1]*base;
	}
}RHInitDummy;

template<class T>
vector<xint>calcHash(const T &v){
	vector<xint>hs(v.size()+1);
	for(int i=0;i<v.size();i++){
		hs[i+1]=hs[i]*base+v[i];
	}
	return hs;
}

int N;
string S[111111];
string T;

xint hst;
vint G[111111];
vector<xint>H;
int dfs(int v){
	int ret=0;
	for(auto u:G[v]){
		for(auto c:S[u]){
			H.pb(H.back()*base+c);
			if(H.size()>T.size()&&H.back()-H[H.size()-1-T.size()]*basepow[T.size()]==hst)ret++;
		}
		ret+=dfs(u);
		rep(i,S[u].size())H.pop_back();
	}
	return ret;
}

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

	cin>>N;
	for(int i=1;i<N;i++){
		int p;
		cin>>p>>S[i];
		p--;
		G[p].pb(i);
	}
	cin>>T;

	hst=calcHash(T)[T.size()];
	H.pb(0);
	cout<<dfs(0)<<endl;
	return 0;
}


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

#define int long long

#define rep(i,n) for(int i=0;i<(n);i++)
#define pb push_back
#define eb emplace_back
#define all(v) (v).begin(),(v).end()
#define fi first
#define se second
typedef vector<int>vint;
typedef pair<int,int>pint;
typedef vector<pint>vpint;

template<typename A,typename B>inline void chmin(A &a,B b){if(a>b)a=b;}
template<typename A,typename B>inline void chmax(A &a,B b){if(a<b)a=b;}

template<class A,class B>
ostream& operator<<(ostream& ost,const pair<A,B>&p){
	ost<<"{"<<p.first<<","<<p.second<<"}";
	return ost;
}

template<class T>
ostream& operator<<(ostream& ost,const vector<T>&v){
	ost<<"{";
	for(int i=0;i<v.size();i++){
		if(i)ost<<",";
		ost<<v[i];
	}
	ost<<"}";
	return ost;
}

struct ModX{
	using ull=uint64_t;
	static const ull mod=(1ll<<61)-1;
	static const ull MASK30=(1ll<<30)-1;
	static const ull MASK31=(1ll<<31)-1;

	ull a;

	ModX& s(ull vv){
		a=vv<mod?vv:vv-mod;
		return *this;
	}
	ModX(ull a=0):a(a%mod){}

	ModX& operator+=(const ModX& x){return s(a+x.a);}
	ModX& operator-=(const ModX& x){return s(a+mod-x.a);}
	ModX& operator*=(const ModX& x){
		const ull au=a>>31;
		const ull ad=a&MASK31;
		const ull bu=x.a>>31;
		const ull bd=x.a&MASK31;
		const ull mid=ad*bu+au*bd;
		const ull midu=mid>>30;
		const ull midd=mid&MASK30;
		const ull z=au*bu*2+midu+(midd<<31)+ad*bd;
		return s((z&mod)+(z>>61));
	}

	ModX operator+(const ModX &x)const{return ModX(*this)+=x;}
	ModX operator-(const ModX &x)const{return ModX(*this)-=x;}
	ModX operator*(const ModX &x)const{return ModX(*this)*=x;}

	bool operator==(const ModX &x)const{return a==x.a;}
	bool operator!=(const ModX &x)const{return a!=x.a;}
	bool operator<(const ModX &x)const{return a<x.a;}

	ModX operator-()const{return ModX()-*this;}
};

istream& operator>>(istream& in,const ModX& a){
	return (in>>a.a);
}

ostream& operator<<(ostream& out,const ModX& a){
	return (out<<a.a);
}
using xint=ModX;
const xint b(119);

xint po[333333];

vector<int>G[333333];
string S[333333];

vector<xint>H;
int ans;
string T;
xint hst;
void dfs(int v){
	for(auto u:G[v]){
		for(auto c:S[u]){
			H.pb(H.back()*b+c);
			if(H.size()>T.size()){
				auto h=H.back()-H[H.size()-1-T.size()]*po[T.size()];
				if(h==hst)ans++;
			}
		}

		dfs(u);
		rep(i,S[u].size())H.pop_back();
	}
}

signed main(){
	cin.tie(0);
	ios_base::sync_with_stdio(0);
	po[0]=1;
	for(int i=1;i<333333;i++)po[i]=po[i-1]*b;

	int N;cin>>N;
	for(int i=1;i<N;i++){
		int p;
		cin>>p>>S[i];
		p--;
		G[p].pb(i);
	}
	H.pb(0);
	cin>>T;
	hst=0;
	rep(i,T.size())hst=hst*b+T[i];
	dfs(0);

	cout<<ans<<endl;
	return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<int> adj[100005];
string str[100005],pat;
int lps[300005],res;
char txt[300005];
pair<int,int> A[100005];
void LPS()
{
    int len=0,i=1;
    lps[0]=0;
    while (i < pat.length())
    {
       if (pat[i] == pat[len])
       {
         len++;
         lps[i] = len;
         i++;
       }
       else
       {
         if (len != 0)
           len = lps[len-1];
         else
         {
           lps[i] = 0;
           i++;
         }
       }
    }
}
void KMP(int v,int p)
{
    int i,j;
    for(i=0,j=A[p].second;i<str[v].length();i++,j++)
        txt[j]=str[v][i];
    A[v].second=j;
    j=A[p].first;
    for(i=A[p].second;i<A[v].second;)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == pat.length())
        {
            res++;
            j = lps[j-1];
        }
        else if (i < A[v].second && pat[j] != txt[i])
        {
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    A[v].first=j;
    for(i=0;i<adj[v].size();i++)
        if(adj[v][i]!=p)
            KMP(adj[v][i],v);
}
char s[300005];
int main()
{
    int n,i,u;
    scanf("%d",&n);
    for(i=2;i<=n;i++)
    {
        scanf("%d%s",&u,s);
        string s2(s);
        str[i]=s2;
        adj[i].push_back(u);
        adj[u].push_back(i);
    }
    scanf("%s",s);
    string s2(s);
    pat=s2;
    LPS();
    KMP(1,0);
    printf("%d",res);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<int> adj[100005];
string str[100005],pat;
int lps[300005],res;
char txt[300005];
pair<int,int> A[100005];
void LPS()
{
    int len=0,i=1;
    lps[0]=0;
    while (i < pat.length())
    {
       if (pat[i] == pat[len])
       {
         len++;
         lps[i] = len;
         i++;
       }
       else
       {
         if (len != 0)
           len = lps[len-1];
         else
         {
           lps[i] = 0;
           i++;
         }
       }
    }
}
void KMP(int v,int p)
{
    int i,j;
    for(i=0,j=A[p].second;i<str[v].length();i++,j++)
        txt[j]=str[v][i];
    A[v].second=j;
    j=A[p].first;
    for(i=A[p].second;i<A[v].second;)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == pat.length())
        {
            res++;
            j = lps[j-1];
        }
        else if (i < A[v].second && pat[j] != txt[i])
        {
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    A[v].first=j;
    for(i=0;i<adj[v].size();i++)
        if(adj[v][i]!=p)
            KMP(adj[v][i],v);
}
int main()
{
    int n,i,u;
    cin>>n;
    for(i=2;i<=n;i++)
    {
        cin>>u>>str[i];
        adj[i].push_back(u);
        adj[u].push_back(i);
    }
    cin>>pat;
    LPS();
    KMP(1,0);
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long       ll;
typedef pair<int,int>   pii;
typedef vector<int>     vi;
typedef long double     ld;
#define MOD         1000000007
#define pb          push_back
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define endl        '\n'
#define PI          3.14159265359d
#define sz(x)       (int)x.size()
vi adj[100005];
int lps[300005],res;
string A[100005],pat;
void LPS(){
    int len=0,i=1;
    while(i<sz(pat)){
        if (pat[i]==pat[len])
            lps[i++]=++len;
        else if(len)
            len=lps[len-1];
        else
            lps[i++]=0;
    }
}
void dfs(int u,int j)
{
    for(auto c:A[u])
    {
        while(j&&(j==sz(pat)||pat[j]!=c))
            j=lps[j-1];
        if(pat[j]==c)
            j++;
        if(j==sz(pat))
            res++;
    }
    for(auto i:adj[u])
        dfs(i,j);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,i,p;
    cin>>n;
    for(i=2;i<=n;i++)
    {
        cin>>p>>A[i];
        adj[p].pb(i);
    }
    cin>>pat;
    LPS();
    dfs(1,0);
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long       ll;
typedef pair<int,int>   pii;
typedef vector<int>     vi;
typedef long double     ld;
#define MOD         1000000007
#define pb          push_back
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define endl        '\n'
#define PI          3.14159265359d
#define sz(x)       (int)x.size()
vi adj[100005];
int lps[300005],go[300005][26],res;
string A[100005],pat;
void LPS(){
    int len=0,i=1;
    while(i<sz(pat)){
        if (pat[i]==pat[len])
            lps[i++]=++len;
        else if(len)
            len=lps[len-1];
        else
            lps[i++]=0;
    }
}
void dfs(int u,int j)
{
    for(auto c:A[u])
    {
        j=go[j][c-'a'];
        if(j==sz(pat))
            res++;
    }
    for(auto i:adj[u])
        dfs(i,j);
}
int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    int n,i,j,p;
    cin>>n;
    for(i=2;i<=n;i++)
    {
        cin>>p>>A[i];
        adj[p].pb(i);
    }
    cin>>pat;
    LPS();
    for(i=0;i<=sz(pat);i++)
        for(j=0;j<26;j++)
            if(i<sz(pat)&&pat[i]==(char)(j+'a'))
                go[i][j]=i+1;
            else
                go[i][j]=go[lps[i-1]][j];
    dfs(1,0);
    cout<<res;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define ll long long
vector<int> adj[100005];
string str[100005],pat;
int lps[100005],res;
char txt[300005];
pair<int,int> A[100005];
void LPS()
{
    int len=0,i=1;
    lps[0]=0;
    while (i < pat.length())
    {
       if (pat[i] == pat[len])
       {
         len++;
         lps[i] = len;
         i++;
       }
       else
       {
         if (len != 0)
           len = lps[len-1];
         else
         {
           lps[i] = 0;
           i++;
         }
       }
    }
}
void KMP(int v,int p)
{
    int i,j;
    for(i=0,j=A[p].second;i<str[v].length();i++,j++)
        txt[j]=str[v][i];
    A[v].second=j;
    j=A[p].first;
    for(i=A[p].second;i<A[v].second;)
    {
        if (pat[j] == txt[i])
        {
            j++;
            i++;
        }
        if (j == pat.length())
        {
            res++;
            j = lps[j-1];
        }
        else if (i < A[v].second && pat[j] != txt[i])
        {
            if (j != 0)
                j = lps[j-1];
            else
                i = i+1;
        }
    }
    A[v].first=j;
    for(i=0;i<adj[v].size();i++)
        if(adj[v][i]!=p)
            KMP(adj[v][i],v);
}
int main()
{
    int n,i,u;
    cin>>n;
    for(i=2;i<=n;i++)
    {
        cin>>u>>str[i];
        adj[i].push_back(u);
        adj[u].push_back(i);
    }
    cin>>pat;
    LPS();
    KMP(1,0);
    cout<<res;
    return 0;
}


#include <bits/stdc++.h>

struct Solver
{
  Solver(int n) : child(n)
  {
    for (int i = 1, p; i < n; ++ i) {
      std::string s;
      std::cin >> p >> s;
      child[p - 1].emplace_back(i, s);
    }
    std::string p;
    std::cin >> p;
    m = p.size();
    go.resize(m + 1);
    std::vector<int> fail(m + 1);
    go[0][p[0] - 'a'] = 1;
    fail[1] = 0;
    for (int i = 1; i <= m; ++ i) {
      go[i] = go[fail[i]];
      int ch = p[i] - 'a';
      if (i < m) {
        go[i][ch] = i + 1;
        fail[i + 1] = go[fail[i]][ch];
      }
    }
    dfs(0, 0, "");
  }

  void dfs(int u, int p, const std::string& s)
  {
    for (auto&& c : s) {
      p = go[p][c - 'a'];
      result += p == m;
    }
    for (auto&& e : child[u]) {
      dfs(e.first, p, e.second);
    }
  }

  int m, result = 0;
  std::vector<std::vector<std::pair<int, std::string>>> child;
  std::vector<std::array<int, 26>> go;
};

int main()
{
  std::ios::sync_with_stdio(false);
  int n;
  while (std::cin >> n) {
    Solver solver(n);
    std::cout << solver.result << std::endl;
  }
}


#include<bits/stdc++.h>
using namespace std;
#define endl '\n'

vector<int> prefixFunctionKMP(string cadena){
	vector<int> prefixFunction(cadena.size());
	prefixFunction[0] = 0;
	for(int i=1,j=0; i<cadena.size(); i++){
		while(j > 0 && cadena[i] != cadena[j]){
			j = prefixFunction[j-1];
		}
		if(cadena[i] == cadena[j])
		j++;
		prefixFunction[i] = j;
	}
	return prefixFunction;
}

string patron;
vector<int> prefix;
vector<int> link[26];
const int maxNodos = 101000;
long long ans = 0;
vector<int> grafo[maxNodos+1];
vector<string> cadenas(maxNodos+1);

void solver(int x, int j){
	for(int i=0; i<cadenas[x].size(); i++){
		if(j > 0 && cadenas[x][i] != patron[j])
		j = link[cadenas[x][i]-'a'][j-1];

		if(cadenas[x][i] == patron[j])
		j++;
		if(j == patron.size()){
			j = prefix[j-1];
			ans++;
		}
	}
	for(int i=0; i<grafo[x].size(); i++){
		int y = grafo[x][i];
		solver(y, j);
	}
}

void generarLink(){
	for(int j=0; j<26; j++){
		for(int i=0; i<patron.size(); i++)
		link[j].push_back(0);
	}
	for(int j=0; j<26; j++){
		if(patron.size() > 0 && patron[1]-'a' == j)
		link[j][0] = 1;
	}
	for(int i=1; i<patron.size(); i++){
		int l = prefix[i] - 1;
		for(int j=0; j<26; j++){
			if((i+1 < patron.size()) && (patron[i+1]-'a' == j))
			link[j][i] = i+1;
			else{
				if(l < 0)
				link[j][i] = 0;
				else
				link[j][i] = link[j][l];
			}
		}
	}
}

int main(){
	ios_base::sync_with_stdio(0);cin.tie(NULL);
	int n,x,i;
	cin>>n;
	for(i=2; i<=n; i++){
		cin>>x>>cadenas[i];
		grafo[x].push_back(i);
	}
	cin>>patron;
	prefix = prefixFunctionKMP(patron);
	generarLink();
	solver(1,0);
	cout<<ans<<endl;
}


#include <bits/stdc++.h>

using namespace std;
const int N=3e5+5;
string s[N];
int lp[N];
vector<int> adj[N];
string t;
int ans;
void ff(string t)
{
    for(int i=1,k=0;i<t.size();i++)
    {
        while(k>0&&t[i]!=t[k])
            k=lp[k-1];
        if(t[i]==t[k])
            k++;
        lp[i]=k;
    }
}
void solve(int u,int k)
{
    //cout<<u<<" "<<k<<endl;
    for(auto c:s[u])
    {
        while(k>0&&c!=t[k])
            k=lp[k-1];
        if(c==t[k])
            k++;
        if(k==(int)t.size())
        {
            ans++;
            k=lp[k-1];
        }
    }
    for(auto v:adj[u])
        solve(v,k);
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int p;
        cin>>p>>s[i];
        adj[p].push_back(i);
    }
    cin>>t;
    ff(t);
    solve(1,0);
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N=3e5+5;
string s[N];
int lp[N];
vector<int> adj[N];
string t;
int ans;
inline void ff()
{
    for(int i=1,k=0;i<t.size();i++)
    {
        while(k>0&&t[i]!=t[k])
            k=lp[k-1];
        if(t[i]==t[k])
            k++;
        lp[i]=k;
    }
}
inline void solve(int u,int k)
{
    for(auto c:s[u])
    {
        while(k>0&&c!=t[k])
            k=lp[k-1];
        if(c==t[k])
            k++;
        if(k==(int)t.size())
        {
            ans++;
            k=lp[k-1];
        }
    }
    for(auto v:adj[u])
        solve(v,k);
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int p;
        cin>>p>>s[i];
        adj[p].push_back(i);
    }
    cin>>t;
    ff();
    solve(1,0);
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N=3e5+5;
string s[N];
int lp[N],dp[50][50];
vector<int> adj[N];
string t;
int ans;
inline int PF(char c,int k)
{
    int &ret=dp[c-'a'][k];
    if(~ret) return ret;
    while(k&&c!=t[k])
        k=lp[k-1];
    if(c==t[k])
        k++;
    return ret=k;
}
inline void ff()
{
    for(int i=1,k=0;i<t.size();i++)
    {
        k=PF(t[i],k);
        lp[i]=k;
    }
}
inline void solve(int u,int k)
{
    for(auto c:s[u])
    {
        k=PF(c,k);
        if(k==(int)t.size())
        {
            ans++;
            k=lp[k-1];
        }
    }
    for(auto v:adj[u])
        solve(v,k);
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    memset(dp,-1,sizeof dp);
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int p;
        cin>>p>>s[i];
        adj[p].push_back(i);
    }
    cin>>t;
    ff();
    solve(1,0);
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N=3e5+5;
string s[N];
int lp[N],dp[50][N];
vector<int> adj[N];
string t;
int ans;
inline int PF(char c,int k)
{
    int &ret=dp[c-'a'][k];
    if(~ret) return ret;
    while(k&&c!=t[k])
        k=lp[k-1];
    if(c==t[k])
        k++;
    return ret=k;
}
inline void ff()
{
    for(int i=1,k=0;i<t.size();i++)
    {
        k=PF(t[i],k);
        lp[i]=k;
    }
}
inline void solve(int u,int k)
{
    for(auto c:s[u])
    {
        k=PF(c,k);
        if(k==(int)t.size())
        {
            ans++;
            k=lp[k-1];
        }
    }
    for(auto v:adj[u])
        solve(v,k);
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    memset(dp,-1,sizeof dp);
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int p;
        cin>>p>>s[i];
        adj[p].push_back(i);
    }
    cin>>t;
    ff();
    solve(1,0);
    cout<<ans<<endl;
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
const int N=3e5+5;
string s[N];
int lp[N];
vector<int> adj[N];
string t;
long long ans;
void ff(string t)
{
    for(int i=1,k=0;i<t.size();i++)
    {
        while(k>0&&t[i]!=t[k])
            k=lp[k-1];
        if(t[i]==t[k])
            k++;
        lp[i]=k;
    }
}
void solve(int u,int k)
{
    //cout<<u<<" "<<k<<endl;
    for(auto c:s[u])
    {
        while(k>0&&c!=t[k])
            k=lp[k-1];
        if(c==t[k])
            k++;
        if(k==(int)t.size())
        {
            ans++;
            k=lp[k-1];
        }
    }
    for(auto v:adj[u])
        solve(v,k);
}
int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    int n;
    cin>>n;
    for(int i=2;i<=n;i++)
    {
        int p;
        cin>>p>>s[i];
        adj[p].push_back(i);
    }
    cin>>t;
    ff(t);
    solve(1,0);
    cout<<ans<<endl;
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
struct st{
  long long q;
  long long w;
  long long e;
};
st str;
vector<st>v[2000001];
string s,t,S;
long long kmp[2000001];
long long n,i,ans,a;
void dfs(int x,int y){
    int k=y;
    for(int r=0;r<v[x].size();r++){
        int y=k;
        for(int i=v[x][r].w;i<v[x][r].e;i++){
            if(s[y] != S[i]){
                if(y != 0)y=kmp[y-1];
            }
            if(s[y] == S[i]){
                y++;
            }
            if(y == s.size()){
                ans++;
                if(y != 0)y=kmp[y-1];
            }
        }
        dfs(v[x][r].q,y);
    }
}
main(){
    cin>>n;
    for(int i=2;i<=n;i++){
        scanf("%d" , &a);
        cin>>t;
        str.w=S.size();
        S=S+t;
        str.q=i;
        str.e=S.size();
        v[a].push_back(str);
    }
    cin>>s;
    int j=0;
    for(int i=1;i<s.size();i++){
        if(j == s.size() - 1)break;
        if(s[i] == s[j]){
            kmp[i]=++j;
        }
        else{
            if(j != 0)j=kmp[j-1];
        }
    }
    dfs(1,0);
    cout<<ans<<endl;
}


#include <vector>
#include<iostream>
#include<cstring>
using namespace std;
struct st{
  int v,a,b;
};

st str;
vector<st>gr[1000001];
char S[300002],P[100002];
int kmp[1000001];
int n,i,ans,a,m,u;

void dfs(int u,int q){
    int q0=q;

    for(int r=0;r<gr[u].size();r++){
        int q=q0,v=gr[u][r].v;
        for(int i=gr[u][r].a;i<gr[u][r].b;i++){
            while (P[q+1] != S[i] && q > 0){
                q=kmp[q];
                if (gr[v].size()==0 && q+gr[u][r].b-i<m) break;
            }
            if (P[q+1] == S[i])
                q++;
            if(q == m){
                ans++;
                q=kmp[q];
            }
        }
        dfs(v,q);
    }
}
main(){
    scanf("%d",&n);
    for(int i=2;i<=n;i++){
        scanf("%d %s",&u,S+a);
        int l=strlen(S+a);
        str.v=i;
        str.a=a; str.b=a+l;
        gr[u].push_back(str);
        a+=l;
    }
    scanf("%s",P+1); P[0]='#'; m=strlen(P)-1;
    int q=0; kmp[1]=0;
    for(int i=2;i<=m;i++){
        while (P[q+1]!=P[i] && q>0) q=kmp[q];
        if(P[q+1] == P[i]) q++;
        kmp[i]=q;
    }

    dfs(1,0);
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
struct st{
  long long q;
  long long w;
  long long e;
};
st str;
vector<st>v[2000001];
string s,t,S;
long long kmp[2000001];
long long n,i,ans,a;
void dfs(int x,int y){
    int k=y;
    for(int r=0;r<v[x].size();r++){
        int y=k;
        for(int i=v[x][r].w;i<v[x][r].e;i++){
            while (s[y] != S[i] && y > 0){
                y=kmp[y-1];
                if(v[x][r].e - i + y < s.size() && v[x].size() == 0) break;
            }
            if (s[y] == S[i])
                y++;
            if(y == s.size()){
                ans++;
                y=kmp[y-1];
            }
        }
        dfs(v[x][r].q,y);
    }
}
main(){
    cin>>n;
    for(int i=2;i<=n;i++){
        cin>>a>>t;
        str.w=S.size();
        S=S+t;
        str.q=i;
        str.e=S.size();
        v[a].push_back(str);
    }
    cin>>s;
    int j=0;
    for(int i=1;i<s.size();i++){
        if(j == s.size() - 1)break;
        if(s[i] == s[j]){
            kmp[i]=++j;
        }
        else{
            if(j != 0)j=kmp[j-1];
        }
    }
    dfs(1,0);
    cout<<ans<<endl;
}


#include<bits/stdc++.h>
using namespace std;
struct st{
  long long q;
  long long w;
  long long e;
};
st str;
vector<st>v[2000001];
string s,t,S;
long long kmp[2000001];
long long n,i,ans,a;
void dfs(int x,int y){
    int k=y;
    for(int r=0;r<v[x].size();r++){
        int y=k;
        for(int i=v[x][r].w;i<v[x][r].e;i++){
            if(s[y] != S[i]){
                if(y != 0)y=kmp[y-1];
                if(v[x][r].e - i + y < s.size() && v[x].size() == 0) break;
            }
            if(s[y] == S[i]){
                y++;
            }
            if(y == s.size()){
                ans++;
                if(y != 0)y=kmp[y-1];
            }
        }
        dfs(v[x][r].q,y);
    }
}
main(){
    cin>>n;
    for(int i=2;i<=n;i++){
        cin>>a>>t;
        str.w=S.size();
        S=S+t;
        str.q=i;
        str.e=S.size();
        v[a].push_back(str);
    }
    cin>>s;
    int j=0;
    for(int i=1;i<s.size();){
        if(j == s.size() - 1)break;
        if(s[i] == s[j]){
            kmp[i]=++j;
            ++i;
        }
        else{
            if(j != 0)j=kmp[j-1];
            else i++;
        }
    }
    dfs(1,0);
    cout<<ans<<endl;
}