#include <bits/stdc++.h>
long long ago;
using namespace std;
long long int pw(long long int a, long long int b, long long int mod) {
  if (!b) return 1;
  if (b & 1) return a * pw(a * a % mod, b / 2, mod) % mod;
  return pw(a * a % mod, b / 2, mod) % mod;
}
const long long int MAXN = 2e5 + 10;
const long long int INF = 8e18;
const long long int MOD = 1e9 + 7;
const long long int LOG = 20;
const long long int MASK = (1 << LOG);
int n, A[MAXN], dp[MAXN], par[MAXN][LOG], L[MAXN], R[MAXN], timer;
int mark[MAXN], sub[MAXN], B[MAXN];
long long int ps[MAXN], cntA[MASK], cntB[MASK];
vector<int> adj[MAXN], good, comp[MAXN], cadj[MAXN];
string s;
void DFS(int u, int p) {
  A[u] = (1 << int(s[u - 1] - 'a'));
  dp[u] = dp[p] ^ A[u];
  par[u][0] = p;
  for (int i = 1; i < LOG; i++) par[u][i] = par[par[u][i - 1]][i - 1];
  L[u] = timer++;
  for (int v : adj[u]) {
    if (v == p) continue;
    DFS(v, u);
  }
  R[u] = timer;
}
bool ispar(int u, int v) { return u == 0 || (L[u] <= L[v] && R[v] <= R[u]); }
int LCA(int u, int v) {
  if (u == v) return u;
  if (ispar(v, u)) swap(u, v);
  for (int i = LOG; i--;) {
    if (!ispar(par[u][i], v)) u = par[u][i];
    if (!ispar(par[v][i], u)) v = par[v][i];
  }
  return (ispar(u, v) ? u : par[u][0]);
}
int getPath(int u, int v) { return dp[u] ^ dp[v] ^ A[LCA(u, v)]; }
inline void addPath(int u, int v, long long int x) {
  ps[u] += x, ps[v] += x;
  int w = LCA(u, v);
  ps[w] -= x, ps[par[w][0]] -= x;
}
void subDFS(int u, int p) {
  sub[u] = 1;
  for (int v : adj[u]) {
    if (mark[v] || v == p) continue;
    subDFS(v, u);
    sub[u] += sub[v];
  }
}
int centroid(int u, int p, int cnt) {
  for (int v : adj[u]) {
    if (!mark[v] && v != p && sub[v] > cnt / 2) return centroid(v, u, cnt);
  }
  return u;
}
void build(int u, int p) {
  subDFS(u, 0);
  int v = centroid(u, 0, sub[u]);
  mark[v] = 1;
  for (int w : adj[v]) {
    if (!mark[w]) build(w, v);
  }
  cadj[v].push_back(v);
  for (int w : cadj[v]) {
    for (int x : comp[w]) {
      B[x] = getPath(v, x);
      cntA[B[x]]++;
    }
  }
  long long int vcnt = 0;
  for (int w : cadj[v]) {
    for (int x : comp[w]) cntB[B[x]]++;
    for (int x : comp[w]) {
      long long int res = 0;
      for (int i : good) {
        res += cntA[i ^ B[x] ^ A[v]] - cntB[i ^ B[x] ^ A[v]];
      }
      addPath(v, x, res);
      vcnt += res;
    }
    for (int x : comp[w]) cntB[B[x]]--;
  }
  for (int w : cadj[v]) {
    if (w == v) continue;
    for (int x : comp[w]) comp[v].push_back(x), cntA[B[x]]--;
    comp[w].clear();
  }
  cntA[A[v]]--;
  addPath(v, v, 1 - vcnt / 2);
  cadj[p].push_back(v);
}
void DFS2(int u, int p) {
  for (int v : adj[u]) {
    if (v == p) continue;
    DFS2(v, u);
    ps[u] += ps[v];
  }
}
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(nullptr);
  cout.tie(nullptr);
  good.push_back(0);
  for (int i = 0; i <= int('t' - 'a'); i++) good.push_back(1 << i);
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  for (int i = 1; i <= n; i++) {
    comp[i].push_back(i);
  }
  cin >> s;
  DFS(1, 0);
  build(1, 0);
  DFS2(1, 0);
  for (int i = 1; i <= n; i++) {
    cout << ps[i] << ' ';
  }
  cout << '\n';
  return 0;
}
