#include<bits/stdc++.h>
#pragma GCC optimize(2)
#pragma GCC optimize(3)
#pragma GCC optimize("Ofast")
#pragma GCC optimize("inline")
#pragma GCC optimize("-fgcse")
#pragma GCC optimize("-fgcse-lm")
#pragma GCC optimize("-fipa-sra")
#pragma GCC optimize("-ftree-pre")
#pragma GCC optimize("-ftree-vrp")
#pragma GCC optimize("-fpeephole2")
#pragma GCC optimize("-ffast-math")
#pragma GCC optimize("-fsched-spec")
#pragma GCC optimize("unroll-loops")
#pragma GCC optimize("-falign-jumps")
#pragma GCC optimize("-falign-loops")
#pragma GCC optimize("-falign-labels")
#pragma GCC optimize("-fdevirtualize")
#pragma GCC optimize("-fcaller-saves")
#pragma GCC optimize("-fcrossjumping")
#pragma GCC optimize("-fthread-jumps")
#pragma GCC optimize("-funroll-loops")
#pragma GCC optimize("-freorder-blocks")
#pragma GCC optimize("-fschedule-insns")
#pragma GCC optimize("inline-functions")
#pragma GCC optimize("-ftree-tail-merge")
#pragma GCC optimize("-fschedule-insns2")
#pragma GCC optimize("-fstrict-aliasing")
#pragma GCC optimize("-falign-functions")
#pragma GCC optimize("-fcse-follow-jumps")
#pragma GCC optimize("-fsched-interblock")
#pragma GCC optimize("-fpartial-inlining")
#pragma GCC optimize("no-stack-protector")
#pragma GCC optimize("-freorder-functions")
#pragma GCC optimize("-findirect-inlining")
#pragma GCC optimize("-fhoist-adjacent-loads")
#pragma GCC optimize("-frerun-cse-after-loop")
#pragma GCC optimize("inline-small-functions")
#pragma GCC optimize("-finline-small-functions")
#pragma GCC optimize("-ftree-switch-conversion")
#pragma GCC optimize("-foptimize-sibling-calls")
#pragma GCC optimize("-fexpensive-optimizations")
#pragma GCC optimize("inline-functions-called-once")
#pragma GCC optimize("-fdelete-null-pointer-checks")
#pragma GCC target("sse,sse2,sse3,sse4,popcnt,abm,mmx,avx,avx2")
#include<bits/stdc++.h>
using namespace std;
const int N=5e5+5,INF=1<<30;
int n,ans[N],dep[N],c[1<<22],dis[N];
int siz[N],hs[N],id[N],head[N],nxt[N];
void dfs(int u)
{
siz[u]=1;
hs[u]=-1;
for(int i=head[u];i;i=nxt[i])
{
dis[i]^=dis[u];
dep[i]=dep[u]+1;
dfs(i);
if(hs[u]==-1||siz[i]>siz[hs[u]]) hs[u]=i;
}
}
void init(int u)
{
c[dis[u]]=-INF;
for(int i=head[u];i;i=nxt[i]) init(i);
}
int o;
void push_up(int u)
{
ans[o]=max(ans[o],dep[u]+c[dis[u]]);
for(int i=0;i<=21;i++)
ans[o]=max(ans[o],dep[u]+c[1<<i^dis[u]]);
for(int i=head[u];i;i=nxt[i]) push_up(i);
}
void update(int u)
{
c[dis[u]]=max(c[dis[u]],dep[u]);
for(int i=head[u];i;i=nxt[i]) update(i);
}
void dsu(int u)
{
for(int i=head[u];i;i=nxt[i])
{
if(hs[u]==i) continue;
dsu(i);
init(i);
}
if(hs[u]!=-1)
{
dsu(hs[u]);
o=u;
}
for(int i=head[u];i;i=nxt[i])
{
if(hs[u]==i) continue;
push_up(i);
update(i);
}
c[dis[u]]=max(c[dis[u]],dep[u]);
ans[u]=max(ans[u],dep[u]+c[dis[u]]);
for(int i=0;i<=21;i++)
ans[u]=max(ans[u],dep[u]+c[1<<i^dis[u]]);
ans[u]-=dep[u]<<1;
for(int i=head[u];i;i=nxt[i]) ans[u]=max(ans[u],ans[i]);
}
inline int read()
{
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch))
{
if(ch=='-') f=-1;
ch=getchar();
}
while(isdigit(ch))
{
x=(x<<3)+(x<<1)+(ch^48);
ch=getchar();
}
return x*f;
}
signed main()
{
n=read();
for(int i=0;i<(1<<22);i++) c[i]=-INF;
for(int i=2,u;i<=n;i++)
{
u=read();
nxt[i]=head[u];
head[u]=i;
char ch=getchar();
while(ch<'a'||ch>'v') ch=getchar();
dis[i]=1<<(ch-'a');
}
dfs(1);
dsu(1);
for(int i=1;i<=n;i++) printf("%d ",ans[i]);
return 0;
}