#include <bits/stdc++.h>
#define F first
#define S second
#define pb(x) push_back(x)
#define mp(a, b) make_pair(a, b)
using namespace std;
typedef long long ll;
typedef pair<int, int> pii;
typedef vector<ll> vll;
typedef vector<int> vi;
typedef pair<ll, ll> pll;
const int MOD = 1e9 + 7;
const int LOGN = 20;
const ll INF = 1e18;
ll __gcd(ll a, ll b) {
	if(b == 0)
		return a;
	return __gcd(b, a%b);
}
ll __lcm(ll a, ll b) {
	return ((a * b) / __gcd(a, b));
}
const int MAX = (1 << 21) + 100;
vector< set<int> > adj;
vi masks(MAX, 0);
vi subtree;
vll ans;
string s;
int n;
int nn = 0;
void dfs1(int u, int p) {
	subtree[u] = 1;
	nn++;
	for(auto v: adj[u]) {
		if(v == p)
			continue;
		dfs1(v, u);
		subtree[u] += subtree[v];
	}
}
int dfs2(int u, int p) {
	for(auto v: adj[u])
		if(v != p and subtree[v] > nn / 2)
			return dfs2(v, u);
	return u;
}
void dfs3(int u, int p, int mask, int add) {
	masks[mask] += add;
	for(auto v: adj[u]) {
		if(v == p)
			continue;
		dfs3(v, u, mask ^ (1 << (s[v] - 'a')), add);
	}
}
ll cnt = 0;
void dfs4(int u, int p, int mask, int centroid) {
	ans[u] += masks[mask];
	if(mask == (1 << (s[centroid] - 'a')))
		cnt++;
	for(int i = 0; i <= 20; i++) {
		ans[u] += masks[mask ^ (1 << i)];
		if((mask ^ (1 << i)) == (1 << (s[centroid] - 'a')))
			cnt++;
	}
	for(auto v: adj[u]) {
		if(v == p)
			continue;
		dfs4(v, u, (mask ^ (1 << (s[v] - 'a'))), centroid);
		ans[u] += ans[v];
	}
}
void decompose(int root, int depth) {
	int x;
	nn = 0;
	dfs1(root, root);
	int centroid = dfs2(root, root);
	dfs3(centroid, centroid, (1 << (s[centroid] - 'a')), 1);
	cnt = 0;
	for(auto v: adj[centroid]) {
		int mask = (1 << (s[v] - 'a')) ^ (1 << (s[centroid] - 'a'));
		dfs3(v, centroid, mask, -1);
		dfs4(v, centroid, (1 << (s[v] - 'a')), centroid);
		dfs3(v, centroid, mask, 1);
		cnt += ans[v];
	}
	cnt /= 2;
	ans[centroid] += cnt;
	for(auto v: adj[centroid]) {
		int mask = (1 << (s[v] - 'a')) ^ (1 << (s[centroid] - 'a'));
		dfs3(v, centroid, mask, -1);
	}
	masks[1 << (s[centroid] - 'a')] = 0;
	for(auto v: adj[centroid]) {
		adj[v].erase(centroid);
		decompose(v, depth + 1);
	}
}
int main() {
	std :: ios_base :: sync_with_stdio(false);
	cin.tie(NULL), cout.tie(NULL);
	cin >> n;
	adj.assign(n, set<int>());
	subtree.assign(n, 0);
	ans.assign(n, 0);
	int x, y;
	for(int i = 0; i < n - 1; ++i) {
		cin >> x >> y;
		x--, y--;
		adj[x].insert(y);
		adj[y].insert(x);
	}
	cin >> s;
	decompose(0, 0);
	for(int i = 0; i < n; ++i)
		cout << ans[i] + 1 << " ";
	cout << endl;
}


#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

#define ll long long
#define db long double
#define ii pair<int,int>
#define vi vector<int>
#define fi first
#define se second
#define sz(a) (int)(a).size()
#define all(a) (a).begin(),(a).end()
#define pb emplace_back
#define mp make_pair
#define FN(i, n) for (int i = 0; i < (int)(n); ++i)
#define FEN(i,n) for (int i = 1;i <= (int)(n); ++i)
#define rep(i,a,b) for(int i=a;i<b;i++)
#define repv(i,a,b) for(int i=b-1;i>=a;i--)
#define SET(A, val) memset(A, val, sizeof(A))
typedef tree<int ,null_type,less<int>,rb_tree_tag,tree_order_statistics_node_update>ordered_set ;
// order_of_key (val): returns the no. of values less than val
// find_by_order (k): returns the kth largest element.(0-based)
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...)
#endif
const int L=200005,N=(1<<20);
//call dfsMCT,change solve and dfs1
vi vpart[L],ad[L]; bool vis[L];//par:parent in cent|H:depth
int SZ[L],par[L],part[L],H[L],cpart;//cpart:no of parts in cent
ll ans[L],dp[L];
string s;
int dfsSZ(int u,int p=-1)
{
  SZ[u]=1;//vpart[i]:nodes in part i
  for(int v:ad[u])
    if(!vis[v] && v!=p)
      SZ[u]+=dfsSZ(v,u);
  return SZ[u];
}
int dfsFC(int u,int r,int p=-1)
{
  for(int v:ad[u])
    if(!vis[v] && v!=p)
      {
  if(SZ[v]>SZ[r]/2)
    return dfsFC(v,r,u);
      }
  return u;
}
int cnt[N],val[L],tmp[N];
void dfs1(int u,int r,int p=-1)
{
  dp[u]=0;
  if(p==r)
    {
      part[u]=++cpart;
      vpart[cpart].clear();
    }
  else if(p!=-1) part[u]=part[p];
  if(p!=-1) vpart[cpart].pb(u);
  for(int v1:ad[u])
    if(!vis[v1]&&v1!=p)
      {
  H[v1]=H[u]+1;
  val[v1]=(val[u]^(1<<(s[v1-1]-'a')));
  dfs1(v1,r,u);
      }
}
void dfs2(int u,int r,int par=-1)
{
  dp[u]=cnt[val[u]];
  rep(i,0,20)
    dp[u]+=cnt[val[u]^(1<<i)];
  for(int v1:ad[u])
    {
      if(vis[v1] || v1==par) continue;
      dfs2(v1,r,u);
      dp[u]+=dp[v1];
    }
  ans[u]+=dp[u];
}
void solve(int r,int szr)
{
  H[r]=cpart=0;
  val[r]=(1<<(s[r-1]-'a'));
  dfs1(r,r);
  rep(i,1,cpart+1)
    for(int v1:vpart[i])
      cnt[val[v1]]++;
  cnt[val[r]]++;
  rep(i,1,cpart+1)
    {
      for(int v1:vpart[i])
  {
    cnt[val[v1]]--;
    val[v1]^=(1<<(s[r-1]-'a'));
    tmp[val[v1]]++;
  }
      for(int v1:vpart[i])
  {
    if(tmp[val[v1]])
      {
        dp[r]+=(ll)tmp[val[v1]]*cnt[val[v1]];
        rep(j,0,20)
    dp[r]+=(ll)tmp[val[v1]]*cnt[val[v1]^(1<<j)];
        tmp[val[v1]]=0;
      }
  }
      dfs2(vpart[i][0],r,r);
      for(int v1:vpart[i])
  {
    val[v1]^=(1<<(s[r-1]-'a'));
    cnt[val[v1]]++;
  }
    }
  cnt[val[r]]--;
  dp[r]+=cnt[0];
  rep(i,0,20)
    dp[r]+=cnt[(1<<i)];
  ans[r]+=dp[r]/2;
  rep(i,1,cpart+1)
    for(int v1:vpart[i]) cnt[val[v1]]--;
}
void dfsMCT(int u,int p=-1)
{
  dfsSZ(u);
  int r=dfsFC(u,u);
  par[r]=p; solve(r,SZ[u]); vis[r]=true;
  for(int v:ad[r])
    if(!vis[v]) dfsMCT(v,r);
}
int main()
{
  std::ios::sync_with_stdio(false);
  cin.tie(NULL) ; cout.tie(NULL) ;
  int n,x,y;
  cin>>n;
  rep(i,1,n)
    {
      cin>>x>>y;
      ad[x].pb(y); ad[y].pb(x);
    }
  cin>>s;
  dfsMCT(1);
  rep(i,1,n+1) cout<<ans[i]+1<<" ";
  cout<<'\n';
  return 0 ;
}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root, vector<int> & dead){
    int sz[N];
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    vector<int> dead(n+5,0);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N], dead[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root){
    vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,int)> add_cnt = [&](int u, int prev, int mask, int add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],1);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),0);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),1);
        }
        ans[c]>>=1;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N];
int k; //ok.size()
vector<int> ok;

int OneCentroid(int root, vector<bool> & dead){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

vector<int> CenDec(int n){
    vector<int> ans(n+5);
    vector<bool> dead(n+5,false);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=true;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,int> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=false;
    };
    rec(1);
    return ans;
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    int n; cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok.push_back(0);
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok.push_back(i);
        i=i<<1;
    }
    k=ok.size();
    //init end
    auto ans=CenDec(n);
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N];
int k; //ok.size()
vector<int> ok;

int OneCentroid(int root, vector<bool> & dead){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

vector<int> CenDec(int n){
    vector<int> ans(n+5);
    vector<bool> dead(n+5,false);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=true;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,int> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=false;
    };
    rec(1);
    return ans;
}

signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    int n; cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok.push_back(0);
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok.push_back(i);
        i=i<<1;
    }
    k=ok.size();
    //init end
    auto ans=CenDec(n);
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N], dead[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,int)> add_cnt = [&](int u, int prev, int mask, int add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],1);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),0);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),1);
        }
        ans[c]>>=1;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N];
int k=0; //ok.size()
int ok[N];
ll ans[N];

int OneCentroid(int root, vector<bool> & dead){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(int n){
    vector<int> dead(n+5,0);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
    return ans;
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    int n; cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok.push_back(0);
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec(n);
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
#define pii pair<ll,int>
#define ff first
#define ss second
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N], dead[N];
int n,k=0; //ok.size()
ll ans[N];
pii child[N];
pii cnt[1111111];
int c_cnt=0, c_child=0;

int OneCentroid(int root){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        //unordered_map <int,ll> cnt, child;
        ++c_cnt; ++c_child;
        function<void (int,int,int,int)> add_cnt = [&](int u, int prev, int mask, int add){
            if(cnt[mask].ss<c_cnt) cnt[mask].ff=0;
            cnt[mask].ff += (add ? 1 : -1);
            cnt[mask].ss=c_cnt;
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            if(child[u].ss<c_child) child[u].ff=0;
            child[u].ss=c_child;

            for(int i=0; i<k; ++i){
                int tmp=ok[i]^mask;
                if(cnt[tmp].ss<c_cnt) cnt[tmp].ff=0;
                cnt[tmp].ss=c_cnt;

                child[u].ff+=cnt[tmp].ff;
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u].ff+=child[v].ff;
            }
            ans[u]+=child[u].ff;
        };
        add_cnt(c,-1,1<<letter[c],1);
        for(int i=0; i<k;++i){
            if(cnt[ok[i]].ss<c_cnt) cnt[ok[i]].ff=0;
            cnt[ok[i]].ss=c_cnt;
            ans[c]+=cnt[ok[i]].ff;
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){

            if(child[u].ss<c_child) child[u].ff=0;
            child[u].ss=c_child;

            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),0);
            calc(u,c,1<<letter[u]);

            ans[c]+=child[u].ff;
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),1);
        }
        ans[c]>>=1;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root, vector<int> & dead){
    vector<int> sz;
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    vector<int> dead(n+5,0);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,int)> add_cnt = [&](int u, int prev, int mask, int add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],1);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),0);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),1);
        }
        ans[c]<<=1;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N];
int k; //ok.size()
vector<int> ok;

int OneCentroid(int root, vector<bool> & dead){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

vector<ll> CenDec(int n){
    vector<ll> ans(n+5);
    vector<bool> dead(n+5,false);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=true;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,int> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=false;
    };
    rec(1);
    return ans;
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    int n; cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok.push_back(0);
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok.push_back(i);
        i=i<<1;
    }
    k=ok.size();
    //init end
    auto ans=CenDec(n);
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define int long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N];
int k; //ok.size()
vector<int> ok;

int OneCentroid(int root, vector<bool> & dead){
    int sz[N];
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

vector<int> CenDec(int n){
    vector<int> ans(n+5);
    vector<bool> dead(n+5,false);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=true;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,int> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=false;
    };
    rec(1);
    return ans;
}

signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    int n; cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok.push_back(0);
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok.push_back(i);
        i=i<<1;
    }
    k=ok.size();
    //init end
    auto ans=CenDec(n);
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define pii pair<int,int>
#define ff first
#define ss second
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root, vector<int> & dead){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    vector<int> dead(n+5,0);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        map <int,ll> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root, vector<int> & dead){
    unordered_map<int,int> sz;
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    vector<int> dead(n+5,0);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int N=200005;
vector<int> g[N];
int mask[N], letter[N], ok[N];
int n,k=0; //ok.size()
ll ans[N];

int OneCentroid(int root, vector<int> & dead){
    static vector<int> sz(N);
    function<void (int,int)> get_sz = [&](int u, int prev){
        sz[u]=1;
        for(auto v : g[u]) if(v!=prev && !dead[v]){
            get_sz(v,u);
            sz[u]+=sz[v];
        }
    };
    get_sz(root, -1);
    int n=sz[root];
    function<int (int,int)> dfs = [&](int u, int prev){
        for(auto v : g[u]) if (v!=prev && !dead[v]){
            if(sz[v] > n/2){
                return dfs(v,u);
            }
        }
        return u;
    };
    return dfs(root,-1);
}

void CenDec(){
    vector<int> dead(n+5,0);
    function<void (int)> rec = [&](int start){
        int c=OneCentroid(start,dead);
        dead[c]=1;
        for(auto u:g[c]) if(!dead[u]){
            rec(u);
        }

        unordered_map <int,ll> cnt, child;
        function<void (int,int,int,bool)> add_cnt = [&](int u, int prev, int mask, bool add){
            cnt[mask] += (add ? 1 : -1);
            for(auto v:g[u]) if((v!=prev && !dead[v])){
                add_cnt(v,u,mask^(1<<letter[v]),add);
            }
        };

        function<void (int,int,int)> calc = [&](int u, int prev, int mask){
            for(int i=0; i<k; ++i){
                child[u]+=cnt[ok[i]^mask];
            }

            for(auto v:g[u]) if(v!=prev && !dead[v]){
                calc(v, u, mask^(1<<letter[v]));
                child[u]+=child[v];
            }
            ans[u]+=child[u];
        };
        add_cnt(c,-1,1<<letter[c],true);
        for(int i=0; i<k;++i){
            ans[c]+=cnt[ok[i]];
        }
        --ans[c];
        int tmp=0;
        for(auto u:g[c]) if(!dead[u]){
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),false);
            calc(u,c,1<<letter[u]);
           ans[c]+=child[u];
            add_cnt(u,c,(1<<letter[c])^(1<<letter[u]),true);
        }
        ans[c]/=2;
        ++ans[c];
        dead[c]=0;
    };
    rec(1);
}

int main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0); cout.tie(0);
    cin>>n;
    for(int i=1; i<n; ++i){
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    string s; cin>>s;
    for(int i=0; i<s.size(); ++i){
        letter[i+1]=s[i]-'a';
    }

    ok[k++]=0;
    int i=1;
    int limit=1<<20;
    //init here
    while(i<limit){
        ok[k++]=i;
        i=i<<1;
    }
    //init end
    CenDec();
    for(int i=1; i<=n; ++i)
        cout<<ans[i]<<' ';

}


// Problem : E. Palindromes in a Tree
// Contest : Codeforces - Codecraft-18 and Codeforces Round #458 (Div. 1 + Div.
// 2, combined)
// URL : https://codeforces.com/problemset/problem/914/E
// Memory Limit : 256 MB
// Time Limit : 4000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

// Macros

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define ll long long
#define db long double
#define pb push_back
#define eb emplace_back
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define mi map<int, int>
#define mii map<pii, int>
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define sz(x) (int) x.size()
#define mod 1000000007
#define EPS 1e-9
#define inf 1e10
#define PI acos(-1.0)
#define int long long
#define N 200005

// Solution

int n;
string s;
int ans[N];
unordered_map<int, int> cnt;
vi g[N];
int d[N], vis[N];

void dfs(int u, int par = -1) {
  d[u] = 1;
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    dfs(i, u);
    d[u] += d[i];
  }
}

int get_centroid(int u, int size, int par = -1) {
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    if (2 * d[i] > size) return get_centroid(i, size, u);
  }
  return u;
}

void dfs1(int u, int par, int hash, int add) {
  hash ^= (1 << (s[u - 1] - 'a'));
  cnt[hash] += add;
  if (cnt[hash] <= 0) cnt.erase(hash);
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      dfs1(v, u, hash, add);
    }
  }
}

int cent_cnt = 0;

int dfs2(int u, int par, int hash) {
  hash ^= (1 << (s[u - 1] - 'a'));
  int ret = 0;
  for (int i = 0; i < 21; i++) {
    int need = (hash ^ (1 << i));
    if (cnt.count(need)) ret += cnt[need];
    if (need == 0) ret++, cent_cnt++;
  }
  if (cnt.count(hash)) ret += cnt[hash];
  if (hash == 0) ret++, cent_cnt++;
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      ret += dfs2(v, u, hash);
    }
  }
  ans[u] += ret;
  return ret;
}

void get_ans(int centroid) {
  cnt.clear();
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt = 0;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, -1);
      cent_cnt += dfs2(v, centroid, (1 << (s[centroid - 1] - 'a')));
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt /= 2;
  ans[centroid] += cent_cnt;
}

void go(int u) {
  dfs(u);
  int centroid = get_centroid(u, d[u]);
  get_ans(centroid);
  vis[centroid] = 1;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      go(v);
    }
  }
}

void solve() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  cin >> s;
  go(1);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] + 1 << ' ';
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

  int tests;
  tests = 1;
  // cin>>tests;

  for (int test = 1; test <= tests; test++) {
    // cout<<"Case #"<<test<<": ";
    solve();
  }

  return 0;
}


// Problem : E. Palindromes in a Tree
// Contest : Codeforces - Codecraft-18 and Codeforces Round #458 (Div. 1 + Div.
// 2, combined)
// URL : https://codeforces.com/problemset/problem/914/E
// Memory Limit : 256 MB
// Time Limit : 4000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

// Macros

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define ll long long
#define db long double
#define pb push_back
#define eb emplace_back
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define mi map<int, int>
#define mii map<pii, int>
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define sz(x) (int) x.size()
#define mod 1000000007
#define EPS 1e-9
#define inf 1e10
#define PI acos(-1.0)
#define int long long
#define N 100005

// Solution

int n;
string s;
int ans[N];
mi cnt;
vi g[N];
int d[N], vis[N];

void dfs(int u, int par = -1) {
  d[u] = 1;
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    dfs(i, u);
    d[u] += d[i];
  }
}

int get_centroid(int u, int size, int par = -1) {
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    if (2 * d[i] > size) return get_centroid(i, size, u);
  }
  return u;
}

void dfs1(int u, int par, int hash, int add) {
  hash ^= (1 << (s[u - 1] - 'a'));
  cnt[hash] += add;
  if (cnt[hash] <= 0) cnt.erase(hash);
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      dfs1(v, u, hash, add);
    }
  }
}

int cent_cnt = 0;

int dfs2(int u, int par, int hash) {
  hash ^= (1 << (s[u - 1] - 'a'));
  int ret = 0;
  for (int i = 0; i < 21; i++) {
    int need = (hash ^ (1 << i));
    if (cnt.count(need)) ret += cnt[need];
    if (need == 0) ret++, cent_cnt++;
  }
  if (cnt.count(hash)) ret += cnt[hash];
  if (hash == 0) ret++, cent_cnt++;
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      ret += dfs2(v, u, hash);
    }
  }
  ans[u] += ret;
  return ret;
}

void get_ans(int centroid) {
  cnt.clear();
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt = 0;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, -1);
      cent_cnt += dfs2(v, centroid, (1 << (s[centroid - 1] - 'a')));
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt /= 2;
  ans[centroid] += cent_cnt;
}

void go(int u) {
  dfs(u);
  int centroid = get_centroid(u, d[u]);
  get_ans(centroid);
  vis[centroid] = 1;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      go(v);
    }
  }
}

void solve() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  cin >> s;
  go(1);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] + 1 << ' ';
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

  int tests;
  tests = 1;
  // cin>>tests;

  for (int test = 1; test <= tests; test++) {
    // cout<<"Case #"<<test<<": ";
    solve();
  }

  return 0;
}


// Problem : E. Palindromes in a Tree
// Contest : Codeforces - Codecraft-18 and Codeforces Round #458 (Div. 1 + Div.
// 2, combined)
// URL : https://codeforces.com/problemset/problem/914/E
// Memory Limit : 256 MB
// Time Limit : 4000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

// Macros

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define ll long long
#define db long double
#define pb push_back
#define eb emplace_back
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define mi map<int, int>
#define mii map<pii, int>
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define sz(x) (int) x.size()
#define mod 1000000007
#define EPS 1e-9
#define inf 1e10
#define PI acos(-1.0)
#define int long long
#define N 200005

// Solution

int n;
string s;
int ans[N];
vi g[N];
int d[N], vis[N];
int when[1 << 21], cnt[1 << 21];
int timer;

void dfs(int u, int par = -1) {
  d[u] = 1;
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    dfs(i, u);
    d[u] += d[i];
  }
}

int get_centroid(int u, int size, int par = -1) {
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    if (2 * d[i] > size) return get_centroid(i, size, u);
  }
  return u;
}

void dfs1(int u, int par, int hash, int add) {
  hash ^= (1 << (s[u - 1] - 'a'));
  if (when[hash] != timer) {
    when[hash] = timer;
    cnt[hash] = 0;
  }
  cnt[hash] += add;
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      dfs1(v, u, hash, add);
    }
  }
}

int cent_cnt = 0;

int dfs2(int u, int par, int hash) {
  hash ^= (1 << (s[u - 1] - 'a'));
  int ret = 0;
  for (int i = 0; i < 21; i++) {
    int need = (hash ^ (1 << i));
    if (when[need] == timer) ret += cnt[need];
    if (need == 0) ret++, cent_cnt++;
  }
  if (when[hash] == timer) ret += cnt[hash];
  if (hash == 0) ret++, cent_cnt++;
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      ret += dfs2(v, u, hash);
    }
  }
  ans[u] += ret;
  return ret;
}

void get_ans(int centroid) {
  timer++;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt = 0;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, -1);
      cent_cnt += dfs2(v, centroid, (1 << (s[centroid - 1] - 'a')));
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt /= 2;
  ans[centroid] += cent_cnt;
}

void go(int u) {
  dfs(u);
  int centroid = get_centroid(u, d[u]);
  get_ans(centroid);
  vis[centroid] = 1;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      go(v);
    }
  }
}

void solve() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  cin >> s;
  go(1);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] + 1 << ' ';
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

  int tests;
  tests = 1;
  // cin>>tests;

  for (int test = 1; test <= tests; test++) {
    // cout<<"Case #"<<test<<": ";
    solve();
  }

  return 0;
}


// Problem : E. Palindromes in a Tree
// Contest : Codeforces - Codecraft-18 and Codeforces Round #458 (Div. 1 + Div.
// 2, combined)
// URL : https://codeforces.com/problemset/problem/914/E
// Memory Limit : 256 MB
// Time Limit : 4000 ms
// Powered by CP Editor (https://github.com/cpeditor/cpeditor)

#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;

// Macros

template <typename T>
using ordered_set =
    tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
#define ll long long
#define db long double
#define pb push_back
#define eb emplace_back
#define pii pair<int, int>
#define vi vector<int>
#define vii vector<pii>
#define mi map<int, int>
#define mii map<pii, int>
#define fi first
#define se second
#define all(a) (a).begin(), (a).end()
#define sz(x) (int) x.size()
#define mod 1000000007
#define EPS 1e-9
#define inf 1e10
#define PI acos(-1.0)
#define int long long
#define N 200005

// Solution

int n;
string s;
int ans[N];
mi cnt;
vi g[N];
int d[N], vis[N];

void dfs(int u, int par = -1) {
  d[u] = 1;
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    dfs(i, u);
    d[u] += d[i];
  }
}

int get_centroid(int u, int size, int par = -1) {
  for (int i : g[u]) {
    if (vis[i] || i == par) continue;
    if (2 * d[i] > size) return get_centroid(i, size, u);
  }
  return u;
}

void dfs1(int u, int par, int hash, int add) {
  hash ^= (1 << (s[u - 1] - 'a'));
  cnt[hash] += add;
  if (cnt[hash] <= 0) cnt.erase(hash);
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      dfs1(v, u, hash, add);
    }
  }
}

int cent_cnt = 0;

int dfs2(int u, int par, int hash) {
  hash ^= (1 << (s[u - 1] - 'a'));
  int ret = 0;
  for (int i = 0; i < 21; i++) {
    int need = (hash ^ (1 << i));
    if (cnt.count(need)) ret += cnt[need];
    if (need == 0) ret++, cent_cnt++;
  }
  if (cnt.count(hash)) ret += cnt[hash];
  if (hash == 0) ret++, cent_cnt++;
  for (int v : g[u]) {
    if (v != par && !vis[v]) {
      ret += dfs2(v, u, hash);
    }
  }
  ans[u] += ret;
  return ret;
}

void get_ans(int centroid) {
  cnt.clear();
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt = 0;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      dfs1(v, centroid, 0, -1);
      cent_cnt += dfs2(v, centroid, (1 << (s[centroid - 1] - 'a')));
      dfs1(v, centroid, 0, 1);
    }
  }
  cent_cnt /= 2;
  ans[centroid] += cent_cnt;
}

void go(int u) {
  dfs(u);
  int centroid = get_centroid(u, d[u]);
  get_ans(centroid);
  vis[centroid] = 1;
  for (int v : g[centroid]) {
    if (!vis[v]) {
      go(v);
    }
  }
}

void solve() {
  cin >> n;
  for (int i = 0; i < n - 1; i++) {
    int u, v;
    cin >> u >> v;
    g[u].pb(v);
    g[v].pb(u);
  }
  cin >> s;
  go(1);
  for (int i = 1; i <= n; i++) {
    cout << ans[i] + 1 << ' ';
  }
}

signed main() {
  ios_base::sync_with_stdio(false);
  cin.tie(0);
  cout.tie(0);
  // freopen("input.txt", "r", stdin); freopen("output.txt", "w", stdout);

  int tests;
  tests = 1;
  // cin>>tests;

  for (int test = 1; test <= tests; test++) {
    // cout<<"Case #"<<test<<": ";
    solve();
  }

  return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define y1 A2Dalek
#define y0 Cyberman
#define yn RoseTyler
#define j1 JackHarkness
#define fs first
#define sd second
const int N=2e5;
const int oo=1e9+5;
int du[]={-1,0,0,1};
int dv[]={0,-1,1,0};
const long long mod=1e9+7;
typedef pair<int,int> ii;
typedef pair<int,ii> iii;
long long sqr(long long x) {return x*x;}
int getbit(int state, int i) {return ((state>>i)&1);}

int n,now[1100000],s[N+5],state[N+5],col[N+5];
long long res[N+5],tmp[N+5];
vector<int> okstate,need,g[N+5];
vector<ii> q;
bool block[N+5];
void dfs(int u, int p)
{
    state[u]=state[p]^(1<<col[u]);
    q.push_back(ii(state[u],u));
    for (int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if (v==p || block[v]) continue;
        dfs(v,u);
    }
}
void dfs2(int u, int p)
{
    for (int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if (v==p || block[v]) continue;
        dfs2(v,u);
    }
    if (p)
    {
        tmp[p]+=tmp[u];
        res[u]+=tmp[u];
        tmp[u]=0;
    }
}
void Reset()
{
    for (int i=0;i<need.size();i++) now[need[i]]=0;
    need.clear();
}
void sol(int root)
{
    now[(1<<col[root])]++;
    need.push_back((1<<col[root]));
    state[root]=0;
    for (int i=0;i<g[root].size();i++)
    {
        int v=g[root][i];
        if (block[v]) continue;
        q.clear();
        dfs(v,root);
        for (int j=0;j<q.size();j++)
        {
            now[q[j].fs^(1<<col[root])]++;
            need.push_back((q[j].fs^(1<<col[root])));
        }
    }
    for (int i=0;i<g[root].size();i++)
    {
        int v=g[root][i];
        if (block[v]) continue;
        q.clear();
        dfs(v,root);
        for (int j=0;j<q.size();j++) now[q[j].fs^(1<<col[root])]--;
        for (int j=0;j<q.size();j++) for (int k=0;k<21;k++) tmp[q[j].sd]+=1ll*now[okstate[k]^q[j].fs];
        for (int j=0;j<q.size();j++) now[q[j].fs^(1<<col[root])]++;
    }
    q.clear();
    q.push_back(ii(0,root));
    now[(1<<col[root])]--;
    for (int j=0;j<q.size();j++) for (int k=0;k<21;k++) tmp[q[j].sd]+=1ll*now[okstate[k]^q[j].fs];
    dfs2(root,0);
    res[root]+=tmp[root]/2+1;
    tmp[root]=0;
    Reset();
}
void getsize(int u, int p)
{
    s[u]=1;
    for (int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if (v==p || block[v]) continue;
        getsize(v,u);
        s[u]+=s[v];
    }
}
int getroot(int u, int p, int Size)
{
    int id=-1;
    for (int i=0;i<g[u].size();i++)
    {
        int v=g[u][i];
        if (v==p || block[v]) continue;
        if (id==-1 || s[id]<s[v]) id=v;
    }
    if (id==-1 || s[id]*2<=Size) return u;
    return getroot(id,u,Size);
}
void process(int u, int p)
{
    getsize(u,p);
    int root=getroot(u,p,s[u]);
    sol(root);
    block[root]=true;
    for (int i=0;i<g[root].size();i++)
    {
        int v=g[root][i];
        if (block[v]) continue;
        process(v,root);
    }
}
int main()
{
	//freopen("Palindromes in a Tree.inp","r",stdin);
	//freopen("Palindromes in a Tree.out","w",stdout);
	ios_base::sync_with_stdio(false);
    cin>>n;
    for (int i=1;i<n;i++)
    {
        int u,v;
        cin>>u>>v;
        g[u].push_back(v);
        g[v].push_back(u);
    }
    for (int i=1;i<=n;i++)
    {
        char c;
        cin>>c;
        col[i]=c-'a';
    }
    okstate.push_back(0);
    for (int i=0;i<20;i++) okstate.push_back((1<<i));
    process(1,0);
    for (int i=1;i<=n;i++) cout<<res[i]<<" ";
	return 0;
}


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

#define pb push_back
#define ll long long
#define maxn 100005
#define fr(i,j,k) for(int i=j;i<k;i++)
#define f(n) fr(i,0,n)
#define f1(n) fr(i,1,n+1)
#define ms(i) memset(i,0,sizeof(i));
#define ms1(i) memset(i,-1,sizeof(i));
#define F first
#define S second
#define all(x) x.begin(), x.end()
const int mod = 1e9+7;
vector<int>g[200005];
int a[200005];
ll ans[200005];
int sz[200005];
int u[200005];
int mask[200005];
int num[1<<20];
ll tot, alone;
void clear_used(int now) {
    u[now] = 0;
    for (auto i:g[now]) {
        if (u[i] == 1) {
            clear_used(i);
        }
    }
}
void build(int now) {
    sz[now] = u[now] = 1;
    for (auto i:g[now]) {
        if (u[i])continue;
        build(i);
        sz[now] += sz[i];
    }
}
int find_root(int now, int tar) {
    while (1) {
        int nx = 0;
        for (auto i:g[now]) {
            if (u[i] > 1 ||sz[i] > sz[now]) {
                continue;
            }
            if (2 * sz[i] > tar) {
                nx = i;
                break;
            }
        }
        if (nx) {
            now = nx;
        }
        else {
            return now;
        }
    }
}
void add(int now, int x, int d, int p) {
    x ^= a[now];
    mask[now] = x;
    num[x] += d;
    for (auto i:g[now]) {
        if (i == p || u[i] == 2) {
            continue;
        }
        add(i, x, d, now);
    }
}
ll upd (int now, int d, int m, int p) {
    ll res = 0;
    for (int i = 1 ; i < (1 << 20); i<<= 1) {
        int tar = m ^ i ^ mask[now];
        int tmp = num[tar] * d;
        res += tmp;
        tot += tmp;
        if (!tar) {
            alone += d;
        }
    }
    int idx = mask[now] ^ m;
    int tmp = num[idx] * d;
    res += tmp;
    tot += tmp;
    if (!idx) {
        alone += d;
    }
    for (auto i:g[now]) {
        if (i == p || u[i]) {
            continue;
        }
        res += upd(i, d, m, now);
    }
    ans[now] += res;
    return res;
}
void solve(int now) {
    //cout << "NOW" << endl;
    build(now);
    now = find_root(now, sz[now]);
    clear_used(now);
    u[now] = 2;
    tot = 0;
    for (auto i:g[now]) {
        if (u[i]) {
            continue;
        }
        add(i, 0, 1, now);
        upd(i, -1, a[now], now);
        add(i, 0, -1, now);
    }
    for (auto i:g[now]) {
        if (u[i]) {
            continue;
        }
        add(i, 0, 1, now);
    }
    alone = 0;
    num[0]++;
    for (auto i:g[now]) {
        if (u[i]) {
            continue;
        }
        upd(i, 1, a[now], now);
    }
    num[0]--;
    ans[now] += (tot + alone) / 2;
    for (auto i:g[now]) {
        if (u[i]) {
            continue;
        }
        add(i, 0, -1, now);
    }
    for (auto i:g[now]) {
        if (!u[i]) {
            solve(i);
        }
    }
}
int main(){
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    string s;
    cin >> n;
    f (n - 1) {
        int x, y;
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }
    cin >> s;
    s = " " + s;
    f1 (n) {
        a[i] = (1<<(s[i]-'a'));
    }
    solve(1);
    f1 (n) {
        cout << ans[i] + 1 << ' ';
    }
    cout << '\n';
}


/*بِسْمِ اللَّهِ الرَّحْمَنِ الرَّحِيم*/
#include <bits/stdc++.h>
using namespace std;
#define INF 1<<30
#define endl '\n'
#define maxn 1000005
#define FASTIO ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
typedef long long ll;
const double PI = acos(-1.0);
const ll mod = 1e9 + 7;

inline void normal(ll &a) { a %= mod; (a < 0) && (a += mod); }
inline ll modMul(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a * b) % mod; }
inline ll modAdd(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); return (a + b) % mod; }
inline ll modSub(ll a, ll b) { a %= mod, b %= mod; normal(a), normal(b); a -= b; normal(a); return a; }
inline ll modPow(ll b, ll p) { ll r = 1; while (p) { if (p & 1) r = modMul(r, b); b = modMul(b, b); p >>= 1; } return r; }
inline ll modInverse(ll a) { return modPow(a, mod - 2); }
inline ll modDiv(ll a, ll b) { return modMul(a, modInverse(b)); }

/* for Random Number generate
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
*/
///**
template < typename F, typename S >
ostream& operator << ( ostream& os, const pair< F, S > & p ) {
  return os << "(" << p.first << ", " << p.second << ")";
}

template < typename T >
ostream &operator << ( ostream & os, const vector< T > &v ) {
  os << "{";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if ( it != v.begin() ) os << ", ";
    os << *it;
  }
  return os << "}";
}

template < typename T >
ostream &operator << ( ostream & os, const set< T > &v ) {
  os << "[";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if ( it != v.begin()) os << ", ";
    os << *it;
  }
  return os << "]";
}

template < typename F, typename S >
ostream &operator << ( ostream & os, const map< F, S > &v ) {
  os << "[";
  for (auto it = v.begin(); it != v.end(); ++it) {
    if ( it != v.begin() ) os << ", ";
    os << it -> first << " = " << it -> second ;
  }
  return os << "]";
}

#define dbg(args...) do {cerr << #args << " : "; faltu(args); } while(0)

clock_t tStart = clock();
#define timeStamp dbg("Execution Time: ", (double)(clock() - tStart)/CLOCKS_PER_SEC)

void faltu () { cerr << endl; }

template <typename T>
void faltu( T a[], int n ) {
  for (int i = 0; i < n; ++i) cerr << a[i] << ' ';
  cerr << endl;
}

template <typename T, typename ... hello>
void faltu( T arg, const hello &... rest) { cerr << arg << ' '; faltu(rest...); }
// Program showing a policy-based data structure.
#include <ext/pb_ds/assoc_container.hpp> // Common file
#include <ext/pb_ds/tree_policy.hpp>
#include <functional> // for less
#include <iostream>
using namespace __gnu_pbds;
using namespace std;
// GNU link : https://goo.gl/WVDL6g
typedef tree<int, null_type, less_equal<int>, rb_tree_tag,
        tree_order_statistics_node_update>
        new_data_set;

// find_by_order(k) – ফাংশনটি kth ordered element এর একটা পয়েন্টার রিটার্ন করে। অর্থাৎ তুমি চাইলেই kth ইন্ডেক্সে কি আছে, সেটা জেনে ফেলতে পারছো!
// order_of_key(x) – ফাংশনটি x এলিমেন্টটা কোন পজিশনে আছে সেটা বলে দেয়।

//*//**___________________________________________________**/
const int N = 2e5 + 5;
vector<int> g[N];
int letter[N], sz[N], treesz;
bool vis[N];

int dfs(int u, int p)
{
  sz[u] = 1;
  for (auto v : g[u]) {
    if (vis[v] || v == p)continue;
    sz[u] += dfs(v, u);
  }
  if (p == -1) treesz = sz[u];
  return sz[u];
}

int findCenter(int u, int p)
{
  for (auto v : g[u]) {
    if (vis[v] || v == p)continue;
    if (sz[v] * 2 > treesz)return findCenter(v, u);
  }
  return u;
}

ll sm, ans[N];
int Timer;
int when[(1 << 21) + 5], cnt[(1 << 21) + 5];

void dfs1(int u, int p, int mask, int val)
{
  mask ^= letter[u];
  if (when[mask] != Timer) {
    when[mask] = Timer;
    cnt[mask] = 0;
  }
  cnt[mask] += val;
  for (auto v : g[u]) {
    if (vis[v] || v == p)continue;
    dfs1(v, u, mask, val);
  }
}

ll dfs2(int u, int p, int mask)
{
  ll res = 0;
  mask ^= letter[u];
  for (auto v : g[u]) {
    if (!vis[v] && v != p)res +=  dfs2(v, u, mask);
  }
  if (when[mask] == Timer) res += cnt[mask];
  if (mask == 0) {
    sm++;
    res++;
  }
  for (int i = 0; i < 21; i++) {
    int need = mask ^ (1 << i);
    if (when[need] == Timer) res += cnt[need];
    if (need == 0) {
      res++;
      sm++;
    }
  }
  ans[u] += res;
  return res;
}

void solve(int center)
{
  Timer++;
  sm = 0;
  for (auto v : g[center]) {
    if (!vis[v])dfs1(v, center, 0, 1);
  }
  for (int v : g[center]) {
    if (vis[v])continue;
    dfs1(v, center, 0, -1);
    sm += dfs2(v, center, letter[center]);
    dfs1(v, center, 0, 1);
  }
  sm /= 2;
  ans[center] += sm;
}

void compsolve(int u)
{
  dfs(u, -1);
  int center = findCenter(u, -1);
  solve(center);
  vis[center] = true;
  for (auto v : g[center]) {
    if (!vis[v])compsolve(v);
  }
}

int main()
{
  FASTIO
  ///*
#ifndef ONLINE_JUDGE
  freopen("in.txt", "r", stdin);
  freopen("out.txt", "w", stdout);
  freopen("error.txt", "w", stderr);
#endif
//*/
  int n;
  cin >> n;
  for (int i = 1; i < n; i++) {
    int u, v;
    cin >> u >> v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  string s;
  cin >> s;
  for (int i = 0; i < n; i++)
    letter[i + 1] = (1 << (s[i] - 'a'));
  compsolve(1);
  for (int i = 1; i <= n; i++)
    cout << ans[i] + 1 << " ";
  cout << endl;
  return 0;
}


/*************************************************************************
    > File Name: E.cpp
    > Author: Roundgod
    > Mail: wcysai@foxmail.com
    > Created Time: 2018-07-24 15:58:47
 ************************************************************************/

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXN 300005
#define INF 1000000000
#define MOD 1000000007
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
ll n,root,a[MAXN],sz[MAXN],cnt[1<<20],ans[MAXN],inc[MAXN];
vector<ll> G[MAXN];
bool centroid[MAXN];
P getroot(ll v,ll p,ll t)//search_centroid
{
    P res=P(INT_MAX,-1);
	ll m=0;
    sz[v]=1;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        res=min(res,getroot(to,v,t));
        m=max(m,sz[to]);
        sz[v]+=sz[to];
    }
    m=max(m,t-sz[v]);
    res=min(res,P(m,v));
    return res;
}
void getmask(ll v,ll p,ll mask,ll num)//enumerate path
{
    mask^=(1<<a[v]);
    cnt[mask]+=num;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        getmask(to,v,mask,num);
    }
}
ll check(ll v,ll p,ll mask)
{
    mask^=(1<<a[v]);
    ll res=cnt[mask];
    for(ll i=0;i<20;i++) res+=cnt[mask^(1<<i)];
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        res+=check(to,v,mask);
    }
    ans[v]+=res;
    return res;
}
void solve(ll v)
{
    //printf("%lld\n",v);
    centroid[v]=true;
    getmask(v,0,0,1);
    ll sum=0;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(centroid[to]) continue;
        getmask(to,v,1<<a[v],-1);
        sum+=check(to,v,0);
        getmask(to,v,1<<a[v],1);
    }
    for(int i=0;i<20;i++) sum+=cnt[1<<i];
    sum+=cnt[0]+1;
    ans[v]+=sum/2;
    getmask(v,0,0,-1);
    //for(ll i=1;i<=n;i++) printf("%lld ",ans[i]);
    //puts("");
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(centroid[to]) continue;
        root=getroot(to,v,sz[to]).S;
        solve(root);
    }
    root=v;
}
void ac()
{
    memset(cnt,0,sizeof(cnt));
    memset(ans,0,sizeof(ans));
    memset(centroid,false,sizeof(centroid));
    root=getroot(1,0,n).S;
    solve(root);
    for(ll i=1;i<=n;i++) printf("%lld ",ans[i]);
}
string str;
int main()
{
    scanf("%lld",&n);
    for(ll i=0;i<n-1;i++)
    {
        ll u,v;
        scanf("%lld%lld",&u,&v);
        G[u].push_back(v);G[v].push_back(u);
    }
    cin>>str;
    for(ll i=0;i<n;i++) a[i+1]=str[i]-'a';
    ac();
    return 0;
}


/*************************************************************************
    > File Name: E.cpp
    > Author: Roundgod
    > Mail: wcysai@foxmail.com
    > Created Time: 2018-07-24 15:58:47
 ************************************************************************/

#pragma GCC optimize(3)
#include<bits/stdc++.h>
#define MAXN 300005
#define INF 1000000000
#define MOD 1000000007
#define F first
#define S second
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
ll n,root,sum,a[MAXN],sz[MAXN],mask[MAXN],cnt[1<<20],ans[MAXN],inc[MAXN];
vector<ll> G[MAXN];
bool centroid[MAXN];
P getroot(ll v,ll p,ll t)//search_centroid
{
    P res=P(INT_MAX,-1);
	ll m=0;
    sz[v]=1;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        res=min(res,getroot(to,v,t));
        m=max(m,sz[to]);
        sz[v]+=sz[to];
    }
    m=max(m,t-sz[v]);
    res=min(res,P(m,v));
    return res;
}
void getmask(ll v,ll p)//enumerate path
{
    cnt[mask[v]]++;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        mask[to]=mask[v]^(1<<a[to]);
        getmask(to,v);
    }
}
void erasemask(ll v,ll p)
{
    cnt[mask[v]]--;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        erasemask(to,v);
    }
}
void calc(ll v,ll sgn,ll rt)
{
    for(ll i=0;i<20;i++)
        inc[v]+=sgn*(cnt[mask[v]^(1<<i)^mask[rt]]);
    inc[v]+=sgn*(cnt[mask[v]^mask[rt]]);
    inc[v]-=sgn;sum+=inc[v];
}
void check(ll v,ll p,ll rt,ll sgn)
{
    calc(v,sgn,rt);
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        check(to,v,rt,sgn);
    }
}
void acm(ll v,ll p)
{
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        acm(to,v);
        inc[v]+=inc[to];
    }
}
void checkout(ll v,ll p,ll rt)
{
    if(v!=rt)ans[v]+=inc[v];inc[v]=0;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(to==p||centroid[to]) continue;
        checkout(to,v,rt);
    }
}
void solve(ll v)
{
    //printf("%lld\n",v);
    centroid[v]=true;
    mask[v]=1<<a[v];
    getmask(v,0);
    sum=0;
    check(v,0,v,1);
    acm(v,0);checkout(v,0,v);
    erasemask(v,0);
    ans[v]+=sum/2;
    sum=0;
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(centroid[to]) continue;
        mask[to]=(1<<a[v])^(1<<a[to]);
        getmask(to,v);
        check(to,v,v,-1);
        checkout(to,v,v);
        erasemask(to,v);
    }
    ans[v]-=sum/2;
    //for(ll i=1;i<=n;i++) printf("%lld ",ans[i]);
    //puts("");
    for(ll i=0;i<(int)G[v].size();i++)
    {
        ll to=G[v][i];
        if(centroid[to]) continue;
        root=getroot(to,v,sz[to]).S;
        solve(root);
    }
    root=v;
}
void ac()
{
    memset(cnt,0,sizeof(cnt));
    memset(ans,0,sizeof(ans));
    memset(centroid,false,sizeof(centroid));
    root=getroot(1,0,n).S;
    solve(root);
    for(ll i=1;i<=n;i++) printf("%lld ",ans[i]+1);
}
string str;
int main()
{
    scanf("%lld",&n);
    for(ll i=0;i<n-1;i++)
    {
        ll u,v;
        scanf("%lld%lld",&u,&v);
        G[u].push_back(v);G[v].push_back(u);
    }
    cin>>str;
    for(ll i=0;i<n;i++) a[i+1]=str[i]-'a';
    ac();
    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;

constexpr int N = 200005;
constexpr int MASK = 20;

using mask_t = int;

vector<int> adj [N];
int id_at [N];
int level [N];
int parent [N];

ll ans [N];
ll ans_repeating [N];

vector<map<mask_t, int>> masks;

pair<ll, ll> calc2(int v, int p, mask_t carry, const map<mask_t, int> &global_holder) {

    carry ^= mask_t(1 << id_at[v]);

    mask_t cur (1 << (MASK-1));

    ll add = 0;
    ll one_cnt = __builtin_popcount(carry) <= 1 ? 1 : 0;

    for (int i = 0; i < MASK-1; i++) {
        auto lookup = carry ^ cur;
        auto it = global_holder.find(lookup);
        if (it != global_holder.end()) {
            add += it->second;
        }
        cur >>= 1;
    }

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        auto res = calc2(u, v, carry, global_holder);
        add += res.first;
        one_cnt += res.second;
    }

    ans[v] += add;
    ans[v] += one_cnt;

    return make_pair(add, one_cnt);
}

void calc(int v, int p, int branch_id, mask_t carry) {

    //cout << "calc " << v << endl;

    map<mask_t, int> global_holder;

    if (p != -1) {
        masks[branch_id][carry]++;
    } else {
        ans[v]++;
    }

    int branch_cnt = 0;

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        if (p == -1) {
            masks.push_back(map<mask_t, int>());
        }
        calc(u, v, p == -1 ? branch_cnt : branch_id, carry ^ mask_t(1 << id_at[u]));
        branch_cnt++;
    }

    if (p == -1) {
        for (int i = 0; i < branch_cnt; i++) {
            for (const auto &m : masks[i]) {
                global_holder[m.first] += m.second;
            }
        }

        branch_cnt = 0;
        ll add = 0;

        for (int u : adj[v]) {
            if (u == p || level[u] != -1) continue;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] -= m.second;
            }

            auto res = calc2(u, v, mask_t(1 << id_at[v]), global_holder);

            add += res.first;
            ans[v] += res.second;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] += m.second;
            }

            branch_cnt++;
        }

        ans[v] += add/2;

        masks.clear();
    }
}

int dfs(int v, int p, int size, int &center) {

    int sz = 1;

    for (int u : adj[v]) {
        if (level[u] != -1 || u == p) continue;
        sz += dfs(u, v, size, center);
    }

    if (center == -1 && (p == -1 || sz*2 >= size)) {
        center = v;
    }

    return sz;
}

void cd_build(int v, int size, int depth, int p = -1) {

    int center = -1;
    dfs(v, -1, size, center);

    level[center] = depth;
    parent[center] = p;

    //cout << "center: " << center << " " << depth << endl;

    calc(center, -1, -1, mask_t(0));

    for (int u : adj[center]) {
        if (level[u] != -1) continue;
        cd_build(u, size/2, depth+1, center);
    }
}

int main(void) {

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    for (int i = 0; i < n-1; i++) {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    string s;
    cin >> s;

    for (int i = 1; i <= n; i++) {
        id_at[i] = s[i-1] - 'a';
    }

    fill_n(level, N, -1);
    cd_build(1, n, 0, -1);

    for (int i = 1; i <= n; i++) {
        cout << ans[i] << " ";
    }

    cout << "\n";

    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;

constexpr int N = 200005;
constexpr int MASK = 20;

using mask_t = int;

vector<int> adj [N];
int id_at [N];
int level [N];
int parent [N];

ll ans [N];
ll ans_repeating [N];

vector<map<mask_t, int>> masks;

pair<ll, ll> calc2(int v, int p, mask_t carry, const map<mask_t, int> &global_holder) {

    carry ^= mask_t(1 << id_at[v]);

    mask_t cur (1 << (MASK-1));

    ll add = 0;
    ll one_cnt = __builtin_popcount(carry) <= 1 ? 1 : 0;

    for (int i = 0; i < MASK; i++) {
        auto lookup = carry ^ cur;
        auto it = global_holder.find(lookup);
        if (it != global_holder.end()) {
            add += it->second;
        }
        cur >>= 1;
    }

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        auto res = calc2(u, v, carry, global_holder);
        add += res.first;
        one_cnt += res.second;
    }

    ans[v] += add;
    ans[v] += one_cnt;

    return make_pair(add, one_cnt);
}

void calc(int v, int p, int branch_id, mask_t carry) {

    //cout << "calc " << v << endl;

    map<mask_t, int> global_holder;

    if (p != -1) {
        masks[branch_id][carry]++;
    } else {
        ans[v]++;
    }

    int branch_cnt = 0;

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        if (p == -1) {
            masks.push_back(map<mask_t, int>());
        }
        calc(u, v, p == -1 ? branch_cnt : branch_id, carry ^ mask_t(1 << id_at[u]));
        branch_cnt++;
    }

    if (p == -1) {
        for (int i = 0; i < branch_cnt; i++) {
            for (const auto &m : masks[i]) {
                global_holder[m.first] += m.second;
            }
        }

        branch_cnt = 0;
        ll add = 0;

        for (int u : adj[v]) {
            if (u == p || level[u] != -1) continue;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] -= m.second;
            }

            auto res = calc2(u, v, mask_t(1 << id_at[v]), global_holder);

            add += res.first;
            ans[v] += res.second;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] += m.second;
            }

            branch_cnt++;
        }

        ans[v] += add/2;

        masks.clear();
    }
}

int dfs(int v, int p, int size, int &center) {

    int sz = 1;

    for (int u : adj[v]) {
        if (level[u] != -1 || u == p) continue;
        sz += dfs(u, v, size, center);
    }

    if (center == -1 && (p == -1 || sz*2 >= size)) {
        center = v;
    }

    return sz;
}

void cd_build(int v, int size, int depth, int p = -1) {

    int center = -1;
    dfs(v, -1, size, center);

    level[center] = depth;
    parent[center] = p;

    //cout << "center: " << center << " " << depth << endl;

    calc(center, -1, -1, mask_t(0));

    for (int u : adj[center]) {
        if (level[u] != -1) continue;
        cd_build(u, size/2, depth+1, center);
    }
}

int main(void) {

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    for (int i = 0; i < n-1; i++) {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    string s;
    cin >> s;

    for (int i = 1; i <= n; i++) {
        id_at[i] = s[i-1] - 'a';
    }

    fill_n(level, N, -1);
    cd_build(1, n, 0, -1);

    for (int i = 1; i <= n; i++) {
        cout << ans[i] << " ";
    }

    cout << "\n";

    return 0;
}


#include <bits/stdc++.h>

using namespace std;
using ll = long long;

constexpr int N = 200005;
constexpr int MASK = 21;

using mask_t = int;

vector<int> adj [N];
int id_at [N];
int level [N];
int parent [N];

ll ans [N];
ll ans_repeating [N];

vector<map<mask_t, int>> masks;

pair<ll, ll> calc2(int v, int p, mask_t carry, const map<mask_t, int> &global_holder) {

    carry ^= mask_t(1 << id_at[v]);

    mask_t cur (1 << (MASK-1));

    ll add = 0;
    ll one_cnt = __builtin_popcount(carry) <= 1 ? 1 : 0;

    for (int i = 0; i < MASK; i++) {
        auto lookup = carry ^ cur;
        auto it = global_holder.find(lookup);
        if (it != global_holder.end()) {
            add += it->second;
        }
        cur >>= 1;
    }

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        auto res = calc2(u, v, carry, global_holder);
        add += res.first;
        one_cnt += res.second;
    }

    ans[v] += add;
    ans[v] += one_cnt;

    return make_pair(add, one_cnt);
}

void calc(int v, int p, int branch_id, mask_t carry) {

    //cout << "calc " << v << endl;

    map<mask_t, int> global_holder;

    if (p != -1) {
        masks[branch_id][carry]++;
    } else {
        ans[v]++;
    }

    int branch_cnt = 0;

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        if (p == -1) {
            masks.push_back(map<mask_t, int>());
        }
        calc(u, v, p == -1 ? branch_cnt : branch_id, carry ^ mask_t(1 << id_at[u]));
        branch_cnt++;
    }

    if (p == -1) {
        for (int i = 0; i < branch_cnt; i++) {
            for (const auto &m : masks[i]) {
                global_holder[m.first] += m.second;
            }
        }

        branch_cnt = 0;
        ll add = 0;

        for (int u : adj[v]) {
            if (u == p || level[u] != -1) continue;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] -= m.second;
            }

            auto res = calc2(u, v, mask_t(1 << id_at[v]), global_holder);

            add += res.first;
            ans[v] += res.second;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] += m.second;
            }

            branch_cnt++;
        }

        ans[v] += add/2;

        masks.clear();
    }
}

int dfs(int v, int p, int size, int &center) {

    int sz = 1;

    for (int u : adj[v]) {
        if (level[u] != -1 || u == p) continue;
        sz += dfs(u, v, size, center);
    }

    if (center == -1 && (p == -1 || sz*2 >= size)) {
        center = v;
    }

    return sz;
}

void cd_build(int v, int size, int depth, int p = -1) {

    int center = -1;
    dfs(v, -1, size, center);

    level[center] = depth;
    parent[center] = p;

    //cout << "center: " << center << " " << depth << endl;

    calc(center, -1, -1, mask_t(0));

    for (int u : adj[center]) {
        if (level[u] != -1) continue;
        cd_build(u, size/2, depth+1, center);
    }
}

int main(void) {

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    for (int i = 0; i < n-1; i++) {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    string s;
    cin >> s;

    for (int i = 1; i <= n; i++) {
        id_at[i] = s[i-1] - 'a';
    }

    fill_n(level, N, -1);
    cd_build(1, n, 0, -1);

    for (int i = 1; i <= n; i++) {
        cout << ans[i] << " ";
    }

    cout << "\n";

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;

#define A(x) get<0>(x)
#define B(x) get<1>(x)
#define C(x) get<2>(x)
#define D(x) get<3>(x)

#define mp make_pair
#define mt make_tuple

constexpr ld pi = acos((ld) -1.0);
mt19937 gen (228);

#ifdef REK

#define dbg(...) cout << __VA_ARGS__
#define stddbg(...) printf(__VA_ARGS__)

#else

#define dbg(...) ((void) 0)
#define stddbg(...) ((void) 0)

#endif

constexpr int N = 200005;
constexpr int MASK = 21;

using mask_t = int;

vector<int> adj [N];
int id_at [N];
int level [N];
int parent [N];

ll ans [N];
ll ans_repeating [N];

vector<map<mask_t, int>> masks;

pair<ll, ll> calc2(int v, int p, mask_t carry, const map<mask_t, int> &global_holder) {

    carry ^= mask_t(1 << id_at[v]);

    dbg("vertex " << v << ", carry is " << bitset<25>(carry) << endl);

    mask_t cur (1 << (MASK-1));

    ll add = 0;
    ll one_cnt = __builtin_popcount(carry) <= 1 ? 1 : 0;

    for (int i = 0; i < MASK+1; i++) {
        auto lookup = carry ^ cur;
        auto it = global_holder.find(lookup);
        if (it != global_holder.end()) {
            dbg("add with " << bitset<25>(cur) << " : " << bitset<25>(it->first) << endl);
            add += it->second;
        }
        cur >>= 1;
    }

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        auto res = calc2(u, v, carry, global_holder);
        add += res.first;
        one_cnt += res.second;
    }

    ans[v] += add;
    ans[v] += one_cnt;

    return make_pair(add, one_cnt);
}

void calc(int v, int p, int branch_id, mask_t carry) {

    dbg("calc " << v << endl);

    if (p != -1) {
        masks[branch_id][carry]++;
    } else {
        ans[v]++;
    }

    int branch_cnt = 0;

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        if (p == -1) {
            masks.push_back(map<mask_t, int>());
        }
        calc(u, v, p == -1 ? branch_cnt : branch_id, carry ^ mask_t(1 << id_at[u]));
        branch_cnt++;
    }

    if (p == -1) {
        map<mask_t, int> global_holder;

        for (int i = 0; i < branch_cnt; i++) {
            for (const auto &m : masks[i]) {
                global_holder[m.first] += m.second;
            }
        }

        branch_cnt = 0;
        ll add = 0;

        for (int u : adj[v]) {
            if (u == p || level[u] != -1) continue;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] -= m.second;
            }

            auto res = calc2(u, v, mask_t(1 << id_at[v]), global_holder);

            add += res.first;
            ans[v] += res.second;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] += m.second;
            }

            branch_cnt++;
        }

        ans[v] += add/2;

        masks.clear();
    }
}

int dfs(int v, int p, int size, int &center) {

    int sz = 1;

    for (int u : adj[v]) {
        if (level[u] != -1 || u == p) continue;
        sz += dfs(u, v, size, center);
    }

    if (center == -1 && (p == -1 || sz*2 >= size)) {
        center = v;
    }

    return sz;
}

void cd_build(int v, int size, int depth, int p = -1) {

    int center = -1;
    dfs(v, -1, size, center);

    level[center] = depth;
    parent[center] = p;

    dbg("center: " << center << " " << depth << endl);

    calc(center, -1, -1, mask_t(0));

    for (int u : adj[center]) {
        if (level[u] != -1) continue;
        cd_build(u, size/2, depth+1, center);
    }
}

int main(void) {

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    for (int i = 0; i < n-1; i++) {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    string s;
    cin >> s;

    for (int i = 1; i <= n; i++) {
        id_at[i] = s[i-1] - 'a';
    }

    fill_n(level, N, -1);
    cd_build(1, n, 0, -1);

    for (int i = 1; i <= n; i++) {
        cout << ans[i] << " ";
    }

    cout << "\n";

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

using ll = long long;
using ld = long double;
using pll = pair<ll, ll>;

#define A(x) get<0>(x)
#define B(x) get<1>(x)
#define C(x) get<2>(x)
#define D(x) get<3>(x)

#define mp make_pair
#define mt make_tuple

constexpr ld pi = acos((ld) -1.0);
mt19937 gen (228);

#ifdef REK

#define dbg(...) cout << __VA_ARGS__
#define stddbg(...) printf(__VA_ARGS__)

#else

#define dbg(...) ((void) 0)
#define stddbg(...) ((void) 0)

#endif

constexpr int N = 200005;
constexpr int MASK = 20;

using mask_t = int;

vector<int> adj [N];
int id_at [N];
int level [N];
int parent [N];

ll ans [N];
ll ans_repeating [N];

vector<unordered_map<mask_t, int>> masks;

pair<ll, ll> calc2(int v, int p, mask_t carry, const unordered_map<mask_t, int> &global_holder) {

    carry ^= mask_t(1 << id_at[v]);

    dbg("vertex " << v << ", carry is " << bitset<25>(carry) << endl);

    mask_t cur (1 << (MASK-1));

    ll add = 0;
    ll one_cnt = __builtin_popcount(carry) <= 1 ? 1 : 0;

    for (int i = 0; i < MASK+1; i++) {
        auto lookup = carry ^ cur;
        auto it = global_holder.find(lookup);
        if (it != global_holder.end()) {
            dbg("add with " << bitset<25>(cur) << " : " << bitset<25>(it->first) << endl);
            add += it->second;
        }
        cur >>= 1;
    }

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        auto res = calc2(u, v, carry, global_holder);
        add += res.first;
        one_cnt += res.second;
    }

    ans[v] += add;
    ans[v] += one_cnt;

    return make_pair(add, one_cnt);
}

void calc(int v, int p, int branch_id, mask_t carry) {

    dbg("calc " << v << endl);

    if (p != -1) {
        masks[branch_id][carry]++;
    } else {
        ans[v]++;
    }

    int branch_cnt = 0;

    for (int u : adj[v]) {
        if (u == p || level[u] != -1) continue;
        if (p == -1) {
            masks.push_back(unordered_map<mask_t, int>());
        }
        calc(u, v, p == -1 ? branch_cnt : branch_id, carry ^ mask_t(1 << id_at[u]));
        branch_cnt++;
    }

    if (p == -1) {
        unordered_map<mask_t, int> global_holder;

        for (int i = 0; i < branch_cnt; i++) {
            for (const auto &m : masks[i]) {
                global_holder[m.first] += m.second;
            }
        }

        branch_cnt = 0;
        ll add = 0;

        for (int u : adj[v]) {
            if (u == p || level[u] != -1) continue;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] -= m.second;
            }

            auto res = calc2(u, v, mask_t(1 << id_at[v]), global_holder);

            add += res.first;
            ans[v] += res.second;

            for (const auto &m : masks[branch_cnt]) {
                global_holder[m.first] += m.second;
            }

            branch_cnt++;
        }

        ans[v] += add/2;

        masks.clear();
    }
}

int dfs(int v, int p, int size, int &center) {

    int sz = 1;

    for (int u : adj[v]) {
        if (level[u] != -1 || u == p) continue;
        sz += dfs(u, v, size, center);
    }

    if (center == -1 && (p == -1 || sz*2 >= size)) {
        center = v;
    }

    return sz;
}

void cd_build(int v, int size, int depth, int p = -1) {

    int center = -1;
    dfs(v, -1, size, center);

    level[center] = depth;
    parent[center] = p;

    dbg("center: " << center << " " << depth << endl);

    calc(center, -1, -1, mask_t(0));

    for (int u : adj[center]) {
        if (level[u] != -1) continue;
        cd_build(u, size/2, depth+1, center);
    }
}

int main(void) {

    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);

    int n;
    cin >> n;

    for (int i = 0; i < n-1; i++) {
        int a, b;
        cin >> a >> b;
        adj[a].push_back(b);
        adj[b].push_back(a);
    }

    string s;
    cin >> s;

    for (int i = 1; i <= n; i++) {
        id_at[i] = s[i-1] - 'a';
    }

    fill_n(level, N, -1);
    cd_build(1, n, 0, -1);

    for (int i = 1; i <= n; i++) {
        cout << ans[i] << " ";
    }

    cout << "\n";

    return 0;
}


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

int getroot(int x,int fa,int tot)
{
    for (int i=first[x];i;i=e[i].next)
    if(!vis[e[i].to]&&(fa^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 (int i=first[x];i;i=e[i].next)
    if(!vis[e[i].to]&&(fa^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 (int i=0;i<20;i++) t+=sum[now^(1<<i)];
    t+=sum[now];
    for (int i=first[x];i;i=e[i].next)
    if(!vis[e[i].to]&&(fa^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 (int 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 (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=e[i].next)
    if(!vis[e[i].to]) getsize(e[i].to,0),solve(getroot(e[i].to,0,sz[e[i].to]));
}

main()
{
    scanf("%d",&n);
    for (int i=1,x,y;i<n;i++) scanf("%d%d",&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;

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 size[maxn]; bool die[maxn];
void getsize(int x,int fa)
{
    size[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;
        getsize(e.to,x); size[x]+=size[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 (size[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;
        getsize(e.to,0); cd(getroot(e.to,0,size[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';
    getsize(1,0);
    cd(getroot(1,0,size[1]));
    for (int i=1;i<=n;i++) printf("%lld ",ans[i]);
    return 0;
}


#include<bits/stdc++.h>
using namespace std;
#define int long long
struct Edge{int to,next;}E[500000];
int n,first[500000],top,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].next=first[x]; first[x]=top;}
void getsize(int x,int fa)
{
    sz[x]=1;
    for (int i=first[x];i;i=E[i].next)
    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 (int i=first[x];i;i=E[i].next)
    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 (int 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 (int i=0;i<20;i++) t+=sum[now^(1<<i)];
    t+=sum[now];
    for (int 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 (int 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 (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=E[i].next)
    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 (int i=1;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,first[500000],top,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].next=first[x]; first[x]=top;}
void getsize(int x,int fa)
{
    sz[x]=1;
    for (int i=first[x];i;i=E[i].next)
    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 (int i=first[x];i;i=E[i].next)
    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 (int 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 (int i=0;i<20;i++) t+=sum[now^(1<<i)];
    t+=sum[now];
    for (int 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 (int 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 (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=E[i].next)
    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 (int i=1;i<n;i++) scanf("%lld%d",&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;
}