// Steins;Gate
#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <string>
#include <vector>
using namespace std;
using ll = long long;
#define INF 0x3f3f3f3f
#define lowbit(x) (x & -x)
#define jiasu ios::sync_with_stdio(false), cin.tie(0), cout.tie(0)
#define rep(i, a, b) for (int i = (a); i <= (b); ++i)
#define don(i, a, b) for (int i = (a); i >= (b); --i)
#define fori(i, a, b) for (int i = (a); i < (b); ++i)
#define mem(x) memset(x, 0, sizeof(x));
#define memmax(x) memset(x, 0x3f, sizeof(x));
using pii = pair<int, int>;
using pq = priority_queue<pii, vector<pii>, greater<pii>>;
#define endl '\n'
template <class T>
void db(T a) {
cerr << "debug: " << a << endl;
}
template <class T>
void db(T a, T b) {
cerr << "debug: " << a << " " << b << endl;
}
template <class T>
void db(T a[], int l, int r) {
cerr << "debug: ";
for (int i = l; i <= r; i++)
cerr << a[i] << ' ';
cerr << endl;
}
const int N = 5e5 + 10;
int n, g[25], f[1 << 23], h[N], ans[N], s[N], a[N], sz[N], son[N];
vector<int> mp[N];
int dfs_son(int u, int fa) {
h[u] = h[fa] + 1;
if (u > 1)
s[u] = s[fa] ^ g[a[u]];
sz[u] = 1;
for (auto v : mp[u]) {
if (v == fa)
continue;
sz[u] += dfs_son(v, u);
if (sz[v] > sz[son[u]])
son[u] = v;
}
return sz[u];
}
void work(int u, int fa, int root) {
ans[root] = max(ans[root], f[s[u]] + h[u] - h[root] * 2);
if ((s[u] ^ s[root]) == 0)
ans[root] = max(ans[root], h[u] - h[root]);
for (int i = 0; i < 22; i++) {
int state = s[u] ^ g[i];
ans[root] = max(ans[root], f[state] + h[u] - h[root] * 2);
if ((s[u] ^ s[root]) == g[i])
ans[root] = max(ans[root], h[u] - h[root]);
}
for (auto v : mp[u]) {
if (v == fa)
continue;
work(v, u, root);
}
}
void pushup(int u, int fa, int flag) {
if (flag)
f[s[u]] = max(f[s[u]], h[u]);
else
f[s[u]] = -INF;
for (auto v : mp[u]) {
if (v == fa)
continue;
pushup(v, u, flag);
}
}
int dfs(int u, int fa, int flag) {
for (auto v : mp[u]) {
if (v == fa || v == son[u])
continue;
ans[u] = max(ans[u], dfs(v, u, 0));
}
if (son[u])
ans[u] = max(ans[u], dfs(son[u], u, 1));
ans[u] = max(ans[u], f[s[u]] - h[u]);
for (int i = 0; i < 22; i++) {
int state = s[u] ^ g[i];
ans[u] = max(ans[u], f[state] - h[u]);
}
for (auto v : mp[u]) {
if (v == fa || v == son[u])
continue;
work(v, u, u);
pushup(v, u, 1);
}
if (!flag) {
for (auto v : mp[u]) {
if (v == fa)
continue;
pushup(v, u, 0);
}
} else {
f[s[u]] = max(f[s[u]], h[u]);
}
return ans[u];
}
signed main() {
jiasu;
cin >> n;
memset(f, 0xcf, sizeof f);
g[0] = 1;
for (int i = 1; i < 23; i++)
g[i] = g[i - 1] * 2;
for (int i = 2; i <= n; i++) {
int x;
char c;
cin >> x >> c;
mp[i].push_back(x), mp[x].push_back(i);
a[i] = c - 'a';
}
dfs_son(1, 0);
dfs(1, 0, 1);
for (int i = 1; i <= n; i++)
cout << ans[i] << ' ';
return 0;
}