#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define MAXN 500000
using namespace std;
struct edge
{
	int to;
	char chr;
	edge(){};
	edge(int _to,char _chr):to(_to),chr(_chr){};
};
vector<edge> G[MAXN+5];
map<int,int> mp[MAXN+5];
map<int,int> mp2;
int ncnt=0,ID[MAXN+5],ans[MAXN+5];
int n;
int LowBit(int i){return i&(-i);}
bool leaf[MAXN+5];
int Count(int st)
{
	int ret=0;
	while(st)
	{
		ret++;
		st-=LowBit(st);
	}
	return ret;
}
void Add(int u,int st,int val,bool typ)
{
	if(Count(st)<=1)
		ans[u]=max(ans[u],val);
	int stn=st;
	map<int,int>::iterator it;
	if(typ==0)
	{
		it=mp[ID[u]].find(stn);
		if(it!=mp[ID[u]].end())
			ans[u]=max(it->second+val,ans[u]);
		for(int i='a';i<='v';i++)
		{
			stn=(st^(1<<(i-'a')));
			it=mp[ID[u]].find(stn);
			if(it==mp[ID[u]].end())
				continue;
			ans[u]=max(it->second+val,ans[u]);
		}
	}
	else if(typ==1)
		mp[ID[u]][st]=max(mp[ID[u]][st],val);
}
void DFS(int u,int fa)
{
	int maxsiz=-1,maxpos;
	char maxch;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa)
			continue;
		DFS(v,u);
		if(maxsiz<(int)mp[ID[v]].size())
		{
			maxsiz=mp[ID[v]].size();
			maxpos=v;
			maxch=w;
		}
	}
	if(maxsiz==-1)
	{
		leaf[u]=true;
		ID[u]=++ncnt;
		mp[ID[u]][0]=0;
		return;
	}
	ans[u]=ans[maxpos];
	ID[u]=ID[maxpos];
	map<int,int>::iterator it;
	mp2.clear();
	for(it=mp[ID[maxpos]].begin();it!=mp[ID[maxpos]].end();it++)
		mp2[it->first^(1<<(maxch-'a'))]=it->second+1;
	mp[ID[maxpos]].clear();
	for(it=mp2.begin();it!=mp2.end();it++)
		Add(u,it->first,it->second,1);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa||v==maxpos)
			continue;
		ans[u]=max(ans[u],ans[v]);
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1,0);
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1,1);
	}
	mp[ID[u]][0]=max(mp[ID[u]][0],0);
}
int main()
{
	scanf("%d",&n);
	char s[10];
	int x;
	for(int i=1;i<n;i++)
	{
		scanf("%d %s",&x,s);
		G[x].push_back(edge(i+1,s[0]));
		G[i+1].push_back(edge(x,s[0]));
	}
	DFS(1,-1);
	for(int i=1;i<=n;i++)
		if(i==1)
			printf("%d",ans[i]);
		else
			printf(" %d",ans[i]);
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500000
#define MAXS 4194304
using namespace std;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
int mxlen[MAXS+5];
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	if(mxlen[st[u]]!=-1)
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st[u]]-dep[rt]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[(1<<i)^st[u]]-dep[rt]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u)
{
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v);
	}
}
void DFS3(int u)
{
	mxlen[st[u]]=-1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS3(v);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),DFS3(v);
	}
	mxlen[st[u]]=dep[u];
	if(son[u])
		DFS(son[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		ans[u]=max(ans[u],ans[v]);
		if(v!=son[u])
			DFS1(v,u),DFS2(v);
	}
	if(mxlen[st[u]]!=-1)
		ans[u]=max(ans[u],mxlen[st[u]]-dep[u]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[u]=max(ans[u],mxlen[(1<<i)^st[u]]-dep[u]);
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
}
int main()
{
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 500000
using namespace std;
struct edge
{
	int to;
	char val;
	edge(){};
	edge(int _to,char _val):to(_to),val(_val){};
};
int ans[MAXN+5],f[(1<<23)+5],col[MAXN+5];
int dep[MAXN+5],siz[MAXN+5],bigson[MAXN+5];
vector<edge> G[MAXN+5];
void prepare(int u)
{
	int maxsiz=-1;
	siz[u]=1;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].val;
		dep[v]=dep[u]+1;
		col[v]=(col[u]^(1<<(w-'a')));
		prepare(v);
		siz[u]+=siz[v];
		if(siz[v]>maxsiz)
		{
			maxsiz=siz[v];
			bigson[u]=v;
		}
	}
}
void Clear(int u)
{
	f[col[u]]=0;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		Clear(v);
	}
}
void Check(int u,int rt)
{
	if(f[col[u]]!=0)
		ans[rt]=max(ans[rt],f[col[u]]+dep[u]-2*dep[rt]);
	for(int i='a';i<='v';i++)
		if(f[col[u]^(1<<(i-'a'))]!=0)
			ans[rt]=max(ans[rt],f[col[u]^(1<<(i-'a'))]+dep[u]-2*dep[rt]);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		Check(v,rt);
	}
}
void Add(int u)
{
	f[col[u]]=max(dep[u],f[col[u]]);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		Add(v);
	}
}
void DFS(int u)
{
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		if(v==bigson[u])
			continue;
		DFS(v);
		Clear(v);
	}
	if(bigson[u]!=0)
		DFS(bigson[u]);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		ans[u]=max(ans[u],ans[v]);
		if(v==bigson[u])
			continue;
		Check(v,u);
		Add(v);
	}
	if(f[col[u]]!=0)
		ans[u]=max(ans[u],f[col[u]]-dep[u]);
	for(int i='a';i<='v';i++)
		if(f[col[u]^(1<<(i-'a'))]!=0)
			ans[u]=max(ans[u],f[col[u]^(1<<(i-'a'))]-dep[u]);
	f[col[u]]=max(f[col[u]],dep[u]);
}
int main()
{
	int n,x;
	char s[10];
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		scanf("%d %s",&x,s);
		G[x].push_back(edge(i+1,s[0]));
	}
	prepare(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		if(i==1)
			printf("%d",ans[i]);
		else
			printf(" %d",ans[i]);
	printf("\n");
	return 0;
}
/*
10
1 d
1 d
2 d
3 e
1 d
1 d
2 b
7 e
4 c

*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500000
#define MAXS 4194304
using namespace std;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
int mxlen[MAXS+5];
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	if(mxlen[st[u]]!=-1)
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st[u]]-dep[rt]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[(1<<i)^st[u]]-dep[rt]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u)
{
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v);
	}
}
void DFS3(int u)
{
	mxlen[st[u]]=-1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS3(v);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),DFS3(v);
	}
	if(son[u])
		DFS(son[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		ans[u]=max(ans[u],ans[v]);
		if(v!=son[u])
			DFS1(v,u),DFS2(v);
	}
	if(mxlen[st[u]]!=-1)
		ans[u]=max(ans[u],mxlen[st[u]]-dep[u]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[u]=max(ans[u],mxlen[(1<<i)^st[u]]-dep[u]);
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
}
int main()
{
	memset(mxlen,-1,sizeof(mxlen));
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define MAXN 500000
using namespace std;
struct edge
{
	int to;
	char chr;
	edge(){};
	edge(int _to,char _chr):to(_to),chr(_chr){};
};
vector<edge> G[MAXN+5];
map<int,int> mp[MAXN+5];
map<int,int> mp2;
int ncnt=0,ID[MAXN+5],ans[MAXN+5];
int n;
int LowBit(int i){return i&(-i);}
int Count(int st)
{
	int ret=0;
	while(st)
	{
		ret++;
		st-=LowBit(st);
	}
	return ret;
}
void Add(int u,int st,int val)
{
	if(Count(st)<=1)
		ans[u]=max(ans[u],val);
	int stn=st;
	map<int,int>::iterator it;
	it=mp[ID[u]].find(stn);
	if(it!=mp[ID[u]].end())
		ans[u]=max(it->second+val,ans[u]);
	for(int i='a';i<='v';i++)
	{
		stn=(st^(1<<(i-'a')));
		it=mp[ID[u]].find(stn);
		if(it==mp[ID[u]].end())
			continue;
		ans[u]=max(it->second+val,ans[u]);
	}
	mp[ID[u]][st]=max(mp[ID[u]][st],val);
}
void DFS(int u,int fa)
{
	int maxsiz=-1,maxpos;
	char maxch;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa)
			continue;
		DFS(v,u);
		if(maxsiz<(int)mp[ID[v]].size())
		{
			maxsiz=mp[ID[v]].size();
			maxpos=v;
			maxch=w;
		}
	}
	if(maxsiz==-1)
	{
		ID[u]=++ncnt;
		mp[ID[u]][0]=0;
		return;
	}
	ans[u]=ans[maxpos];
	ID[u]=ID[maxpos];
	map<int,int>::iterator it;
	mp2.clear();
	for(it=mp[ID[maxpos]].begin();it!=mp[ID[maxpos]].end();it++)
		mp2[it->first^(1<<(maxch-'a'))]=it->second+1;
	mp[ID[maxpos]].clear();
	for(it=mp2.begin();it!=mp2.end();it++)
		Add(u,it->first,it->second);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa||v==maxpos)
			continue;
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1);
	}
}
int main()
{
	scanf("%d",&n);
	char s[10];
	int x;
	for(int i=1;i<n;i++)
	{
		scanf("%d %s",&x,s);
		G[x].push_back(edge(i+1,s[0]));
		G[i+1].push_back(edge(x,s[0]));
	}
	DFS(1,-1);
	for(int i=1;i<=n;i++)
		if(i==1)
			printf("%d",ans[i]);
		else
			printf(" %d",ans[i]);
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<map>
#define MAXN 500000
#define MAXS 7000000
using namespace std;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
map<int,int> mp;
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	int st1=st[u],st2=st[u];
	if(mp.find(st2)!=mp.end())
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mp[st2]-dep[rt]);
	for(int i=0;i<26;i++)
	{
		st2=(1<<i)^st1;
		if(mp.find(st2)!=mp.end())
			ans[rt]=max(ans[rt],dep[u]-dep[rt]+mp[st2]-dep[rt]);
	}
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u,int rt)
{
	mp[st[u]]=max(mp[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v,rt);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),mp.clear();
	}
	mp[st[u]]=dep[u];
	if(son[u])
	{
		DFS(son[u]);
		ans[u]=max(ans[u],ans[son[u]]);
		int st1=st[u],st2;
		for(int i=0;i<26;i++)
		{
			st2=(1<<i)^st1;
			if(mp.find(st2)!=mp.end())
				ans[u]=max(ans[u],mp[st2]-dep[u]);
		}
		if(mp.find(st[u])!=mp.end())
			ans[u]=max(ans[u],mp[st[u]]-dep[u]);
	}
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
		{
			ans[u]=max(ans[u],ans[v]);
			DFS1(v,u);
			DFS2(v,u);
		}
	}
}
int main()
{
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define MAXN 500000
using namespace std;
struct edge
{
	int to;
	char val;
	edge(){};
	edge(int _to,char _val):to(_to),val(_val){};
};
int ans[MAXN+5],f[(1<<23)+5],col[MAXN+5];
int dep[MAXN+5],siz[MAXN+5],bigson[MAXN+5];
vector<edge> G[MAXN+5];
void prepare(int u,int fa)
{
	int maxsiz=-1;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].val;
		if(v==fa)
			continue;
		dep[v]=dep[u]+1;
		col[v]=(col[u]^(1<<(w-'a')));
		prepare(v,u);
		siz[u]+=siz[v];
		if(siz[v]>maxsiz)
		{
			maxsiz=siz[v];
			bigson[u]=v;
		}
	}
}
void Clear(int u,int fa)
{
	f[col[u]]=0;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		if(v==fa)
			continue;
		Clear(v,u);
	}
}
void Check(int u,int fa,int rt)
{
	if(f[col[u]]!=0)
		ans[rt]=max(ans[rt],f[col[u]]+dep[u]-2*dep[rt]);
	for(int i='a';i<='v';i++)
		if(f[col[u]^(1<<(i-'a'))]!=0)
			ans[rt]=max(ans[rt],f[col[u]^(1<<(i-'a'))]+dep[u]-2*dep[rt]);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		if(v==fa)
			continue;
		Check(v,u,rt);
	}
}
void Add(int u,int fa)
{
	f[col[u]]=max(dep[u],f[col[u]]);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		if(v==fa)
			continue;
		Add(v,u);
	}
}
void DFS(int u,int fa)
{
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		if(v==fa||v==bigson[u])
			continue;
		DFS(v,u);
		Clear(v,u);
	}
	if(bigson[u]!=0)
		DFS(bigson[u],u);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		ans[u]=max(ans[u],ans[v]);
		if(v==fa||v==bigson[u])
			continue;
		Check(v,u,u);
		Add(v,u);
	}
	if(f[col[u]]!=0)
		ans[u]=max(ans[u],f[col[u]]-dep[u]);
	for(int i='a';i<='v';i++)
		if(f[col[u]^(1<<(i-'a'))]!=0)
			ans[u]=max(ans[u],f[col[u]^(1<<(i-'a'))]-dep[u]);
	f[col[u]]=max(f[col[u]],dep[u]);
}
int main()
{
	int n,x;
	char s[10];
	scanf("%d",&n);
	for(int i=1;i<n;i++)
	{
		scanf("%d %s",&x,s);
		G[x].push_back(edge(i+1,s[0]));
		G[i+1].push_back(edge(x,s[0]));
	}
	prepare(1,-1);
	DFS(1,-1);
	for(int i=1;i<=n;i++)
		if(i==1)
			printf("%d",ans[i]);
		else
			printf(" %d",ans[i]);
	printf("\n");
	return 0;
}
/*
10
1 d
1 d
2 d
3 e
1 d
1 d
2 b
7 e
4 c

*/


#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500000
#define MAXS 4194304
using namespace std;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
int mxlen[MAXS+5];
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	if(mxlen[st[u]]!=-1)
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st[u]]-dep[rt]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[(1<<i)^st[u]]-dep[rt]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u)
{
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v);
	}
}
void DFS3(int u)
{
	mxlen[st[u]]=-1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS3(v);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),DFS3(v);
	}
	if(son[u])
		DFS(son[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		ans[u]=max(ans[u],ans[v]);
		if(v!=son[u])
			DFS1(v,u),DFS2(v);
	}
	if(mxlen[st[u]]!=-1)
		ans[u]=max(ans[u],mxlen[st[u]]-dep[u]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[u]=max(ans[u],mxlen[(1<<i)^st[u]]-dep[u]);
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
}
int main()
{
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define MAXN 500000
using namespace std;
struct edge
{
	int to;
	char chr;
	edge(){};
	edge(int _to,char _chr):to(_to),chr(_chr){};
};
vector<edge> G[MAXN+5];
map<int,int> mp[MAXN+5];
map<int,int> mp2;
int ncnt=0,ID[MAXN+5],ans[MAXN+5],C[(1<<23)+5];
int n;
int LowBit(int i){return i&(-i);}
int Count(int st)
{
	int ret=0;
	while(st)
	{
		ret++;
		st-=LowBit(st);
	}
	return ret;
}
void prepare()
{
	for(int s=0;s<=(1<<23)+3;s++)
		C[s]=Count(s);
}
void Add(int u,int st,int val,bool typ)
{
	int stn=st;
	map<int,int>::iterator it;
	if(typ==0)
	{
		it=mp[ID[u]].find(stn);
		if(it!=mp[ID[u]].end())
			ans[u]=max(it->second+val,ans[u]);
		for(int i='a';i<='v';i++)
		{
			stn=(st^(1<<(i-'a')));
			it=mp[ID[u]].find(stn);
			if(it==mp[ID[u]].end())
				continue;
			ans[u]=max(it->second+val,ans[u]);
		}
	}
	else if(typ==1)
	{
		if(C[st]<=1)
			ans[u]=max(ans[u],val);
		mp[ID[u]][st]=max(mp[ID[u]][st],val);
	}
}
void DFS(int u,int fa)
{
	int maxsiz=-1,maxpos;
	char maxch;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa)
			continue;
		DFS(v,u);
		if(maxsiz<(int)mp[ID[v]].size())
		{
			maxsiz=mp[ID[v]].size();
			maxpos=v;
			maxch=w;
		}
	}
	if(maxsiz==-1)
	{
		ID[u]=++ncnt;
		mp[ID[u]][0]=0;
		return;
	}
	ans[u]=ans[maxpos];
	ID[u]=ID[maxpos];
	map<int,int>::iterator it;
	mp2.clear();
	for(it=mp[ID[maxpos]].begin();it!=mp[ID[maxpos]].end();it++)
		mp2[it->first^(1<<(maxch-'a'))]=it->second+1;
	mp[ID[maxpos]].clear();
	for(it=mp2.begin();it!=mp2.end();it++)
		Add(u,it->first,it->second,1);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa||v==maxpos)
			continue;
		ans[u]=max(ans[u],ans[v]);
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1,0);
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1,1);
	}
	mp[ID[u]][0]=max(mp[ID[u]][0],0);
}
int main()
{
	prepare();
	scanf("%d",&n);
	char s[10];
	int x;
	for(int i=1;i<n;i++)
	{
		scanf("%d %s",&x,s);
		G[x].push_back(edge(i+1,s[0]));
		G[i+1].push_back(edge(x,s[0]));
	}
	DFS(1,-1);
	for(int i=1;i<=n;i++)
		if(i==1)
			printf("%d",ans[i]);
		else
			printf(" %d",ans[i]);
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#include<map>
#define MAXN 500000
using namespace std;
struct edge
{
	int to;
	char chr;
	edge(){};
	edge(int _to,char _chr):to(_to),chr(_chr){};
};
vector<edge> G[MAXN+5];
map<int,int> mp[MAXN+5];
map<int,int> mp2;
int ncnt=0,ID[MAXN+5],ans[MAXN+5];
int n;
int LowBit(int i){return i&(-i);}
bool leaf[MAXN+5];
int Count(int st)
{
	int ret=0;
	while(st)
	{
		ret++;
		st-=LowBit(st);
	}
	return ret;
}
void Add(int u,int st,int val,bool typ)
{
	if(Count(st)<=1)
		ans[u]=max(ans[u],val);
	int stn=st;
	map<int,int>::iterator it;
	if(typ==0)
	{
		it=mp[ID[u]].find(stn);
		if(it!=mp[ID[u]].end())
			ans[u]=max(it->second+val,ans[u]);
		for(int i='a';i<='v';i++)
		{
			stn=(st^(1<<(i-'a')));
			it=mp[ID[u]].find(stn);
			if(it==mp[ID[u]].end())
				continue;
			ans[u]=max(it->second+val,ans[u]);
		}
	}
	else if(typ==1)
		mp[ID[u]][st]=max(mp[ID[u]][st],val);
}
void DFS(int u,int fa)
{
	int maxsiz=-1,maxpos;
	char maxch;
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa)
			continue;
		DFS(v,u);
		if(maxsiz<(int)mp[ID[v]].size())
		{
			maxsiz=mp[ID[v]].size();
			maxpos=v;
			maxch=w;
		}
	}
	if(maxsiz==-1)
	{
		leaf[u]=true;
		ID[u]=++ncnt;
		mp[ID[u]][0]=0;
		return;
	}
	ans[u]=ans[maxpos];
	ID[u]=ID[maxpos];
	map<int,int>::iterator it;
	mp2.clear();
	for(it=mp[ID[maxpos]].begin();it!=mp[ID[maxpos]].end();it++)
		mp2[it->first^(1<<(maxch-'a'))]=it->second+1;
	mp[ID[maxpos]].clear();
	for(it=mp2.begin();it!=mp2.end();it++)
		Add(u,it->first,it->second,1);
	for(int i=0;i<G[u].size();i++)
	{
		int v=G[u][i].to;
		char w=G[u][i].chr;
		if(v==fa||v==maxpos)
			continue;
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1,0);
		for(it=mp[ID[v]].begin();it!=mp[ID[v]].end();it++)
			Add(u,((it->first)^(1<<(w-'a'))),it->second+1,1);
	}
	mp[ID[u]][0]=max(mp[ID[u]][0],0);
}
int main()
{
	scanf("%d",&n);
	char s[10];
	int x;
	for(int i=1;i<n;i++)
	{
		scanf("%d %s",&x,s);
		G[x].push_back(edge(i+1,s[0]));
		G[i+1].push_back(edge(x,s[0]));
	}
	DFS(1,-1);
	for(int i=1;i<=n;i++)
		if(i==1)
			printf("%d",ans[i]);
		else
			printf(" %d",ans[i]);
	printf("\n");
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500000
#define MAXS 4194304
using namespace std;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
int mxlen[MAXS+5];
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	int st1=st[u],st2=st[u];
	if(mxlen[st2]!=-1)
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st2]-dep[rt]);
	for(int i=0;i<22;i++)
	{
		st2=(1<<i)^st1;
		if(mxlen[st2]!=-1)
			ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st2]-dep[rt]);
	}
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u,int rt)
{
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v,rt);
	}
}
void DFS3(int u)
{
	mxlen[st[u]]=-1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS3(v);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),DFS3(v);
	}
	mxlen[st[u]]=dep[u];
	if(son[u])
	{
		DFS(son[u]);
		ans[u]=max(ans[u],ans[son[u]]);
		int st1=st[u],st2=st[u];
		if(mxlen[st2]!=-1)
			ans[u]=max(ans[u],mxlen[st2]-dep[u]);
		for(int i=0;i<22;i++)
		{
			st2=(1<<i)^st1;
			if(mxlen[st2]!=-1)
				ans[u]=max(ans[u],mxlen[st2]-dep[u]);
		}
	}
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
		{
			ans[u]=max(ans[u],ans[v]);
			DFS1(v,u);
			DFS2(v,u);
		}
	}
}
int main()
{
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500000
#define MAXS 4194304
using namespace std;
typedef short int SI;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
int mxlen[MAXS+5];
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	int st1=st[u],st2=st[u];
	ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st2]-dep[rt]);
	for(int i=0;i<22;i++)
	{
		st2=(1<<i)^st1;
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st2]-dep[rt]);
	}
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u,int rt)
{
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v,rt);
	}
}
void DFS3(int u)
{
	mxlen[st[u]]=0;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS3(v);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),DFS3(v);
	}
	mxlen[st[u]]=dep[u];
	if(son[u])
	{
		DFS(son[u]);
		ans[u]=max(ans[u],ans[son[u]]);
		int st1=st[u],st2;
		for(int i=0;i<22;i++)
		{
			st2=(1<<i)^st1;
			ans[u]=max(ans[u],mxlen[st2]-dep[u]);
		}
		ans[u]=max(ans[u],mxlen[st[u]]-dep[u]);
	}
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
		{
			ans[u]=max(ans[u],ans[v]);
			DFS1(v,u);
			DFS2(v,u);
		}
	}
}
int main()
{
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include<cstdio>
#include<cstring>
#include<algorithm>
#define MAXN 500000
#define MAXS 4194304
using namespace std;
struct edge
{
	int to;
	char w;
	edge *nxt;
}edges[MAXN+5];
edge *ncnt=&edges[0],*Adj[MAXN+5];
int n,siz[MAXN+5],son[MAXN+5];
int st[MAXN+5],ans[MAXN+5],dep[MAXN+5];
int mxlen[MAXS+5];
void AddEdge(int u,int v,char w)
{
	edge *p=++ncnt;
	p->to=v;p->w=w;
	p->nxt=Adj[u];Adj[u]=p;
}
void PreDFS(int u)
{
	siz[u]=1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;int w=p->w-'a';
		st[v]=(st[u]^(1<<w));
		dep[v]=dep[u]+1;
		PreDFS(v);
		siz[u]+=siz[v];
		if(son[u]==0||siz[v]>siz[son[u]])
			son[u]=v;
	}
}
void DFS1(int u,int rt)
{
	if(mxlen[st[u]]!=-1)
		ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[st[u]]-dep[rt]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[rt]=max(ans[rt],dep[u]-dep[rt]+mxlen[(1<<i)^st[u]]-dep[rt]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS1(v,rt);
	}
}
void DFS2(int u)
{
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS2(v);
	}
}
void DFS3(int u)
{
	mxlen[st[u]]=-1;
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		DFS3(v);
	}
}
void DFS(int u)
{
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		if(v!=son[u])
			DFS(v),DFS3(v);
	}
	mxlen[st[u]]=dep[u];
	if(son[u])
		DFS(son[u]);
	for(edge *p=Adj[u];p!=NULL;p=p->nxt)
	{
		int v=p->to;
		ans[u]=max(ans[u],ans[v]);
		if(v!=son[u])
			DFS1(v,u),DFS2(v);
	}
	if(mxlen[st[u]]!=-1)
		ans[u]=max(ans[u],mxlen[st[u]]-dep[u]);
	for(int i=0;i<22;i++)
		if(mxlen[(1<<i)^st[u]]!=-1)
			ans[u]=max(ans[u],mxlen[(1<<i)^st[u]]-dep[u]);
	mxlen[st[u]]=max(mxlen[st[u]],dep[u]);
}
int main()
{
	memset(mxlen,-1,sizeof(mxlen));
	scanf("%d",&n);
	int u;char str[5];
	for(int i=2;i<=n;i++)
	{
		scanf("%d %s",&u,str);
		AddEdge(u,i,str[0]);
	}
	PreDFS(1);
	DFS(1);
	for(int i=1;i<=n;i++)
		printf("%d\n",ans[i]);
	return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
unordered_map<int,int> mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    mp[i1].reserve((mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
unordered_map<int,int> mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    mp[i1].reserve(3 * (mp[i1].size() + mp[i2].size()) / 2);
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    mp[i1].resize(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].find(z) != mp[i1].end())
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    // mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].find(z) != mp[i1].end())
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    // mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table<int,int> mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    // mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
unordered_map<int,int> mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    // mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            if(mp[i1].count(z))
                a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include <bits/stdc++.h>

#ifdef _MSC_VER
#define __builtin_popcount __popcnt
#endif

#include <ext/pb_ds/assoc_container.hpp>
using namespace __gnu_pbds;
typedef gp_hash_table<int, int> table;

using namespace std;

typedef long long ll;
typedef vector<int> vi;
typedef pair<int, int> pii;
#define pb push_back
#define fori(i,s,n) for(int i = s; i < n; i++)
#define zero(a) memset(a, 0, sizeof(a))

const int N=5e5 + 10;

int n,a[N],var[N], h[N];
char ch;
vector<pii> adj[N];
vi valid;
table mp[N];

inline void merge(int i1,int i2,char c){
    var[i2] ^= 1 << (c - 'a');
    if(mp[i1].size() < mp[i2].size()) mp[i1].swap(mp[i2]), swap(var[i1], var[i2]);
    // mp[i1].reserve(2 * (mp[i1].size() + mp[i2].size()));
    int va = var[i1]^var[i2];
    for(auto val:valid){
        for(auto el:mp[i2]){
            int z = el.first ^ val ^ va;
            a[i1]=max(a[i1],mp[i1][z]+ el.second - 2 * h[i1]);
        }
    }
    for(auto el : mp[i2])
        mp[i1][el.first^va]= max(mp[i1][el.first^va], el.second);
    mp[i2].clear();
}

void dfs(int u){

    mp[u][0] = h[u];

    for(auto el:adj[u]){
        h[el.first] = h[u] + 1;
        dfs(el.first);
        a[u]=max(a[u],a[el.first]);
        merge(u,el.first, el.second);
    }
}

int main(){
    ios::sync_with_stdio(0);
	cout.tie(0); cin.tie(0);
    cin>>n;
    fori(i,1,n)
    {
        int u;
        cin>>u>>ch;
        adj[u].push_back({i+1,ch});
    }
    valid.push_back(0);
    fori(i,0,22) valid.push_back(1<<i);

    h[1] = 1;
    dfs(1);

    fori(i,1,n+1)
        cout << a[i] << ' ';

    return 0;
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (i > 81) continue;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(22);
//vector<vector<bool> > c(N,vector<bool>(22));
int c[N];
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	for (int i = 0; i < 22; i++)
	if (bit[i])
		c[v] += (1<<i);
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
map<int,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[v].size() < mp[i].size()) {
			swap(mp[v],mp[i]);
		}
		for (auto k:mp[i]) {
			int bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 22; j++) {
				bt^=(1<<j);
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 bt^=(1<<j);
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (i > 90) continue;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[v].size() < mp[i].size()) {
			mp[v].swap(mp[i]);
			//swap(P[v],P[i]);
		}
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[P[i]]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	//	bit[d]=1;
	c[v] = bit;
	sz[v] = 1;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
		sz[v] += sz[i.fi];
	}
	if (d != -1)
		//bit^=(1<<d);
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v,bool keep) {
//	if (v != 1) ans[v] = 1;
	int big=-1,mxsz=-1;
	for (auto i : adj[v])
		if (sz[i.fi] > mxsz) {
			mxsz = sz[i.fi];
			big = i.fi;
		}
	for (auto i : adj[v]) {
			dfs(i.fi,0);
			ans[v] = max(ans[v],ans[i.fi]);
	}
/*	if (big+1) {
		dfs(big,1);
		ans[v] = max(ans[big],ans[v]);
	}*/
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[P[v]].size() < mp[P[i]].size()) {
			mp[P[v]].swap(mp[P[i]]);
		//	cout <<"DS";
		//	P[v] = P[i];
			swap(P[v],P[i]);
		}
		for (auto k:mp[P[i]]) {
			auto bt = k.fi;
			if (mp[P[v]].count(bt)) {
				ans[v] = max(ans[v],mp[P[v]][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1^bt[j];
			//	bt[j]^=1;
				if (mp[P[v]].count(bt)) {
			ans[v] = max(ans[v],mp[P[v]][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1^bt[j];//(1<<j);
				//bt[j]^=1;
			}
		}
		for (auto&j: mp[P[i]]) {
			if (mp[P[v]].count(j.fi) == 0 || mp[P[v]][j.fi] < j.se);
				mp[P[v]][j.fi] = j.se;
		}
	}
//	for (auto i  : adj[v]) {
//
//	}
//	mp[P[v]][c[v]] = h[v];
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1,1);
//	mp[3][bit] = 2;
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e2+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
			     if (bt[j]) bt[j] = 0;
	       else bt[j] = 1;
			//	bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 if (bt[j]) bt[j] = 0;
	             else bt[j] = 1;
				//bt[j]= 1-bt[j];
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	//	bit[d]=1;
	c[v] = bit;
	sz[v] = 1;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
		sz[v] += sz[i.fi];
	}
	if (d != -1)
		//bit^=(1<<d);
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v,bool keep) {
//	if (v != 1) ans[v] = 1;
	int big=-1,mxsz=-1;
	for (auto i : adj[v])
		if (sz[i.fi] > mxsz) {
			mxsz = sz[i.fi];
			big = i.fi;
		}
	for (auto i : adj[v]) {
			dfs(i.fi,0);
			ans[v] = max(ans[v],ans[i.fi]);
	}
/*	if (big+1) {
		dfs(big,1);
		ans[v] = max(ans[big],ans[v]);
	}*/
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[P[v]].size() < mp[P[i]].size()) {
			mp[P[v]].swap(mp[P[i]]);
		//	cout <<"DS";
		//	P[v] = P[i];
			swap(P[v],P[i]);
		}
		for (auto k:mp[P[i]]) {
			auto bt = k.fi;
			if (mp[P[v]].count(bt)) {
				ans[v] = max(ans[v],mp[P[v]][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1^bt[j];
			//	bt[j]^=1;
				if (mp[P[v]].count(bt)) {
			ans[v] = max(ans[v],mp[P[v]][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1^bt[j];//(1<<j);
				//bt[j]^=1;
			}
		}
		for (auto&j: mp[P[i]]) {
			if (mp[P[v]].count(j.fi) == 0 || mp[P[v]][j.fi] < j.se);
				mp[P[v]][j.fi] = j.se;
		}
	}
//	for (auto i  : adj[v]) {
//
//	}
	mp[P[v]][c[v]] = h[v];
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1,1);
//	mp[3][bit] = 2;
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			vector<bool> bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
			     if (bt[j]) bt[j] = 0;
	       else bt[j] = 1;
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 if (bt[j]) bt[j] = 0;
	             else bt[j] = 1;
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (i > 80) continue;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (i > 85) continue;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v])
	 {
		int i = i1.fi;
		if (mp[P[v]].size() < mp[P[i]].size()) {
			mp[P[v]].swap(mp[P[i]]);
			swap(P[v],P[i]);
		}
		for (auto k:mp[P[i]]) {
			auto bt = k.fi;
			if (mp[P[v]].count(bt)) {
				ans[v] = max(ans[v],mp[P[v]][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[P[v]].count(bt)) {
			ans[v] = max(ans[v],mp[P[v]][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[P[i]]) {
			if (mp[P[v]].count(j.fi) == 0 || mp[P[v]][j.fi] < j.se);
				mp[P[v]][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= min(80,n); i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= min(80,n); i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e2+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			vector<bool> bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
			     if (bt[j]) bt[j] = 0;
	       else bt[j] = 1;
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 if (bt[j]) bt[j] = 0;
	             else bt[j] = 1;
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= min(80,n); i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (i > 80) continue;
		for (auto k:mp[i]) {
			vector<bool>  bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
//	cout << endl << endl << endl;

//	for (auto i : adj[81])
//		cout << i.fi <<' '<<i.se <<'\n';exit(0);
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= min(60,n); i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(22);
//vector<vector<bool> > c(N,vector<bool>(22));
int c[N];
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	for (int i = 0; i < 22; i++)
	if (bit[i])
		c[v] += (1<<i);
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
unordered_map<int,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[v].size() < mp[i].size()) {
			swap(mp[v],mp[i]);
		}
		for (auto& k:mp[i]) {
			int bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 22; j++) {
				bt^=(1<<j);
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 bt^=(1<<j);
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(22);
//vector<vector<bool> > c(N,vector<bool>(22));
int c[N];
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	for (int i = 0; i < 22; i++)
	if (bit[i])
		c[v] += (1<<i);
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
unordered_map<int,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[v].size() < mp[i].size()) {
			swap(mp[v],mp[i]);
		}
		for (auto k:mp[i]) {
			int bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 22; j++) {
				bt^=(1<<j);
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 bt^=(1<<j);
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
	//	if (mp[v].size() < mp[i].size()) {
	//		mp[v].swap(mp[i]);
			//swap(mp[v],mp[i]);
			//swap(P[v],P[i]);
	//	}
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= min(n,50); i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= min(60,n); i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= 80; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(22);
vector<vector<bool> > c(N,vector<bool>(22));
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			vector<bool> bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 22; j++) {
			     if (bt[j]) bt[j] = 0;
	       else bt[j] = 1;
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 if (bt[j]) bt[j] = 0;
	             else bt[j] = 1;
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (i > 82) continue;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(26);
vector<vector<bool> > c(N,vector<bool>(26));
void calcsize(int v,int d) {
	if (d!=-1)
		bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		bit[d] = 1-bit[d];
}
struct haha{
	bitset<26> g;
	bool operator <(bitset<26> T) const{
		for (int i = 0; i < 26; i++)
			if (g[i] != T[i]) return g[i] < T[i];
		return 0;
	}
};
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		for (auto k:mp[i]) {
			auto bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 26; j++) {
				bt[j] = 1-bt[j];
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				bt[j]= 1-bt[j];
			}
		}
		for (auto&j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se);
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= min(n,80); i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= min(60,n); i++)
		cout << ans[i] <<' ';
}


#include<bits/stdc++.h>
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC optimize("Ofast")
#pragma GCC target("avx,avx2,fma")
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(22);
//vector<vector<bool> > c(N,vector<bool>(22));
int c[N];
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	for (int i = 0; i < 22; i++)
	if (bit[i])
		c[v] += (1<<i);
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
unordered_map<int,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[v].size() < mp[i].size()) {
			swap(mp[v],mp[i]);
		}
		for (auto k:mp[i]) {
			int bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 22; j++) {
				bt^=(1<<j);
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 bt^=(1<<j);
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include<bits/stdc++.h>
#define bool int
#define ll long long
#define pb push_back
#define pii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define all(x) (x).begin(),(x).end()
using namespace std;
const int N = 5e5+5;
vector<pii> adj[N];
int sz[N],h[N];
vector<bool> bit(22);
vector<vector<bool> > c(N,vector<bool>(22));
void calcsize(int v,int d) {
	if (d!=-1)
	    if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
	//	bit[d] = 1-bit[d];
	c[v] = bit;
	for (auto i : adj[v]) {
		h[i.fi] = h[v]+1;
		calcsize(i.fi,i.se);
	}
	if (d != -1)
		 if (bit[d]) bit[d] = 0;
	    else bit[d] = 1;
}
map<vector<bool>,int> mp[N];
int n;
int ans[N],P[N];
void dfs(int v) {
	for (auto i : adj[v]) {
			dfs(i.fi);
			ans[v] = max(ans[v],ans[i.fi]);
	}
	P[v] = v;
	mp[v][c[v]] = h[v];
	for (auto i1 : adj[v]) {
		int i = i1.fi;
		if (mp[v].size() < mp[i].size()) {
			swap(mp[v],mp[i]);
		}
		for (auto k:mp[i]) {
			vector<bool> bt = k.fi;
			if (mp[v].count(bt)) {
				ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
			}
			for (int j = 0; j < 22; j++) {
			     if (bt[j]) bt[j] = 0;
	       else bt[j] = 1;
				if (mp[v].count(bt)) {
			ans[v] = max(ans[v],mp[v][bt]+k.se - 2*h[v]);
				}
				 if (bt[j]) bt[j] = 0;
	             else bt[j] = 1;
			}
		}
		for (auto j: mp[i]) {
			if (mp[v].count(j.fi) == 0 || mp[v][j.fi] < j.se)
				mp[v][j.fi] = j.se;
		}
	}
	if (adj[v].size()) ans[v] = max(ans[v],1);
}
main() {
	ios::sync_with_stdio(0);
	cin.tie(0);
	cin >> n;
	for (int i = 2; i <= n; i++) {
		int p; char c;
		cin >> p >> c;
		adj[p].pb({i,c-'a'});
	}
	h[1] = 1;
	calcsize(1,-1);
	dfs(1);
	for (int i = 1; i <= n; i++)
		cout << ans[i] <<' ';

}


#include <bits/stdc++.h>

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#define ll long long
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define o cout<<"BUG"<<endl;
#define	IOS ios_base::sync_with_stdio(0);
#define en "\n"
#define FOR(i, j, n) for(int j = i; j < n; ++j)
#define forn(i, j, n) for(int j = i; j <= n; ++j)
#define nfor(i, j, n) for(int j = n; j >= i; --j)
#define sortv(vv) sort(vv.begin(), vv.end())

using namespace std;
const ll maxn=5e5+100,inf=1e18,LOG=23,mod=1e9 + 7;

#define int ll
int n, ans[maxn], deep[maxn], mask[maxn], deepmask[(1 << LOG)], res, sz[maxn], p[maxn];
vector <pair <int, int> > edge[maxn];

void dfs_cnt(int v, int mas = 0)
{
	mask[v] = mas;
	int mxsz = 0;
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		int ch = edge[v][i].s;
		deep[to] = deep[v] + 1;
		dfs_cnt(to, mas ^ (1 << (ch - 'a')));
		sz[v] += sz[to];
		if(mxsz < sz[to])
		{
			mxsz = sz[to];
			p[v] = to;
		}
	}
	sz[v]++;
}

void add(int v)
{
	deepmask[mask[v]] = max(deep[v], deepmask[mask[v]]);
}
/*13
1 a
2 b
3 d
3 a
4 a
5 d
6 d
7 a
3 a
10 b
11 b
9 a*/
void upd(int v, int root)
{
	forn(0, i, LOG - 1)
	{
		int mas = mask[v] ^ (1 << i);
		if(deepmask[mas] == 0) {
			deepmask[mas] = -1e9;
		}
		res = max(res, deepmask[mas] + deep[v] - deep[root] * 2);
	}
	if(deepmask[mask[v]] == 0) deepmask[mask[v]] = -1e9;
	res = max(res, deepmask[mask[v]] + deep[v] - deep[root] * 2);
}

void dfs_upd(int v, int root)
{
	upd(v, root);
	FOR(0, i, edge[v].size())
	{
		dfs_upd(edge[v][i].f, root);
	}
}

void dfs_add(int v)
{
	add(v);
	FOR(0, i, edge[v].size())
	{
		dfs_add(edge[v][i].f);
	}
}

void dfs_clear(int v)
{
	deepmask[mask[v]] = -1e9;
	FOR(0, i, edge[v].size())
	{
		dfs_clear(edge[v][i].f);
	}
}

void dfs(int v, int cl = 0)
{
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs(to, 1);
	}
	if(p[v] != 0) dfs(p[v], 0);
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs_upd(to, v);
		dfs_add(to);
	}
	upd(v, v);
	add(v);
	ans[v] = res;
	if(cl)
	{
		res = 0;
		dfs_clear(v);
	}
}

main()
{
	IOS
	cin >> n;
	forn(2, i, n)
	{
		int l;
		char c;
		cin >> l >> c;
		edge[l].pb(mp(i, (int) c));
	}
	deep[1] = 1;
	dfs_cnt(1);
	dfs(1);
	forn(1, i, n)
	{
		cout << ans[i] << " ";
	}
}


#include <bits/stdc++.h>

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#define ll long long
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define o cout<<"BUG"<<endl;
#define	IOS ios_base::sync_with_stdio(0);
#define en "\n"
#define FOR(i, j, n) for(int j = i; j < n; ++j)
#define forn(i, j, n) for(int j = i; j <= n; ++j)
#define nfor(i, j, n) for(int j = n; j >= i; --j)
#define sortv(vv) sort(vv.begin(), vv.end())

using namespace std;
const ll maxn=5e5+100,inf=1e18,LOG=23,mod=1e9 + 7;

#define int ll
int n, ans[maxn], deep[maxn], mask[maxn], deepmask[(1 << LOG)], res, sz[maxn], p[maxn];
vector <pair <int, int> > edge[maxn];

void dfs_cnt(int v, int mas = 0)
{
	mask[v] = mas;
	int mxsz = 0;
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		int ch = edge[v][i].s;
		deep[to] = deep[v] + 1;
		dfs_cnt(to, mas ^ (1 << (ch - 'a')));
		sz[v] += sz[to];
		if(mxsz < sz[to])
		{
			mxsz = sz[to];
			p[v] = to;
		}
	}
	sz[v]++;
}

void add(int v)
{
	deepmask[mask[v]] = max(deep[v], deepmask[mask[v]]);
}
/*13
1 a
2 b
3 d
3 a
4 a
5 d
6 d
7 a
3 a
10 b
11 b
9 a*/
void upd(int v, int root)
{
	forn(0, i, LOG - 1)
	{
		int mas = mask[v] ^ (1 << i);
		res = max(res, deepmask[mas] + deep[v] - deep[root] * 2);
	}
	res = max(res, deepmask[mask[v]] + deep[v] - deep[root] * 2);
}

void dfs_upd(int v, int root)
{
	upd(v, root);
	FOR(0, i, edge[v].size())
	{
		dfs_upd(edge[v][i].f, root);
	}
}

void dfs_add(int v)
{
	add(v);
	FOR(0, i, edge[v].size())
	{
		dfs_add(edge[v][i].f);
	}
}

void dfs_clear(int v)
{
	deepmask[mask[v]] = -1e9;
	FOR(0, i, edge[v].size())
	{
		dfs_clear(edge[v][i].f);
	}
}

void dfs(int v, int cl = 0)
{
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs(to, 1);
	}
	if(p[v] != 0) dfs(p[v], 0);
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs_upd(to, v);
	}
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs_add(to);
	}
	upd(v, v);
	add(v);
	ans[v] = res;
	if(cl)
	{
		res = 0;
		dfs_clear(v);
	}
}

main()
{
	IOS
	cin >> n;
	forn(2, i, n)
	{
		int l;
		char c;
		cin >> l >> c;
		edge[l].pb(mp(i, (int) c));
	}
	forn(0, i, (1 << LOG) - 1)
	{
		deepmask[i] = -1e9;
	}
	deep[1] = 1;
	dfs_cnt(1);
	dfs(1);
	forn(1, i, n)
	{
		cout << ans[i] << " ";
	}
}


#include <bits/stdc++.h>

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#define ll long long
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define o cout<<"BUG"<<endl;
#define	IOS ios_base::sync_with_stdio(0);
#define en "\n"
#define FOR(i, j, n) for(int j = i; j < n; ++j)
#define forn(i, j, n) for(int j = i; j <= n; ++j)
#define nfor(i, j, n) for(int j = n; j >= i; --j)
#define sortv(vv) sort(vv.begin(), vv.end())

using namespace std;
const ll maxn=5e5+100,inf=1e18,LOG=23,mod=1e9 + 7;

#define int ll
int n, ans[maxn], deep[maxn], mask[maxn], deepmask[(1 << LOG)], res, sz[maxn], p[maxn];
vector <pair <int, int> > edge[maxn];

void dfs_cnt(int v, int mas = 0)
{
	mask[v] = mas;
	int mxsz = 0;
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		int ch = edge[v][i].s;
		deep[to] = deep[v] + 1;
		dfs_cnt(to, mas ^ (1 << (ch - 'a')));
		sz[v] += sz[to];
		if(mxsz < sz[to])
		{
			mxsz = sz[to];
			p[v] = to;
		}
	}
	sz[v]++;
}

void add(int v)
{
	deepmask[mask[v]] = max(deep[v], deepmask[mask[v]]);
}
/*13
1 a
2 b
3 d
3 a
4 a
5 d
6 d
7 a
3 a
10 b
11 b
9 a*/
void upd(int v, int root)
{
	forn(0, i, LOG - 1)
	{
		int mas = mask[v] ^ (1 << i);
		res = max(res, deepmask[mas] + deep[v] - deep[root] * 2);
	}
	res = max(res, deepmask[mask[v]] + deep[v] - deep[root] * 2);
}

void dfs_upd(int v, int root)
{
	upd(v, root);
	FOR(0, i, edge[v].size())
	{
		dfs_upd(edge[v][i].f, root);
	}
}

void dfs_add(int v)
{
	add(v);
	FOR(0, i, edge[v].size())
	{
		dfs_add(edge[v][i].f);
	}
}

void dfs_clear(int v)
{
	deepmask[mask[v]] = -1e9;
	FOR(0, i, edge[v].size())
	{
		dfs_clear(edge[v][i].f);
	}
}

void dfs(int v, int cl = 0)
{
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs(to, 1);
	}
	if(p[v] != 0) dfs(p[v], 0);
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs_upd(to, v);
		dfs_add(to);
	}
	upd(v, v);
	add(v);
	ans[v] = res;
	if(cl)
	{
		res = 0;
		dfs_clear(v);
	}
}

void dfs2(int v)
{
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		dfs2(to);
		ans[v] = max(ans[v], ans[to]);
	}
}

main()
{
	IOS
	cin >> n;
	forn(2, i, n)
	{
		int l;
		char c;
		cin >> l >> c;
		edge[l].pb(mp(i, (int) c));
	}
	forn(0, i, (1 << LOG) - 1)
	{
		deepmask[i] = -1e9;
	}
	deep[1] = 1;
	dfs_cnt(1);
	dfs(1);
	dfs2(1);
	forn(1, i, n)
	{
		cout << ans[i] << " ";
	}
}


#include <bits/stdc++.h>

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#define ll long long
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define o cout<<"BUG"<<endl;
#define	IOS ios_base::sync_with_stdio(0);
#define en "\n"
#define FOR(i, j, n) for(int j = i; j < n; ++j)
#define forn(i, j, n) for(int j = i; j <= n; ++j)
#define nfor(i, j, n) for(int j = n; j >= i; --j)
#define sortv(vv) sort(vv.begin(), vv.end())

using namespace std;
const ll maxn=5e5+100,inf=1e18,LOG=24,mod=1e9 + 7;

#define int ll
int n, ans[maxn], deep[maxn], mask[maxn], deepmask[(1 << LOG)], res, sz[maxn], p[maxn];
vector <pair <int, int> > edge[maxn];

void dfs_cnt(int v, int mas = 0)
{
	mask[v] = mas;
	int mxsz = 0;
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		int ch = edge[v][i].s;
		deep[to] = deep[v] + 1;
		dfs_cnt(to, mas ^ (1 << (ch - 'a')));
		sz[v] += sz[to];
		if(mxsz < sz[to])
		{
			mxsz = sz[to];
			p[v] = to;
		}
	}
	sz[v]++;
}

void add(int v)
{
	deepmask[mask[v]] = max(deep[v], deepmask[mask[v]]);
}
/*13
1 a
2 b
3 d
3 a
4 a
5 d
6 d
7 a
3 a
10 b
11 b
9 a*/
void upd(int v, int root)
{
	forn(0, i, LOG - 1)
	{
		int mas = mask[v] ^ (1 << i);
		res = max(res, deepmask[mas] + deep[v] - deep[root] * 2);
	}
	res = max(res, deepmask[mask[v]] + deep[v] - deep[root] * 2);
}

void dfs_upd(int v, int root)
{
	upd(v, root);
	FOR(0, i, edge[v].size())
	{
		dfs_upd(edge[v][i].f, root);
	}
}

void dfs_add(int v)
{
	add(v);
	FOR(0, i, edge[v].size())
	{
		dfs_add(edge[v][i].f);
	}
}

void dfs_clear(int v)
{
	deepmask[mask[v]] = 0;
	FOR(0, i, edge[v].size())
	{
		dfs_clear(edge[v][i].f);
	}
}

void dfs(int v, int cl = 0)
{
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs(to, 1);
	}
	if(p[v] != 0) dfs(p[v], 0);
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs_upd(to, v);
		dfs_add(to);
	}
	upd(v, v);
	add(v);
	ans[v] = res;
	if(cl)
	{
		res = 0;
		dfs_clear(v);
	}
}

main()
{
	IOS
	cin >> n;
	forn(2, i, n)
	{
		int l;
		char c;
		cin >> l >> c;
		edge[l].pb(mp(i, (int) c));
	}
	deep[1] = 1;
	dfs_cnt(1);
	dfs(1);
	forn(1, i, n)
	{
		cout << ans[i] << " ";
	}
}


#include <bits/stdc++.h>

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#define ll long long
#define f first
#define s second
#define pb push_back
#define mp make_pair
#define o cout<<"BUG"<<endl;
#define	IOS ios_base::sync_with_stdio(0);
#define en "\n"
#define FOR(i, j, n) for(int j = i; j < n; ++j)
#define forn(i, j, n) for(int j = i; j <= n; ++j)
#define nfor(i, j, n) for(int j = n; j >= i; --j)
#define sortv(vv) sort(vv.begin(), vv.end())

using namespace std;
const ll maxn=5e5+100,inf=1e18,LOG=24,mod=1e9 + 7;

#define int ll
int n, ans[maxn], deep[maxn], mask[maxn], deepmask[(1 << LOG)], res, sz[maxn], p[maxn];
vector <pair <int, int> > edge[maxn];

void dfs_cnt(int v, int mas = 0)
{
	mask[v] = mas;
	int mxsz = 0;
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		int ch = edge[v][i].s;
		deep[to] = deep[v] + 1;
		dfs_cnt(to, mas ^ (1 << (ch - 'a')));
		sz[v] += sz[to];
		if(mxsz < sz[to])
		{
			mxsz = sz[to];
			p[v] = to;
		}
	}
	sz[v]++;
}

void add(int v)
{
	deepmask[mask[v]] = max(deep[v], deepmask[mask[v]]);
}
/*13
1 a
2 b
3 d
3 a
4 a
5 d
6 d
7 a
3 a
10 b
11 b
9 a*/
void upd(int v, int root)
{
	forn(0, i, LOG - 1)
	{
		int mas = mask[v] ^ (1 << i);
		if(deepmask[mas] == 0) continue;
		res = max(res, deepmask[mas] + deep[v] - deep[root] * 2);
	}
	if(deepmask[mask[v]] == 0) return;
	res = max(res, deepmask[mask[v]] + deep[v] - deep[root] * 2);
}

void dfs_upd(int v, int root)
{
	upd(v, root);
	FOR(0, i, edge[v].size())
	{
		dfs_upd(edge[v][i].f, root);
	}
}

void dfs_add(int v)
{
	add(v);
	FOR(0, i, edge[v].size())
	{
		dfs_add(edge[v][i].f);
	}
}

void dfs_clear(int v)
{
	deepmask[mask[v]] = 0;
	FOR(0, i, edge[v].size())
	{
		dfs_clear(edge[v][i].f);
	}
}

void dfs(int v, int cl = 0)
{
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs(to, 1);
	}
	if(p[v] != 0) dfs(p[v], 0);
	FOR(0, i, edge[v].size())
	{
		int to = edge[v][i].f;
		if(to == p[v]) continue;
		dfs_upd(to, v);
		dfs_add(to);
	}
	upd(v, v);
	add(v);
	ans[v] = res;
	if(cl)
	{
		res = 0;
		dfs_clear(v);
	}
}

main()
{
	IOS
	cin >> n;
	forn(2, i, n)
	{
		int l;
		char c;
		cin >> l >> c;
		edge[l].pb(mp(i, (int) c));
	}
	deep[1] = 1;
	dfs_cnt(1);
	dfs(1);
	forn(1, i, n)
	{
		cout << ans[i] << " ";
	}
}