#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, M = 12e5 + 5;
vector<int> adj[N];
void add(int a, int b) {
  adj[a].push_back(b);
  adj[b].push_back(a);
}
bitset<N> B;
char C[N];
int SZ[N], IND[N], CNT[M], n, a, b, TV[21];
long long ans[N], ANS[N];
int get(int x) { return (TV[x]); }
int getsize(int u, int p) {
  int sm = 1;
  for (auto x : adj[u])
    if (x != p && !B[x]) sm += getsize(x, u);
  return (SZ[u] = sm);
}
int findc(int u, int p, int sz) {
  int rt = u;
  for (auto x : adj[u])
    if (x != p && !B[x] && SZ[x] * 2 >= sz) rt = findc(x, u, sz);
  return (rt);
}
void Do(int u, int p, int d, bool f) {
  d ^= get(IND[u]);
  CNT[d] += f ? 1 : -1;
  for (auto x : adj[u])
    if (x != p && !B[x]) Do(x, u, d, f);
}
void updans(int u, int p, int d) {
  d ^= get(IND[u]);
  ANS[u] = CNT[d];
  for (int i = 0; i < 20; i++) ANS[u] += CNT[d ^ get(i)];
  for (auto x : adj[u])
    if (x != p && !B[x]) updans(x, u, d), ANS[u] += ANS[x];
  ans[u] += ANS[u];
}
void darkol(int u) {
  int sz = getsize(u, 0);
  u = findc(u, 0, sz);
  B[u] = 1;
  for (auto x : adj[u])
    if (!B[x]) darkol(x);
  B[u] = 0;
  CNT[0] = 1;
  for (auto x : adj[u])
    if (!B[x]) {
      updans(x, u, get(IND[u]));
      ans[u] += ANS[x];
      Do(x, u, 0, 1);
    }
  for (auto x : adj[u])
    if (!B[x]) Do(x, u, 0, 0);
  CNT[0]--;
  reverse(adj[u].begin(), adj[u].end());
  for (auto x : adj[u])
    if (!B[x]) {
      updans(x, u, get(IND[u]));
      Do(x, u, 0, 1);
    }
  for (auto x : adj[u])
    if (!B[x]) Do(x, u, 0, 0);
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; i++) scanf("%d %d", &a, &b), add(a, b);
  scanf("%s", C);
  for (int i = 1; i <= n; i++) IND[i] = C[i - 1] - 'a';
  TV[0] = 1LL;
  for (int i = 1; i < 20; i++) TV[i] = TV[i - 1] << 1;
  darkol(1);
  for (int i = 1; i <= n; i++) printf("%I64d ", ans[i] + 1);
}
