#include <bits/stdc++.h>
using namespace std;
const int mod = (1e9) + 7;
const int siz = 2e5 + 5, siz2 = 105e4 + 5;
int n, curver, lim = 1 << 19, let[siz], treesz[siz], ver[siz2][2];
vector<int> adj[siz];
char arr[siz];
bool done[siz];
long long ans[siz], mask[siz2][2];
void calcsz(int node, int par) {
  treesz[node] = 1;
  int sz = adj[node].size();
  for (int i = 0; i < sz; i++) {
    int nex = adj[node][i];
    if (!done[nex] && nex != par) {
      calcsz(nex, node);
      treesz[node] += treesz[nex];
    }
  }
}
int getcentroid(int node, int par, int tot) {
  int mx = tot - treesz[node], mxnode = node;
  int sz = adj[node].size();
  for (int i = 0; i < sz; i++) {
    int nex = adj[node][i];
    if (!done[nex] && nex != par) {
      if (treesz[nex] > mx) {
        mx = treesz[nex];
        mxnode = nex;
      }
    }
  }
  if (mx <= tot / 2) return node;
  return getcentroid(mxnode, node, tot);
}
bool check(int mask) {
  bool one = false;
  while (mask != 0) {
    if (mask % 2) {
      if (one) return false;
      one = true;
    }
    mask >>= 1;
  }
  return true;
}
long long dfs(int node, int par, int parmask, bool mode, bool dir,
              int centroid) {
  int curmask = (1 << let[node]) ^ parmask;
  int wocent = curmask ^ (1 << let[centroid]);
  long long cursum = 0;
  if (!mode) {
    if (check(curmask) && !dir) {
      ans[centroid]++;
      ans[node]++;
      cursum++;
    }
    if (ver[wocent][dir] == curver) {
      if (!dir) {
        ans[centroid] += mask[wocent][dir];
      }
      ans[node] += mask[wocent][dir];
      cursum += mask[wocent][dir];
    }
    for (int i = 1; i <= lim; i <<= 1) {
      int val = wocent ^ i;
      if (ver[val][dir] == curver) {
        if (!dir) {
          ans[centroid] += mask[val][dir];
        }
        ans[node] += mask[val][dir];
        cursum += mask[val][dir];
      }
    }
  } else {
    if (ver[curmask][dir] == curver) {
      mask[curmask][dir]++;
    } else {
      ver[curmask][dir] = curver;
      mask[curmask][dir] = 1;
    }
  }
  int sz = adj[node].size();
  for (int i = 0; i < sz; i++) {
    int nex = adj[node][i];
    if (!done[nex] && nex != par) {
      long long val = dfs(nex, node, curmask, mode, dir, centroid);
      ans[node] += val;
      cursum += val;
    }
  }
  return cursum;
}
void solve(int cur) {
  calcsz(cur, 0);
  if (treesz[cur] == 1) {
    ans[cur]++;
    return;
  }
  int centroid = getcentroid(cur, 0, treesz[cur]);
  curver++;
  ans[centroid]++;
  int sz = adj[centroid].size();
  int centmask = 1 << let[centroid];
  for (int i = 0; i < sz; i++) {
    int node = adj[centroid][i];
    if (!done[node]) {
      dfs(node, centroid, centmask, 0, 0, centroid);
      dfs(node, centroid, centmask, 1, 0, centroid);
    }
  }
  for (int i = sz - 1; i >= 0; i--) {
    int node = adj[centroid][i];
    if (!done[node]) {
      dfs(node, centroid, centmask, 0, 1, centroid);
      dfs(node, centroid, centmask, 1, 1, centroid);
    }
  }
  done[centroid] = true;
  for (int i = 0; i < sz; i++) {
    int node = adj[centroid][i];
    if (!done[node]) {
      solve(node);
    }
  }
}
int main() {
  scanf("%d", &n);
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  scanf("%s", arr);
  int sz = strlen(arr);
  for (int i = 0; i < sz; i++) let[i + 1] = arr[i] - 97;
  solve(1);
  for (int i = 1; i <= n; i++) {
    printf("%I64d", ans[i]);
    if (i != n)
      printf(" ");
    else
      printf("\n");
  }
  return 0;
}
