#include <bits/stdc++.h>
using namespace std;
const int INF = 1e9, N = 5e5 + 5;
struct edge {
  int to, nxt, val;
} e[N];
int n, tot, mx, now, head[N];
int D[N], dep[N], son[N], size[N];
int col[1 << 22], ans[N];
void add(int u, int v, int w) {
  e[++tot].to = v;
  e[tot].nxt = head[u];
  e[tot].val = w;
  head[u] = tot;
}
void Dfs(int u) {
  size[u] = 1;
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    D[v] = D[u] ^ (1 << e[i].val);
    dep[v] = dep[u] + 1;
    Dfs(v);
    size[u] += size[v];
    if (!son[u] || size[son[u]] < size[v]) son[u] = v;
  }
}
void cal(int u) {
  if (col[D[u]]) mx = max(mx, dep[u] + col[D[u]] - now);
  for (int i = 0; i < 22; i++)
    if (col[(1 << i) ^ D[u]]) mx = max(mx, dep[u] + col[(1 << i) ^ D[u]] - now);
}
void up(int u) { col[D[u]] = max(dep[u], col[D[u]]); }
void calc(int u) {
  cal(u);
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    calc(v);
  }
}
void upd(int u) {
  up(u);
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    upd(v);
  }
}
void clear(int u) {
  col[D[u]] = 0;
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    clear(v);
  }
}
void dfs(int u, bool keep) {
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if (v != son[u]) dfs(v, 0);
  }
  if (son[u]) dfs(son[u], 1);
  now = dep[u] << 1;
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    mx = max(ans[v], mx);
  }
  for (int i = head[u]; i; i = e[i].nxt) {
    int v = e[i].to;
    if (v != son[u]) {
      calc(v);
      upd(v);
    }
  }
  cal(u);
  up(u);
  ans[u] = mx;
  if (!keep) {
    clear(u);
    mx = 0;
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 2; i <= n; i++) {
    int x;
    char c1, c;
    scanf("%d%c%c", &x, &c1, &c);
    add(x, i, c - 'a');
  }
  Dfs(1);
  dfs(1, 1);
  for (int i = 1; i <= n; i++) printf("%d ", ans[i]);
  return 0;
}
