#include <bits/stdc++.h>
using namespace std;
struct rd {
  int next, to;
} road[400010];
char a[200010];
int head[200010], n, size[200010], Max[200010], root, t[1 << 20], s[200010],
    d[200010], tot, sum, X;
long long ans[200010];
bool flag[200010];
vector<int> son, F, G;
inline void addedge(int x, int y) {
  road[++tot].next = head[x];
  road[tot].to = y;
  head[x] = tot;
}
inline void getroot(int x, int fa) {
  size[x] = Max[x] = 1;
  for (int now = head[x]; now; now = road[now].next)
    if (road[now].to != fa && flag[road[now].to] == 0) {
      getroot(road[now].to, x);
      size[x] += size[road[now].to];
      Max[x] = max(Max[x], size[road[now].to]);
    }
  Max[x] = max(Max[x], sum - size[x]);
  if (Max[x] < Max[root]) root = x;
}
inline void dfs1(int x, int fa, int S) {
  S ^= 1 << a[x] - 'a';
  s[x] = S;
  G.push_back(x);
  for (int now = head[x]; now; now = road[now].next)
    if (flag[road[now].to] == 0 && road[now].to != fa) dfs1(road[now].to, x, S);
}
inline long long dfs2(int x, int fa) {
  long long cnt = 0;
  for (int now = head[x]; now; now = road[now].next)
    if (road[now].to != fa && flag[road[now].to] == 0)
      cnt += dfs2(road[now].to, x);
  if (x == X)
    ans[x] += d[x] + (cnt - d[x]) / 2;
  else
    cnt += d[x], ans[x] += cnt;
  d[x] = s[x] = 0;
  return cnt;
}
inline void dfs(int x) {
  flag[x] = 1;
  son.clear();
  for (int now = head[x]; now; now = road[now].next)
    if (flag[road[now].to] == 0) son.push_back(road[now].to);
  F.clear();
  t[1 << a[x] - 'a'] = 1;
  F.push_back(1 << a[x] - 'a');
  for (int i = 0; i < son.size(); i++) {
    G.clear();
    dfs1(son[i], x, 0);
    for (int j = 0; j < G.size(); j++) {
      d[G[j]] += t[s[G[j]]];
      for (int w = 0; w < 20; w++) d[G[j]] += t[s[G[j]] ^ (1 << w)];
    }
    for (int j = 0; j < G.size(); j++)
      t[s[G[j]] ^ (1 << a[x] - 'a')]++,
          F.push_back(s[G[j]] ^ (1 << a[x] - 'a'));
  }
  for (int i = 0; i < F.size(); i++) t[F[i]] = 0;
  F.clear();
  for (int i = son.size() - 1; i >= 0; i--) {
    G.clear();
    dfs1(son[i], x, 0);
    for (int j = 0; j < G.size(); j++) {
      d[G[j]] += t[s[G[j]]];
      for (int w = 0; w < 20; w++) d[G[j]] += t[s[G[j]] ^ (1 << w)];
    }
    for (int j = 0; j < G.size(); j++)
      t[s[G[j]] ^ (1 << a[x] - 'a')]++,
          F.push_back(s[G[j]] ^ (1 << a[x] - 'a'));
  }
  d[x] += t[0];
  for (int w = 0; w < 20; w++) d[x] += t[1 << w];
  for (int i = 0; i < F.size(); i++) t[F[i]] = 0;
  X = x;
  dfs2(x, 0);
  for (int now = head[x]; now; now = road[now].next)
    if (flag[road[now].to] == 0) {
      sum = size[road[now].to];
      root = 0;
      getroot(road[now].to, 0);
      dfs(root);
    }
}
int main() {
  cin >> n;
  for (int i = 1, x, y; i < n; i++) {
    scanf("%d%d", &x, &y);
    addedge(x, y);
    addedge(y, x);
  }
  scanf("%s", a + 1);
  sum = n;
  Max[0] = 999999999;
  getroot(1, 0);
  dfs(root);
  for (int i = 1; i <= n; i++) printf("%I64d ", ans[i] + 1);
  return 0;
}
