#include <bits/stdc++.h>   using namespace std;   const int block_size = 320;   const long long mod = 1e9 + 7;   const long long inf = 1e9 + 7;   const long double eps = 1e-9;   const double PI = atan(1) * 4;   template <typename T>   inline int sign(const T &a) {     if (a < 0) return -1;     if (a > 0) return 1;     return 0;   }   template <typename T, typename S>   inline bool upmin(T &a, const S &b) {     return a > b ? a = b, 1 : 0;   }   template <typename T, typename S>   inline bool upmax(T &a, const S &b) {     return a < b ? a = b, 1 : 0;   }   template <typename T>   inline void in(T &x) {     x = 0;     T f = 1;     char ch = getchar();     while (!isdigit(ch)) {       if (ch ==  - ) f = -1;       ch = getchar();     }     while (isdigit(ch)) {       x = x * 10 + ch -  0 ;       ch = getchar();     }     x *= f;   }   long long twop(int x) { return 1LL << x; }   template <typename A, typename B>   inline void in(A &x, B &y) {     in(x);     in(y);   }   template <typename A, typename B, typename C>   inline void in(A &x, B &y, C &z) {     in(x);     in(y);     in(z);   }   template <typename A, typename B, typename C, typename D>   inline void in(A &x, B &y, C &z, D &d) {     in(x);     in(y);     in(z);     in(d);   }   int c[500010], tsize[500010], hv[500010], ans[500010];   vector<int> son[500010];   int mp[4194304 + 10];   int global;   int addLen;   int opt[4194304], cnt = 0;   void change(int id, int to) {     upmax(mp[id], to);     opt[cnt++] = id;   }   void rollback() {     while (cnt > 0) {       mp[opt[--cnt]] = -inf;     }   }   void tra(int cur, int len, int mask, int &ans) {     for (long long i = 0; i < 22; i++) {       ans = max(ans, mp[mask ^ twop(i) ^ global] + len + addLen);     }     ans = max(ans, mp[mask ^ global] + len + addLen);     for (auto i : son[cur]) {       tra(i, len + 1, mask ^ twop(c[i]), ans);     }   }   void add(int cur, int len, int mask) {     change(mask ^ global, len - addLen);     for (auto i : son[cur]) {       add(i, len + 1, mask ^ twop(c[i]));     }   }   void solve(int cur, bool record) {     for (auto s : son[cur]) {       if (s != hv[cur]) {         solve(s, 0);         upmax(ans[cur], ans[s]);       }     }     if (hv[cur]) {       solve(hv[cur], 1);       global ^= twop(c[hv[cur]]);       addLen++;       change(global, -addLen);       upmax(ans[cur], ans[hv[cur]]);       { upmax(ans[cur], mp[global] + addLen); }       for (long long i = 0; i < 22; i++) {         upmax(ans[cur], mp[0 ^ twop(i) ^ global] + addLen);       }       for (auto i : son[cur]) {         if (i != hv[cur]) {           tra(i, 1, twop(c[i]), ans[cur]);           add(i, 1, twop(c[i]));         }       }     } else {       mp[0] = 0;       global = 0;       addLen = 0;     }     if (!record) {       global = 0;       rollback();       addLen = 0;     }   }   void dfs(int cur) {     tsize[cur] = 1;     for (auto i : son[cur]) {       dfs(i), tsize[cur] += tsize[i];       if (tsize[i] > tsize[hv[cur]]) hv[cur] = i;     }   }   int main() {     memset(mp, 0xcf, sizeof(mp));     int n;     in(n);     for (long long i = 2; i < n + 1; i++) {       int p;       in(p);       char cc = getchar();       c[i] = cc -  a ;       son[p].push_back(i);     }     map<int, int> mp;     int global = 0, addLen = 0;     dfs(1);     solve(1, 0);     for (long long i = 1; i < n + 1; i++) printf( %d  , ans[i]);     return 0;   }