#include <bits/stdc++.h>
using namespace std;
template <class E = int>
struct graph {
  vector<E> *g;
  int n;
  graph() {}
  graph(int size) {
    n = size;
    g = new vector<E>[n];
    for (int i = 0; i < n; ++i) g[i] = vector<E>();
  }
  inline vector<E> &operator[](int v) { return g[v]; }
  inline int size() { return n; }
};
const int N = 1e5 + 5;
const int L = 19;
long long Xs[] = {1999, 1861, 1091, 1747, 1367, 3389, 3673, 2531, 2803, 3769};
long long Ms[] = {2146150087, 1984063909, 1821235309, 1882018657, 1787222167,
                  1495037567, 1703602067, 1457331299, 1667800973, 1389524111};
struct hasharray {
  char *s;
  long long X1, M1, *p1, *h1;
  long long X2, M2, *p2, *h2;
  hasharray() {}
  hasharray(const char *str, int n) {
    s = new char[n];
    strncpy(s, str, n);
    X1 = Xs[rand() % 10];
    M1 = Ms[rand() % 10];
    do {
      X2 = Xs[rand() % 10];
    } while (X2 == X1);
    do {
      M2 = Ms[rand() % 10];
    } while (M2 == M1);
    int i;
    p1 = new long long[N * 3];
    p2 = new long long[N * 3];
    for (p1[0] = p2[0] = i = 1; i <= N * 3; ++i) {
      p1[i] = 1LL * p1[i - 1] * X1 % M1;
      p2[i] = 1LL * p2[i - 1] * X2 % M2;
    }
    h1 = new long long[n + 1];
    h2 = new long long[n + 1];
    for (h1[0] = h2[0] = s[0], i = 1; i < n; ++i) {
      h1[i] = (1LL * h1[i - 1] * X1 + s[i]) % M1;
      h2[i] = (1LL * h2[i - 1] * X2 + s[i]) % M2;
    }
  }
  inline long long operator()(int l, int r) {
    return (h1[r] - (l ? 1LL * h1[l - 1] * p1[r - l + 1] % M1 : 0) + M1) % M1
               << 32LL |
           (h2[r] - (l ? 1LL * h2[l - 1] * p2[r - l + 1] % M2 : 0) + M2) % M2;
  }
};
hasharray ha;
int n, m;
int i, j, k, l;
string s[N];
int *z1[N], *z2[N], zt1[N * 10], zt2[N * 10];
void zf(string &s, int n, int z[]) {
  int i, j;
  z[0] = j = 0;
  for (i = 1; i < n; ++i) {
    z[i] = max(0, min(z[i - j], j + z[j] - i));
    while (i + z[i] < n && s[z[i]] == s[i + z[i]]) ++z[i];
    if (i + z[i] > j + z[j]) j = i;
  }
}
long long X1 = 911, X2 = 881;
long long M1 = 1e9 + 7, M2 = 1e9 + 9;
graph<int> g;
int p[N][L];
int d[N][L], dp[N];
long long ht1[N], ht2[N];
void dfs(int v, int par = -1) {
  p[v][0] = par;
  d[v][0] = (par == -1 ? 1e9 : s[v].length());
  dp[v] = (par == -1 ? 0 : dp[par]) + s[v].length();
  ht1[v] = (par == -1 ? 0 : ht1[par]);
  ht2[v] = (par == -1 ? 0 : ht2[par]);
  for (int j = 0; j < s[v].length(); ++j) {
    ht1[v] = (ht1[v] * X1 + s[v][j]) % M1;
    ht2[v] = (ht2[v] * X2 + s[v][j]) % M2;
  }
  for (int l = 1; l < L; ++l) {
    d[v][l] = (p[v][l - 1] == -1 ? 1e9 : d[v][l - 1] + d[p[v][l - 1]][l - 1]);
    p[v][l] = (p[v][l - 1] == -1 ? -1 : p[p[v][l - 1]][l - 1]);
  }
  for (typeof((g[v]).begin()) it = (g[v]).begin(); it != (g[v]).end(); it++)
    if (par != *it) dfs(*it, v);
}
int brute(string t) {
  int ans = 0;
  for (i = 1; i < n; ++i) {
    for (j = 0; j < s[i].length(); ++j) {
      int x, y;
      x = i;
      y = j;
      string z = "";
      for (k = 0; k < t.length(); ++k) {
        z = s[x][y] + z;
        --y;
        if (y == -1) {
          x = p[x][0];
          if (x < 0) break;
          y = s[x].length() - 1;
        }
      }
      if (z == t) ++ans;
    }
  }
  return ans;
}
long long hasht(int i, int j) {
  return (ht1[i] - ht1[j] * ha.p1[dp[i] - dp[j]] % M1 + M1) % M1 << 32LL |
         (ht2[i] - ht2[j] * ha.p2[dp[i] - dp[j]] % M2 + M2) % M2;
}
int main() {
  if (0) {
    srand(74747);
    srand(time(0));
    freopen("input.txt", "w", stdout);
    n = (rand() % (100)) + 1;
    cout << n << endl;
    for (i = 1; i < n; ++i) {
      cout << (rand() % (i)) + 1 << ' ';
      l = (rand() % (100)) + 1;
      for (j = 0; j < l; ++j) cout << char((rand() % (3)) + 'a');
      cout << endl;
    }
    l = (rand() % (5)) + 1;
    for (j = 0; j < l; ++j) cout << char((rand() % (3)) + 'a');
    cout << endl;
    fclose(stdout);
    int _tm = clock();
    while ((clock() - _tm) / (double)CLOCKS_PER_SEC < 0.2)
      ;
  }
  srand(time(0));
  cin >> n;
  g = graph<int>(n);
  for (k = 1; k < n; ++k) {
    cin >> l >> s[k];
    --l;
    g[k].push_back(l);
    g[l].push_back(k);
  }
  string t;
  cin >> t;
  ha = hasharray(t.c_str(), t.length());
  X1 = ha.X1;
  X2 = ha.X2;
  M1 = ha.M1;
  M2 = ha.M2;
  string a, b;
  a = b = t;
  reverse(b.begin(), b.end());
  for (i = 1; i < n; ++i) {
    string z = s[i];
    a += (i == 1 ? '$' : '#');
    a += z;
    reverse(z.begin(), z.end());
    b += (i == 1 ? '$' : '#');
    b += z;
  }
  long long ans = 0;
  zf(a, a.length(), zt1);
  for (i = 0; i < a.length(); ++i)
    if (zt1[i] >= t.length()) ++ans;
  int *pt = zt1 + (int)t.length() + 1;
  for (i = 1; i < n; ++i) {
    z1[i] = pt;
    pt += (int)s[i].length() + 1;
  }
  zf(b, b.length(), zt2);
  pt = zt2 + (int)t.length() + 1;
  for (i = 1; i < n; ++i) {
    z2[i] = pt;
    pt += (int)s[i].length() + 1;
  }
  dfs(0);
  for (i = 1; i < n; ++i) {
    int sl = s[i].length();
    for (j = 0; j < sl; ++j) {
      if (sl - j - 1 + z2[i][sl - j - 1] == sl && j < t.length() - 1) {
        int len = t.length() - j - 1;
        k = p[i][0];
        for (l = L - 1; l >= 0; --l)
          if (d[k][l] < len) len -= d[k][l], k = p[k][l];
        if (k) {
          int zl = s[k].length();
          if (zl - len + z1[k][zl - len] == zl &&
              hasht(p[i][0], k) == ha(len, t.length() - j - 2))
            ++ans;
        }
      }
    }
  }
  cout << ans << endl;
  return 0;
}
