#include<bits/stdc++.h>
using namespace std;
#define int long long
struct Edge{int to,next;}edge[500000<<1]; int first[500000],le=2,a[500000]; char s[500000];
void add(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
int sum[500000],out[500000],sz[500000],vis[500000],n;
void getsize(int x,int fa)
{
    sz[x]=1;
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || vis[e.to]) continue;
        getsize(e.to,x); sz[x]+=sz[e.to];
    }
}

int getroot(int x,int fa,int tot)
{
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || vis[e.to]) continue;
        if (sz[e.to]*2>tot) return getroot(e.to,x,tot);
    }
    return x;
}

void dfs(int x,int fa,int now,int v)
{
    now^=1<<a[x]; sum[now]+=v;
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || vis[e.to]) continue;
        dfs(e.to,x,now,v);
    }
}

int calc(int x,int fa,int now)
{
    now^=1<<a[x]; int t=0;
    for (int i=0;i<20;i++) t+=sum[now^(1<<i)];
    t+=sum[now];
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || vis[e.to]) continue;
        t+=calc(e.to,x,now);
    }
    out[x]+=t; return t;
}

void solve(int x)
{
    dfs(x,0,0,1); vis[x]=1;
    int now=0;
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (vis[e.to]) continue;
        dfs(e.to,x,1<<a[x],-1);
        now+=calc(e.to,x,0);
        dfs(e.to,x,1<<a[x],1);
    }

    for (int i=0;i<20;i++) now+=sum[1<<i];
    now+=sum[0]+1; out[x]+=now>>1;
    dfs(x,0,0,-1);
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (vis[e.to]) continue;
        getsize(e.to,0); solve(getroot(e.to,0,sz[e.to]));
    }
}

main()
{
    scanf("%lld",&n);
    for (int i=1,x,y;i<n;i++) scanf("%lld%lld",&x,&y),add(x,y),add(y,x);
    scanf("%s",s+1); for (int i=1;i<=n;i++) a[i]=s[i]-'a';
    getsize(1,0);
    solve(getroot(1,0,sz[1]));
    for (int i=1;i<=n;i++) printf("%lld ",out[i]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
struct Edge{int to,next;}E[500000];
int n,i,first[500000],top=2,a[500000],cnt[500000],out[500000],size[500000],vis[500000],x,y;
char s[500000];
void add(int x,int y) {++top;E[top].to=y; E[top].next=first[x]; first[x]=top;}
void getsize(int x,int fa)
{
    size[x]=1;
    for (i=first[x];i;i=E[i].next)
    if((E[i].to^fa)&&(!vis[E[i].to]))getsize(E[i].to,x),size[x]+=size[E[i].to];
}
int getroot(int x,int fa,int tot)
{
    for (i=first[x];i;i=E[i].next)
    if((E[i].to^fa)&&(!vis[E[i].to]))if (size[E[i].to]*2>tot) return getroot(E[i].to,x,tot);
    return x;
}
void dfs(int x,int fa,int now,int v)
{
    now^=1<<a[x]; cnt[now]+=v;
    for (i=first[x];i;i=E[i].next)
    if((E[i].to^fa)&&(!vis[E[i].to]))dfs(E[i].to,x,now,v);
}
int calc(int x,int fa,int now)
{
    now^=1<<a[x]; int t=0;
    for (i=0;i<20;i++) t+=cnt[now^(1<<i)];
    t+=cnt[now];
    for (i=first[x];i;i=E[i].next)
    if((E[i].to^fa)&&(!vis[E[i].to]))t+=calc(E[i].to,x,now);
    out[x]+=t; return t;
}
void solve(int x)
{
    dfs(x,0,0,1);vis[x]=1;
    int now=0;
    for (i=first[x];i;i=E[i].next)
    if(!vis[E[i].to])dfs(E[i].to,x,1<<a[x],-1),now+=calc(E[i].to,x,0),dfs(E[i].to,x,1<<a[x],1);

    for (i=0;i<20;i++) now+=cnt[1<<i];
    now+=cnt[0]+1,out[x]+=now>>1;
    dfs(x,0,0,-1);
    for (i=first[x];i;i=E[i].next)
    if(!vis[E[i].to])getsize(E[i].to,0),solve(getroot(E[i].to,0,size[E[i].to]));
}

main()
{
    scanf("%lld",&n);
    for (i=1;i<n;i++) scanf("%lld%d",&x,&y),add(x,y),add(y,x);
    scanf("%s",s+1); for (i=1;i<=n;i++) a[i]=s[i]-'a';
    getsize(1,0),solve(getroot(1,0,size[1]));
    for (i=1;i<=n;i++) printf("%lld ",out[i]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
struct Edge{int to,ne;}E[500000];
int n,i,fir[500000],top=2,a[500000],sum[500000],out[500000],sz[500000],vis[500000],x,y;
char s[500000];
void add(int x,int y) {++top;E[top].to=y; E[top].ne=fir[x]; fir[x]=top;}
void getsize(int x,int fa)
{
    sz[x]=1;
    for (i=fir[x];i;i=E[i].ne)
    if((E[i].to^fa)&&(!vis[E[i].to]))getsize(E[i].to,x),sz[x]+=sz[E[i].to];
}
int getroot(int x,int fa,int tot)
{
    for (i=fir[x];i;i=E[i].ne)
    if((E[i].to^fa)&&(!vis[E[i].to]))if (sz[E[i].to]*2>tot) return getroot(E[i].to,x,tot);
    return x;
}
void dfs(int x,int fa,int now,int v)
{
    now^=1<<a[x]; sum[now]+=v;
    for (i=fir[x];i;i=E[i].ne)
    if((E[i].to^fa)&&(!vis[E[i].to]))dfs(E[i].to,x,now,v);
}
int calc(int x,int fa,int now)
{
    now^=1<<a[x]; int t=0;
    for (i=0;i<20;i++) t+=sum[now^(1<<i)];
    t+=sum[now];
    for (i=fir[x];i;i=E[i].ne)
    if((E[i].to^fa)&&(!vis[E[i].to]))t+=calc(E[i].to,x,now);
    out[x]+=t; return t;
}
void solve(int x)
{
    dfs(x,0,0,1);vis[x]=1;
    int now=0;
    for (i=fir[x];i;i=E[i].ne)
    if(!vis[E[i].to])dfs(E[i].to,x,1<<a[x],-1),now+=calc(E[i].to,x,0),dfs(E[i].to,x,1<<a[x],1);

    for (i=0;i<20;i++) now+=sum[1<<i];
    now+=sum[0]+1,out[x]+=now>>1,dfs(x,0,0,-1);
    for (i=fir[x];i;i=E[i].ne)
    if(!vis[E[i].to])getsize(E[i].to,0),solve(getroot(E[i].to,0,sz[E[i].to]));
}

main()
{
    scanf("%lld",&n);
    for (i=1;i<n;i++) scanf("%lld%d",&x,&y),add(x,y),add(y,x);
    scanf("%s",s+1); for (i=1;i<=n;i++) a[i]=s[i]-'a';
    getsize(1,0),solve(getroot(1,0,sz[1]));
    for (i=1;i<=n;i++) printf("%lld ",out[i]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;

int n;
#define maxn 200011
struct Edge{int to,next;}edge[maxn<<1]; int first[maxn],le=2,val[maxn]; char s[maxn];
void in(int x,int y) {Edge &e=edge[le]; e.to=y; e.next=first[x]; first[x]=le++;}
void insert(int x,int y) {in(x,y); in(y,x);}

#define maxs 1111111
int cnt[maxs];

#define LL long long
LL ans[maxn]; int sz[maxn]; bool die[maxn];
void getsz(int x,int fa)
{
    sz[x]=1;
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
        getsz(e.to,x); sz[x]+=sz[e.to];
    }
}

int getroot(int x,int fa,int tot)
{
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
        if (sz[e.to]*2>tot) return getroot(e.to,x,tot);
    }
    return x;
}

void dfscnt(int x,int fa,int now,int v)
{
    now^=1<<val[x]; cnt[now]+=v;
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
        dfscnt(e.to,x,now,v);
    }
}

LL calc(int x,int fa,int now)
{
    now^=1<<val[x]; LL t=0;
    for (int i=0;i<20;i++) t+=cnt[now^(1<<i)];
    t+=cnt[now];
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (e.to==fa || die[e.to]) continue;
        t+=calc(e.to,x,now);
    }
    ans[x]+=t; return t;
}

void cd(int x)
{
    dfscnt(x,0,0,1); die[x]=1;
    LL now=0;
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (die[e.to]) continue;
        dfscnt(e.to,x,1<<val[x],-1);
        now+=calc(e.to,x,0);
        dfscnt(e.to,x,1<<val[x],1);
    }

    for (int i=0;i<20;i++) now+=cnt[1<<i];
    now+=cnt[0]+1; ans[x]+=now>>1;
    dfscnt(x,0,0,-1);
    for (int i=first[x];i;i=edge[i].next)
    {
        const Edge &e=edge[i]; if (die[e.to]) continue;
        getsz(e.to,0); cd(getroot(e.to,0,sz[e.to]));
    }
}

int main()
{
    scanf("%d",&n);
    for (int i=1,x,y;i<n;i++) scanf("%d%d",&x,&y),insert(x,y);
    scanf("%s",s+1); for (int i=1;i<=n;i++) val[i]=s[i]-'a';
    getsz(1,0);
    cd(getroot(1,0,sz[1]));
    for (int i=1;i<=n;i++) printf("%lld ",ans[i]);
    return 0;
}


#include "bits/stdc++.h"
using namespace std;

const int N = 222222;
const int ALPHA = 20;

int n;
int done[N];
int sub[N];
int pathmask[1 << ALPHA];
long long ans[N];
long long put[N];
int C;
long long for_centroid = 0;
string labels;
vector<int> adj[N];

void ComputeSubtreeSizes(int u, int p) {
  sub[u] = 1;
  for (int v: adj[u]) {
    if (v != p and !done[v]) {
      ComputeSubtreeSizes(v, u);
      sub[u] += sub[v];
    }
  }
}

int FindCentroid(int u, int p, int threshold) {
  for (int v: adj[u]) {
    if (v != p && !done[v] && sub[v] > threshold) {
      return FindCentroid(v, u, threshold);
    }
  }
  return u;
}

void Mark(int u, int p, int path_mask) {
  path_mask ^= (1 << (labels[u] - 'a'));
  // Odd frequency palindromes.
  for (int bit = 0; bit < ALPHA; bit++) {
    int target_mask = (1 << bit);
    int required_mask = target_mask ^ path_mask;
    put[u] += pathmask[required_mask];
    for_centroid += pathmask[required_mask];
  }
  // Even frequency palindromes.
  put[u] += pathmask[path_mask];
  for_centroid += pathmask[path_mask];
  // Edge case for path from centroid to u
  if (__builtin_popcount(path_mask) <= 1) {
    put[u] += 1;
    ans[C]++;
  }
  for (int v: adj[u]) {
    if (v != p && !done[v]) {
      Mark(v, u, path_mask);
    }
  }
}

void Collect(int u, int p) {
  for (int v: adj[u]) {
    if (v != p and !done[v]) {
      Collect(v, u);
      put[u] += put[v];
    }
  }
  ans[u] += put[u];
}

void Add(int u, int p, int path_mask, int delta) {
  path_mask ^= (1 << (labels[u] - 'a'));
  pathmask[path_mask] += delta;
  if (delta == -1) {
    put[u] = 0;
  }
  for (int v: adj[u]) {
    if (v != p and !done[v]) {
      Add(v, u, path_mask, delta);
    }
  }
}

void Solve(int centroid) {
  for (int child: adj[centroid]) {
    if (!done[child]) {
      Add(child, centroid, 0, +1);
    }
  }
  ans[centroid]++;
  C = centroid;
  for (int child: adj[centroid]) {
    if (!done[child]) {
      Add(child, centroid, 0, -1);
      Mark(child, centroid, 1 << (labels[centroid] - 'a'));
      Collect(child, centroid);
      Add(child, centroid, 0, +1);
    }
  }
  ans[centroid] += (for_centroid >> 1);
  for_centroid = 0;
  // Reset the counts for future centroids.
  for (int child: adj[centroid]) {
    if (!done[child]) {
      Add(child, centroid, 0, -1);
    }
  }
}

void Decompose(int root) {
  ComputeSubtreeSizes(root, root);
  int centroid = FindCentroid(root, root, sub[root] >> 1);
  Solve(centroid);
  done[centroid] = true;
  for (int next_node: adj[centroid]) {
    if (!done[next_node]) {
      Decompose(next_node);
    }
  }
}

int main() {
  ios :: sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i < n; i++) {
    int u, v; cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  cin >> labels; labels = '$' + labels;
  Decompose(1);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] << ' ';
  }
  cout << endl;
}


#include "bits/stdc++.h"
using namespace std;

const int N = 222222;
const int ALPHA = 20;

int n;
int done[N];
int sub[N];
int pathmask[1 << ALPHA];
long long ans[N];
long long put[N];
int C;
long long for_centroid = 0;
string labels;
vector<int> adj[N];

void ComputeSubtreeSizes(int u, int p) {
  sub[u] = 1;
  for (int v: adj[u]) {
    if (v != p and !done[v]) {
      ComputeSubtreeSizes(v, u);
      sub[u] += sub[v];
    }
  }
}

int FindCentroid(int u, int p, int threshold) {
  for (int v: adj[u]) {
    if (v != p && !done[v] && sub[v] > threshold) {
      return FindCentroid(v, u, threshold);
    }
  }
  return u;
}

void Mark(int u, int p, int path_mask) {
  path_mask ^= (1 << (labels[u] - 'a'));
  // Odd frequency palindromes.
  for (int bit = 0; bit < ALPHA; bit++) {
    int target_mask = (1 << bit);
    int required_mask = target_mask ^ path_mask;
    put[u] += pathmask[required_mask];
    for_centroid += pathmask[required_mask];
  }
  // Even frequency palindromes.
  put[u] += pathmask[path_mask];
  for_centroid += pathmask[path_mask];
  // Edge case for path from centroid to u
  if (__builtin_popcount(path_mask) <= 1) {
    put[u] += 1;
    ans[C]++;
  }
  for (int v: adj[u]) {
    if (v != p && !done[v]) {
      Mark(v, u, path_mask);
    }
  }
}

void Collect(int u, int p) {
  for (int v: adj[u]) {
    if (v != p and !done[v]) {
      Collect(v, u);
      put[u] += put[v];
    }
  }
  ans[u] += put[u];
}

void Add(int u, int p, int path_mask, int delta) {
  path_mask ^= (1 << (labels[u] - 'a'));
  pathmask[path_mask] += delta;
  if (delta == -1) {
    put[u] = 0;
  }
  for (int v: adj[u]) {
    if (v != p and !done[v]) {
      Add(v, u, path_mask, delta);
    }
  }
}

void Solve(int centroid) {
  for (int child: adj[centroid]) {
    if (!done[child]) {
      Add(child, centroid, 0, +1);
    }
  }
  ans[centroid]++;
  C = centroid;
  for (int child: adj[centroid]) {
    if (!done[child]) {
      Add(child, centroid, 0, -1);
      Mark(child, centroid, 1 << (labels[centroid] - 'a'));
      Collect(child, centroid);
      Add(child, centroid, 0, +1);
    }
  }
  ans[centroid] += (for_centroid >> 1);
  for_centroid = 0;
  // Reset the counts for future centroids.
  for (int child: adj[centroid]) {
    if (!done[child]) {
      Add(child, centroid, 0, -1);
    }
  }
}

void Decompose(int root) {
  ComputeSubtreeSizes(root, root);
  int centroid = FindCentroid(root, root, sub[root] >> 1);
  Solve(centroid);
  done[centroid] = true;
  for (int next_node: adj[centroid]) {
    if (!done[next_node]) {
      Decompose(next_node);
    }
  }
}

int main() {
  freopen ("inp.in", "r", stdin);
  ios :: sync_with_stdio(false);
  cin >> n;
  for (int i = 1; i < n; i++) {
    int u, v; cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  cin >> labels; labels = '$' + labels;
  Decompose(1);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] << ' ';
  }
  cout << endl;
}


#include<bits/stdc++.h>
using namespace std;
const int Mod = 1000000000+7;
const int oo = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long LL;
typedef priority_queue<int> QMax;
typedef priority_queue<int,vector<int>,greater<int>> QMin;
#define lbit(a) (a&-a)
#define SZ(a) (int)a.size()
#define fi first
#define se second
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define s2int(a,b) scanf("%d%d",&a,&b)
#define sint(a) scanf("%d%d",&a)
#define s2ll(a,b) scanf("%I64d%I64d",&a,&b)
#define sll(a) scanf("%I64d%I64d",&a);
#define mem(a,b) memset(a,b,sizeof a)

#ifdef CF
	#define FOPEN freopen("in.txt","r",stdin)
	#define BUG(x) cout<<x<<"_"<<endl;
#else
	#define FOPEN ;
	#define BUG(x) ;
#endif

const int N = 200000+9;

vi V[N];
int n,a[N];
int sum,f[N],sz[N],root,vis[N];
LL ans[N],cnt[1<<21];
void getroot(int u,int fa){
	sz[u]=1;f[u]=0;
	for(int i:V[u]){
		if(i!=fa&&!vis[i]){
			getroot(i,u);
			sz[u]+=sz[i];
			f[u]=max(f[u],sz[i]);
		}
	}
	f[u]=max(f[u],sum-sz[u]);
	if(f[u]<f[root]) root=u;
}
void col(int u,int fa,int mark,int op){
	mark^=1<<a[u];
	cnt[mark]+=op;
	for(int i:V[u]){
		if(!vis[i]&&i!=fa){
			col(i,u,mark,op);
		}
	}
}
LL Cross(int u,int fa,int mark){
	mark^=1<<a[u];
	LL res=cnt[0^mark];
	for(int i=0;i<20;i++)res+=cnt[(1<<i)^mark];
	for(int i:V[u]){
		if(!vis[i]&&i!=fa){
			res+=Cross(i,u,mark);
		}
	}
	ans[u]+=res;
	return res;
}
void solve(int u){
	vis[u]=1;
	col(u,0,0,1);
	LL tmp=0;
	tmp+=cnt[0];
	for(int i=0;i<20;i++)tmp+=cnt[1<<i];
	for(int i:V[u]){
		if(vis[i])continue;
		col(i,u,1<<a[u],-1);
		tmp+=Cross(i,u,0);
		col(i,u,1<<a[u],1);
	}
	col(u,0,0,-1);
	ans[u]+=(tmp+1)/2;
	for(int i:V[u]){
		if(vis[i])continue;
		root=0;
		sum=sz[i];
		getroot(i,u);
		solve(root);
	}
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;s2int(u,v);
		V[u].pb(v);V[v].pb(u);
	}
	string c;cin>>c;
	for(int i=0;i<n;i++)a[i+1]=c[i]-'a';
	sum=f[0]=n;
	root=0;
	getroot(1,0);
	solve(root);
	for(int i=1;i<=n;i++)printf("%I64d ",ans[i]);
}


#include<bits/stdc++.h>
using namespace std;
const int Mod = 1000000000+7;
const int oo = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long LL;
typedef priority_queue<int> QMax;
typedef priority_queue<int,vector<int>,greater<int>> QMin;
#define lbit(a) (a&-a)
#define SZ(a) (int)a.size()
#define fi first
#define se second
#define pb push_back
#define all(a) (a).begin(),(a).end()
#ifdef CF
	#define FOPEN freopen("in.txt","r",stdin)
	#define BUG(x) cout<<x<<"_"<<endl;
#else
	#define FOPEN ;
	#define BUG(x) ;
#endif

const int N = 200000+9;

vi V[N];
int n,a[N];
map<int,LL> G[N];
LL ans[N];

void dfs(int u,int fa){
	int p=1<<a[u];
	for(int v:V[u]){
		if(v!=fa){
			dfs(v,u);
			for(auto i:G[v]){
				int val=i.first;
				LL cnt=i.second;
				if(G[u].count(val))
					ans[u]+=G[u][val]*cnt;
				for(int j=0;j<22;j++)
					if(G[u].count(val^(1<<j)))
						ans[u]+=G[u][val^(1<<j)]*cnt;
			}
			for(auto i:G[v]){
				G[u][i.first^p]+=i.second;
			}
		}
	}
	G[u][p]++;
	for(int i=0;i<22;i++)
		if(G[u].count(1<<i))
			ans[u]+=G[u][1<<i];
	ans[u]+=G[u][0];
}
void dfs2(int u,int fa){
	if(fa==-1){
		for(int v:V[u]){
			dfs2(v,u);
		}
	}else{
		int p=1<<a[u];
		map<int,LL> gfa=G[fa];
		for(auto i:G[u]){
			gfa[i.first^(1<<a[fa])]-=i.second;
		}
		for(auto i:G[u]){
			if(gfa.count(i.first))ans[u]+=gfa[i.first]*i.second;
			for(int j=0;j<22;j++){
				if(gfa.count(i.fi^(1<<j))) ans[u]+=gfa[i.fi^(1<<j)]*(i.se);
			}
		}
		for(auto i:gfa){
			G[u][i.fi^p]+=i.se;
		}
		gfa.clear();
		for(int v:V[u]){
			if(v==fa)continue;
			dfs2(v,u);
		}
	}
	G[u].clear();
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		u--;v--;
		V[u].pb(v);
		V[v].pb(u);
	}
	string c;
	cin>>c;
	for(int i=0;i<n;i++){
		a[i]=c[i]-'a';
	}
	dfs(0,-1);
	dfs2(0,-1);
	for(int i=0;i<n;i++){
		printf("%I64d ",ans[i]);
	}

}


#include<bits/stdc++.h>
using namespace std;
const int Mod = 1000000000+7;
const int oo = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long LL;
typedef priority_queue<int> QMax;
typedef priority_queue<int,vector<int>,greater<int>> QMin;
#define lbit(a) (a&-a)
#define SZ(a) (int)a.size()
#define fi first
#define se second
#define pb push_back
#define all(a) (a).begin(),(a).end()
#ifdef CF
	#define FOPEN freopen("in.txt","r",stdin)
	#define BUG(x) cout<<x<<"_"<<endl;
#else
	#define FOPEN ;
	#define BUG(x) ;
#endif

const int N = 200000+9;

vi V[N];
int n,a[N];
map<int,LL> G[N];
LL ans[N];

void dfs(int u,int fa){
	int p=1<<a[u];
	for(int v:V[u]){
		if(v!=fa){
			dfs(v,u);
			for(auto i:G[v]){
				int val=i.first;
				LL cnt=i.second;
				if(G[u].count(val))
					ans[u]+=G[u][val]*cnt;
				for(int j=0;j<22;j++)
					if(G[u].count(val^(1<<j)))
						ans[u]+=G[u][val^(1<<j)]*cnt;
			}
			for(auto i:G[v]){
				G[u][i.first^p]+=i.second;
			}
		}
	}
	G[u][p]++;
	for(int i=0;i<22;i++)
		if(G[u].count(1<<i))
			ans[u]+=G[u][1<<i];
	ans[u]+=G[u][0];
}
void dfs2(int u,int fa){
	if(fa==-1){
		for(int v:V[u]){
			dfs2(v,u);
		}
	}else{
		int p=1<<a[u];
		map<int,LL> gfa=G[fa];
		for(auto i:G[u]){
			gfa[i.first^(1<<a[fa])]-=i.second;
		}
		for(auto i:G[u]){
			if(gfa.count(i.first))ans[u]+=gfa[i.first]*i.second;
			for(int j=0;j<22;j++){
				if(gfa.count(i.fi^(1<<j))) ans[u]+=gfa[i.fi^(1<<j)]*(i.se);
			}
		}
		for(auto i:gfa){
			G[u][i.fi^p]+=i.se;
		}
		for(int v:V[u]){
			if(v==fa)continue;
			dfs2(v,u);
		}
	}
	G[u].clear();
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		u--;v--;
		V[u].pb(v);
		V[v].pb(u);
	}
	string c;
	cin>>c;
	for(int i=0;i<n;i++){
		a[i]=c[i]-'a';
	}
	dfs(0,-1);
	dfs2(0,-1);
	for(int i=0;i<n;i++){
		printf("%I64d ",ans[i]);
	}

}


#include<bits/stdc++.h>
using namespace std;
const int Mod = 1000000000+7;
const int oo = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long LL;
typedef priority_queue<int> QMax;
typedef priority_queue<int,vector<int>,greater<int>> QMin;
#define lbit(a) (a&-a)
#define SZ(a) (int)a.size()
#define fi first
#define se second
#define pb push_back
#define all(a) (a).begin(),(a).end()
#ifdef CF
	#define FOPEN freopen("in.txt","r",stdin)
	#define BUG(x) cout<<x<<"_"<<endl;
#else
	#define FOPEN ;
	#define BUG(x) ;
#endif

const int N = 200000+9;

vi V[N];
int n,a[N];
map<int,LL> G[N];
LL ans[N];

int ok[1<<22];
void dfs(int u,int fa){
	int p=1<<a[u];
	for(int v:V[u]){
		if(v!=fa){
			dfs(v,u);
			for(auto i:G[v]){
				int val=i.first;
				LL cnt=i.second;
				if(G[u].count(val))
					ans[u]+=G[u][val]*cnt;
				for(int j=0;j<22;j++)
					if(G[u].count(val^(1<<j)))
						ans[u]+=G[u][val^(1<<j)]*cnt;
			}
			for(auto i:G[v]){
				G[u][i.first^p]+=i.second;
			}
		}
	}
	G[u][p]++;
	for(int i=0;i<22;i++)
		if(G[u].count(1<<i))
			ans[u]+=G[u][1<<i];
	ans[u]+=G[u][0];
}
void dfs2(int u,int fa){
	if(fa==-1){
		for(int v:V[u]){
			dfs2(v,u);
		}
	}else{
		int p=1<<a[u];
		map<int,LL> gfa=G[fa];
		for(auto i:G[u]){
			gfa[i.first^(1<<a[fa])]-=i.second;
		}
		for(auto i:G[u]){
			if(gfa.count(i.first))ans[u]+=gfa[i.first]*i.second;
			for(int j=0;j<22;j++){
				if(gfa.count(i.fi^(1<<j))) ans[u]+=gfa[i.fi^(1<<j)]*(i.se);
			}
		}
		for(auto i:gfa){
			G[u][i.fi^p]+=i.se;
		}
		for(int v:V[u]){
			if(v==fa)continue;
			dfs2(v,u);
		}
	}
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		u--;v--;
		V[u].pb(v);
		V[v].pb(u);
	}
	string c;
	cin>>c;
	for(int i=0;i<n;i++){
		a[i]=c[i]-'a';
	}
	dfs(0,-1);
	dfs2(0,-1);
	for(int i=0;i<n;i++){
		printf("%I64d ",ans[i]);
	}

}


#include<bits/stdc++.h>
using namespace std;
const int Mod = 1000000000+7;
const int oo = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long LL;
typedef priority_queue<int> QMax;
typedef priority_queue<int,vector<int>,greater<int>> QMin;
#define lbit(a) (a&-a)
#define SZ(a) (int)a.size()
#define fi first
#define se second
#define pb push_back
#define all(a) (a).begin(),(a).end()
#ifdef CF
	#define FOPEN freopen("in.txt","r",stdin)
	#define BUG(x) cout<<x<<"_"<<endl;
#else
	#define FOPEN ;
	#define BUG(x) ;
#endif

const int N = 200000+9;

vi V[N];
int n,a[N];
map<int,LL> G[N];
LL ans[N];

int ok[1<<22];
void dfs(int u,int fa){
	int p=1<<a[u];
	for(int v:V[u]){
		if(v!=fa){
			dfs(v,u);
			for(auto i:G[v]){
				int val=i.first;
				LL cnt=i.second;
				if(G[u].count(val))
					ans[u]+=G[u][val]*cnt;
				for(int j=0;j<22;j++)
					if(G[u].count(val^(1<<j)))
						ans[u]+=G[u][val^(1<<j)]*cnt;
			}
			for(auto i:G[v]){
				G[u][i.first^p]+=i.second;
			}
		}
	}
	G[u][p]++;
	for(int i=0;i<22;i++)
		if(G[u].count(1<<i))
			ans[u]+=G[u][1<<i];
	ans[u]+=G[u][0];
}
void dfs2(int u,int fa){
	if(fa==-1){
		for(int v:V[u]){
			dfs2(v,u);
		}
	}else{
		int p=1<<a[u];
		map<int,LL> gfa=G[fa];
		for(auto i:G[u]){
			gfa[i.first^(1<<a[fa])]-=i.second;
		}
		for(auto i:G[u]){
			if(gfa.count(i.first))ans[u]+=gfa[i.first]*i.second;
			for(int j=0;j<22;j++){
				if(gfa.count(i.fi^(1<<j))) ans[u]+=gfa[i.fi^(1<<j)]*(i.se);
			}
		}
		for(auto i:gfa){
			G[u][i.fi^p]+=i.se;
		}
		for(int v:V[u]){
			if(v==fa)continue;
			dfs2(v,u);
		}
	}
	G[u].clear();
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;scanf("%d%d",&u,&v);
		u--;v--;
		V[u].pb(v);
		V[v].pb(u);
	}
	string c;
	cin>>c;
	for(int i=0;i<n;i++){
		a[i]=c[i]-'a';
	}
	dfs(0,-1);
	dfs2(0,-1);
	for(int i=0;i<n;i++){
		printf("%I64d ",ans[i]);
	}

}


#include<bits/stdc++.h>
using namespace std;
const int Mod = 1000000000+7;
const int oo = 0x3f3f3f3f;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef long long LL;
typedef priority_queue<int> QMax;
typedef priority_queue<int,vector<int>,greater<int>> QMin;
#define lbit(a) (a&-a)
#define SZ(a) (int)a.size()
#define fi first
#define se second
#define pb push_back
#define all(a) (a).begin(),(a).end()
#define s2int(a,b) scanf("%d%d",&a,&b)
#define sint(a) scanf("%d%d",&a)
#define s2ll(a,b) scanf("%I64d%I64d",&a,&b)
#define sll(a) scanf("%I64d%I64d",&a);
#define mem(a,b) memset(a,b,sizeof a)

#ifdef CF
	#define FOPEN freopen("in.txt","r",stdin)
	#define BUG(x) cout<<x<<"_"<<endl;
#else
	#define FOPEN ;
	#define BUG(x) ;
#endif

const int N = 200000+9;

vi V[N];
int n,a[N];
int sum,f[N],sz[N],root,vis[N];
LL ans[N],cnt[1<<21];
void getroot(int u,int fa){
	sz[u]=1;f[u]=0;
	for(int i:V[u]){
		if(i!=fa&&!vis[i]){
			getroot(i,u);
			sz[u]+=sz[i];
			f[u]=max(f[u],sz[i]);
		}
	}
	f[u]=max(f[u],sum-sz[u]);
	if(f[u]<f[root]) root=u;
}
void col(int u,int fa,int mark,int op){
	mark^=1<<a[u];
	cnt[mark]+=op;
	for(int i:V[u]){
		if(!vis[i]&&i!=fa){
			col(i,u,mark,op);
		}
	}
}
LL Cross(int u,int fa,int mark){
	mark^=1<<a[u];
	LL res=cnt[0^mark];
	for(int i=0;i<20;i++)res+=cnt[(1<<i)^mark];
	for(int i:V[u]){
		if(!vis[i]&&i!=fa){
			res+=Cross(i,u,mark);
		}
	}
	ans[u]+=res;
	return res;
}
void solve(int u){
	vis[u]=1;
	col(u,0,0,1);
	LL tmp=0;
	tmp+=cnt[0];
	for(int i=0;i<20;i++)tmp+=cnt[1<<i];
	for(int i:V[u]){
		if(vis[i])continue;
		col(i,u,1<<a[u],-1);
		tmp+=Cross(i,u,0);
		col(i,u,1<<a[u],1);
	}
	col(u,0,0,-1);
	ans[u]+=tmp/2;
	for(int i:V[u]){
		if(vis[i])continue;
		root=0;
		sum=sz[i];
		getroot(i,u);
		solve(root);
	}
}
int main(){
	cin>>n;
	for(int i=1;i<n;i++){
		int u,v;s2int(u,v);
		V[u].pb(v);V[v].pb(u);
	}
	string c;cin>>c;
	for(int i=0;i<n;i++)a[i+1]=c[i]-'a';
	sum=f[0]=n;
	root=0;
	getroot(1,0);
	solve(root);
	for(int i=1;i<=n;i++)printf("%I64d ",ans[i]+1);
}


#include<bits/stdc++.h>
using namespace std;
//#define int long long
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
gp_hash_table<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=mp[mask];
    for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^mask];
    }
    return ans;
}
ll ans[N];
int rans[N];
void upd_ans(int v,int p){
//    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v);
            rans[v]+=rans[z];
        }
    }
    if(v^p){
        rans[p]+=rans[v];
        ans[v]+=rans[v];
        rans[v]=0;
    }
    else{
        rans[v]=0;
        ans[v]+=rans[v]/2;
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    rans[v]=0;
    vec<vec<int>>c(sz(g[v]),vec<int>());
    int i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c[i]);
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        i++;
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]--;
        }
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        i++;
    }
    upd_ans(v,v);
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
gp_hash_table<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=mp[mask];
    for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^mask];
    }
    return ans;
}
ll ans[N];
int rans[N];
void upd_ans(int v,int p){
//    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v);
            rans[v]+=rans[z];
        }
    }
    if(v^p){
        rans[p]+=rans[v];
        ans[v]+=rans[v];
        rans[v]=0;
    }
    else{
        ans[v]+=rans[v]/2;
        rans[v]=0;
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    rans[v]=0;
    vec<vec<int>>c(sz(g[v]),vec<int>());
    int i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c[i]);
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        i++;
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]--;
        }
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        i++;
    }
    upd_ans(v,v);
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
unordered_map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=mp[mask];
    for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^mask];
    }
    return ans;
}
ll ans[N];
ll rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
            rans[v]+=rans[z];
        }
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
//    debug()<<imie(v);
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    rans[v]+=get(0);
    upd_ans(v,v,c);

    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=rans[z]/2,assert(rans[z]%2==0);
        rans[z]=0;
    }
    c.clear();
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
//    debug()<<imie(dp[v]);
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=(sz+1)/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=0;
    if(__builtin_popcount(mask)==1){
        int j=0;
        for(j=0;j<26;j++){
            if(pw(j)&mask)
                break;
        }
        for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^(1<<j)];
        }
    }
    else if(__builtin_popcount(mask)==0){
        ans=mp[0];
        for(int i=0;i<26;i++){
            ans+=mp[1<<i];
        }
    }
    return ans;
}
int ans[N];
int rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
                rans[v]+=rans[z];
        }
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    mp[1<<(s[v]-'a')]++;
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
         c.clear();
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    upd_ans(v,v,c);
    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=rans[z]/2;
        rans[z]=0;
    }
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=0;
//    debug()<<imie(mp);
    if(__builtin_popcount(mask)==1){
        int j=0;
        for(j=0;j<26;j++){
            if(pw(j)&mask)
                break;
        }
        for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^(1<<j)];
        }
        ans+=mp[(1<<j)];
    }
    else if(__builtin_popcount(mask)==0){
        ans=mp[0];
        for(int i=0;i<26;i++){
            ans+=mp[1<<i];
        }
    }
    return ans;
}
int ans[N];
int rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
                rans[v]+=rans[z];
        }
    }
//    debug()<<imie(rans[v]);
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
         c.clear();
    }
    rans[v]+=get(0);
    upd_ans(v,v,c);
    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=rans[z]/2,assert(rans[z]%2==0);
        rans[z]=0;
    }
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
//    debug()<<imie(dp[v]);
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=(sz+1)/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=0;
    if(__builtin_popcount(mask)==1){
        int j=0;
        for(j=0;j<26;j++){
            if(pw(j)&mask)
                break;
        }
        for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^(1<<j)];
        }
    }
    else if(__builtin_popcount(mask)==0){
        ans=mp[0];
        for(int i=0;i<26;i++){
            ans+=mp[1<<i];
        }
    }
    return ans;
}
int ans[N];
int rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
                rans[v]+=rans[z];
        }
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    mp[1<<(s[v]-'a')]++;
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
         c.clear();
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    upd_ans(v,v,c);
    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=rans[z]/2;
        rans[z]=0;
    }
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
gp_hash_table<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=mp[mask];
    for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^mask];
    }
    return ans;
}
ll ans[N];
ll rans[N];
void upd_ans(int v,int p){
//    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v);
            rans[v]+=rans[z];
        }
    }
    if(v^p){
        rans[p]+=rans[v];
        ans[v]+=rans[v];
        rans[v]=0;
    }
    else{
        ans[v]+=rans[v]/2;
        rans[v]=0;
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    rans[v]=0;
    vec<vec<int>>c(sz(g[v]),vec<int>());
    int i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c[i]);
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        i++;
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]--;
        }
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        i++;
    }
    upd_ans(v,v);
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
int mp[(int)1e6+601];
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=mp[mask];
    for(int i=0;i<20;i++){
            ans+=mp[(1<<i)^mask];
    }
    return ans;
}
ll ans[N];
ll rans[N];
void upd_ans(int v,int p){
//    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v);
            rans[v]+=rans[z];
        }
    }
    if(v^p){
        rans[p]+=rans[v];
        ans[v]+=rans[v];
        rans[v]=0;
    }
    else{
        ans[v]+=rans[v]/2;
        rans[v]=0;
    }
}
void go(int v){
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    rans[v]=0;
    vec<vec<int>>c(sz(g[v]),vec<int>());
    int i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c[i]);
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        i++;
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]--;
        }
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        i++;
    }
    upd_ans(v,v);
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=0;
//    debug()<<imie(mp);
    if(__builtin_popcount(mask)==1){
        int j=0;
        for(j=0;j<26;j++){
            if(pw(j)&mask)
                break;
        }
        for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^(1<<j)];
        }
        ans+=mp[(1<<j)];
    }
    else if(__builtin_popcount(mask)==0){
        ans=mp[0];
        for(int i=0;i<26;i++){
            ans+=mp[1<<i];
        }
    }
    return ans;
}
ll ans[N];
ll rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
            rans[v]+=rans[z];
        }
    }
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    rans[v]+=get(0);
    upd_ans(v,v,c);
    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=ceil((ld)rans[z]/2);
        rans[z]=0;
    }
    c.clear();
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=0;
//    debug()<<imie(mp);
    if(__builtin_popcount(mask)==1){
        int j=0;
        for(j=0;j<26;j++){
            if(pw(j)&mask)
                break;
        }
        for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^(1<<j)];
        }
        ans+=mp[(1<<j)];
    }
    else if(__builtin_popcount(mask)==0){
        ans=mp[0];
        for(int i=0;i<26;i++){
            ans+=mp[1<<i];
        }
    }
    return ans;
}
int ans[N];
int rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
                rans[v]+=rans[z];
        }
    }
//    debug()<<imie(rans[v]);
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
         c.clear();
    }
    rans[v]+=get(0);
    upd_ans(v,v,c);
    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=ceil((ld)rans[z]/2);
        rans[z]=0;
    }
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
//#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
int mp[1048577];
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=mp[mask];
    for(int i=0;i<20;i++){
            ans+=mp[(1<<i)^mask];
    }
    return ans;
}
ll ans[N];
ll rans[N];
void upd_ans(int v,int p){
//    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v);
            rans[v]+=rans[z];
        }
    }
    if(v^p){
        rans[p]+=rans[v];
        ans[v]+=rans[v];
        rans[v]=0;
    }
    else{
        ans[v]+=rans[v]/2;
        rans[v]=0;
    }
}
void go(int v){
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    rans[v]=0;
    vec<vec<int>>c(sz(g[v]),vec<int>());
    int i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c[i]);
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        i++;
    }
    mp[1<<(s[v]-'a')]--;
    rans[v]+=get(0);
    i=0;
    for(auto &z : g[v]){
        if(used[z]) continue;
        for(auto &q : c[i]){
            mp[masks[q]^(1<<(s[v]-'a'))]--;
        }
        for(auto &q : c[i]){
            rans[q]+=get(masks[q]);
        }
        i++;
    }
    upd_ans(v,v);
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/


#include<bits/stdc++.h>
using namespace std;
//#define int long long
//#include<ext/pb_ds/assoc_container.hpp>
//#include<ext/pb_ds/tree_policy.hpp>
//
//    #pragma GCC optimize("-O3")
//    #pragma GCC optimize("no-stack-protector")
//    #pragma GCC optimize("fast-math")
//    #pragma GCC optimize("Ofast")
//    #pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")
//    #pragma GCC target("avx,avx2,fma")
//    #pragma GCC optimization ("unroll-loops")
//#define LOCAL
#define sim template < class c
#define ris return * this
#define dor > debug & operator <<
#define eni(x) sim > typename \
  enable_if<sizeof dud<c>(0) x 1, debug&>::type operator<<(c i) {
sim > struct rge { c b, e; };
sim > rge<c> range(c i, c j) { return rge<c>{i, j}; }
sim > auto dud(c* x) -> decltype(cerr << *x, 0);
sim > char dud(...);
struct debug {
#ifndef LOCAL
~debug() { cerr << endl; }
eni(!=) cerr << boolalpha << i; ris; }
eni(==) ris << range(begin(i), end(i)); }
sim, class b dor(pair < b, c > d) {
  ris << "(" << d.first << ", " << d.second << ")";
}
sim dor(rge<c> d) {
  *this << "[";
  for (auto it = d.b; it != d.e; ++it)
	*this << ", " + 2 * (it == d.b) << *it;
  ris << "]";
}
#else
sim dor(const c&) { ris; }
#endif
};
#define imie(...) " [" << #__VA_ARGS__ ": " << (__VA_ARGS__) << "] "
#define fi first
#define f first
#define se second
#define vec vector
#define s second
#define vi_a vector<int>a;
#define p_b push_back
#define pb push_back
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ll long long
#define int long long
typedef unsigned long long ull;
////////////////////////////////???????????????CHECK THIS OUT???????????????//////////////////////////////
#define ld long double
#define pll pair<ll,ll>
#define pii pair<int,int>
#define m_p make_pair
#define fast_io cin.tie(0);cout.tie(0);ios_base::sync_with_stdio(0);
#define all(x) x.begin(),x.end()
#define getfiles    ifstream cin("input.txt");ofstream cout("output.txt");
#define pw(x) (1ll << x)
#define sz(x) (int)x.size()
#define endl "\n"
#define rall(x) x.rbegin(),x.rend()
#define len(a) (ll)a.size()
#define rep(x,l,r) for(ll x=l;x<r;x++)
//using namespace __gnu_pbds;
ld eps = (ld)1 / 1e6;
const ld pi=3.14159265359;
ll inf = 1e18,mod1=1e9+7;
ll sqr(ll a) { return a * a; }
ll qb(ll a) { return a * a * a; }
template<typename T> bool umax(T& a, T b) {return a<b?a=b,1:0;}
template<typename T> bool umin(T& a, T b) {return b<a?a=b,1:0;}
bool is_prime(ll val){for(ll i=2;i<=sqrt(val);i++)if(val%i==0)return 0; return 1;}
ll gcd(ll a, ll b) { return !a ? b : gcd(b % a, a); }
ll binpow(ll a, ll b, ll mod) { return b ? (b % 2 ? (a * (sqr(binpow(a, b / 2, mod)) % mod)) % mod : sqr(binpow(a, b / 2, mod)) % mod) : 1; }ll binmult(ll a, ll b, ll mod) { return b ? (b % 2 ? (2 * binmult(a, b / 2, mod) + a) % mod : (2 * binmult(a, b / 2, mod)) % mod) : 0; }
/////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
const ll RR=1e4;
const ll tx[8]={1,-1,2,-2,-1,-2};
const ll ty[8]={-2,-2,-1,-1,2,1};
const char rev_to[4]={'E','W','N','S'};
const int M=1e9+7;
const int N=3e5+3;
const int ppp=73;
const int K=2e5+2;
const int block=600;
const int OPEN=1;
const int CLOSE=0;
//typedef pair<long long,int> pli;
//typedef tree<pli,null_type,less<pli>,rb_tree_tag,tree_order_statistics_node_update> o_st;
auto rnd=bind(uniform_int_distribution<int>(1,5969699),mt19937(time(0)));
void bad(){
    cout<<"IMPOSSIBLE";
    exit(0);
}
int dp[N];
bool used[N];
vec<int> g[N];
void recalc(int v,int p){
    dp[v]=1;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        recalc(z,v);
        dp[v]+=dp[z];
    }
}
int get_centroid(int v,int p,int sz){
    for(auto &z : g[v]){
        if(!used[z] && z!=p && dp[z]>=sz/2){
            return get_centroid(z,v,sz);
        }
    }
    return v;
}
map<int,int>mp;
string s;
int masks[N];
void dfs(int v,int msk,int p,vec<int> &a){
    msk^=(1<<(s[v]-'a'));
    a.p_b(v);
    masks[v]=msk;
    for(auto &z : g[v]){
        if(used[z] || z==p) continue;
        dfs(z,msk,v,a);
    }
}
int get(int mask){
    int ans=0;
//    debug()<<imie(mp);
    if(__builtin_popcount(mask)==1){
        int j=0;
        for(j=0;j<26;j++){
            if(pw(j)&mask)
                break;
        }
        for(int i=0;i<26;i++){
            ans+=mp[(1<<i)^(1<<j)];
        }
        ans+=mp[(1<<j)];
    }
    else if(__builtin_popcount(mask)==0){
        ans=mp[0];
        for(int i=0;i<26;i++){
            ans+=mp[1<<i];
        }
    }
    return ans;
}
int ans[N];
int rans[N];
void upd_ans(int v,int p,vec<int> &a){
    a.p_b(v);
    for(auto &z : g[v]){
        if(!used[z] && z!=p){
            upd_ans(z,v,a);
                rans[v]+=rans[z];
        }
    }
//    debug()<<imie(rans[v]);
}
void go(int v){
    mp.clear();
    recalc(v,v);
    v=get_centroid(v,v,dp[v]);
    used[v]=1;
    masks[v]=1<<(s[v]-'a');
    mp[1<<(s[v]-'a')]++;
    vec<int>c;
    rans[v]=0;
//    debug()<<imie(v);
    for(auto &z : g[v]){
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
            debug()<<imie(get(masks[q]));
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
        c.clear();
    }
    mp.clear();
    for(int i=sz(g[v])-1;i>=0;i--){
        auto z=g[v][i];
        if(used[z]) continue;
        dfs(z,0,v,c);
        for(auto &q : c){
            rans[q]+=get(masks[q]);
//            debug()<<imie(get(masks[q]));
        }
        for(auto &q : c){
            mp[masks[q]^(1<<(s[v]-'a'))]++;
        }
         c.clear();
    }
    rans[v]+=get(0);
//    for(int i=0;i<2;i++)
//        debug()<<imie(i)imie(rans[i]);
    upd_ans(v,v,c);
    for(auto &z : c){
        if(z^v)
            ans[z]+=rans[z];
        else
            ans[z]+=rans[z]/2;
        rans[z]=0;
    }
    for(auto &z : g[v])
        if(!used[z])
            go(z);
}
signed main()
{
    fast_io;
    int n;
    cin>>n;
    for(int i=1;i < n;i++){
        int v,u;
        cin >> v >> u;
        -- v; -- u;
        g[v].pb(u);
        g[u].pb(v);
    }
    cin>>s;
    go(0);
    for(int i = 0; i < n; ++i)
        cout<<ans[i]+1<<' ';
    return 0;
}
/*
15
999834725 999842153 999849581 999857009 999864437 999871865 999879293 999886721 999894149 999901577 999909005 999916433 999901579 999909005 999916431
*/