#include <stdio.h>
#include <iostream>
#include <vector>
#include <algorithm>
#include <functional>
#include <cassert>
#include <ctime>
#include <cstdlib>
typedef unsigned long long ull;
const ull mod = (ull(1) << 61) - 1;
inline ull add(ull a, ull b) {
return (a += b) < mod ? a : a - mod;
}
inline ull sub(ull a, ull b) {
return (a -= b) < mod ? a : a + mod;
}
inline ull mul(ull a, ull b) {
ull l1 = (uint32_t)a, h1 = a >> 32, l2 = (uint32_t)b, h2 = b >> 32;
ull l = l1*l2, m = l1*h2 + l2*h1, h = h1*h2;
ull ret = (l & mod) + (l >> 61) + (h << 3) + (m >> 29) + (m << 35 >> 3) + 1;
ret = (ret & mod) + (ret >> 61);
ret = (ret & mod) + (ret >> 61);
return ret-1;
}
std::vector<int> fast(int n, std::vector<std::pair<int,char>> input) {
const int NMAX = (int)5e5, PMAX = 20;
std::vector<int> answ(1+n), len(1+n);
std::vector<std::vector<int>> edges(1+n);
std::vector<char> cost(1+n); // cost from child to parent
static int parent[PMAX][1+NMAX];
static ull hashes[PMAX][1+NMAX];
// Input:
for (int u = 2; u <= n; ++u) {
int p = input[u].first;
cost[u] = input[u].second;
edges[p].push_back(u);
edges[u].push_back(p);
parent[0][u] = p;
hashes[0][u] = cost[u];
}
// Precalc powers of base:
const ull BASE = (int)1e9+7;
std::vector<ull> pow{1};
while ((int)pow.size() < NMAX) {
pow.push_back(mul(pow.back(), BASE));
}
// Precalc parents and hashes:
for (int p = 1; p < PMAX; ++p) {
for (int u = 1; u <= n; ++u) {
int v = parent[p-1][u];
if (v == 0) continue;
parent[p][u] = parent[p-1][v];
hashes[p][u] = add(mul(hashes[p-1][v], pow[1<<(p-1)]), hashes[p-1][u]);
}
}
// Get parent of vertex u with `nSteps` steps up:
std::function<int(int,int)> get_parent = [&](int u, int nSteps) {
for (int p = PMAX-1; p >= 0; --p) {
if (((nSteps >> p) & 1) == 1) {
u = parent[p][u];
}
}
return u;
};
// Get hash from vertex u with `nSteps` steps up:
std::function<ull(int,int)> get_hash = [&](int u, int nSteps) {
int sum = 0; ull hash = 0;
for (int p = PMAX-1; p >= 0; --p) {
if (((nSteps >> p) & 1) == 1) {
hash = add(hash, mul(hashes[p][u], pow[sum]));
sum += (1 << p);
u = parent[p][u];
}
}
return hash;
};
// DFS:
std::function<void(int,int)> visit = [&](int u, int p) {
int max = -1, r = u;
for (int v : edges[u]) {
if (p == v) continue;
visit(v,u);
if (len[v] > max) {
max = len[v];
r = v;
} else if (len[v] == max) {
// find first not equal symbol
int low = 0, high = max+2;
while (high - low > 1) {
int mid = (low + high) / 2;
ull hash1 = get_hash(get_parent(answ[v], max+1-mid), mid);
ull hash2 = get_hash(get_parent(answ[r], max+1-mid), mid);
if (hash1 == hash2) {
low = mid;
} else {
high = mid;
}
}
if (low < max+1) {
int pv = get_parent(answ[v], max-low);
int pr = get_parent(answ[r], max-low);
assert(cost[pv] != cost[pr]);
if (cost[pv] > cost[pr]) {
r = v;
}
} else if (answ[v] < answ[r]) {
r = v;
}
}
}
len[u] = max+1;
answ[u] = (r == u) ? r : answ[r];
};
visit(1,0); // Run dfs
// Return answer:
for (int u = 1; u <= n; ++u) {
answ[u] = (answ[u] == u) ? 0 : answ[u];
}
return answ;
}
std::vector<int> slow(int n, std::vector<std::pair<int, char>> input) {
std::vector<char> cost(1+n);
std::vector<int> answ(1+n);
std::vector<std::vector<int>> edges(1+n);
// Input:
for (int u = 2; u <= n; ++u) {
int p = input[u].first;
cost[u] = input[u].second;
edges[p].push_back(u);
edges[u].push_back(p);
}
std::function<std::string(int,int)> visit = [&](int u, int p) {
std::string best; int r = u;
for (int v : edges[u]) {
if (v == p) continue;
auto temp = cost[v] + visit(v, u);
if (temp.size() > best.size()) {
best = temp;
r = v;
} else if (temp.size() == best.size()) {
if (temp > best || (temp == best && answ[v] < answ[r])) {
best = temp;
r = v;
}
}
}
answ[u] = (r == u) ? r : answ[r];
return best;
};
visit(1,0);
for (int u = 1; u <= n; ++u) {
if (answ[u] == u) answ[u] = 0;
}
return answ;
}
std::vector<std::pair<int, char>> input(int& n) {
scanf("%d", &n);
std::vector<std::pair<int, char>> answ(1+n);
for (int u = 2; u <= n; ++u) {
int p; char c;
scanf("%d %c", &p, &c);
answ[u] = std::make_pair(p,c);
}
return answ;
}
int main() {
int n;
auto in = input(n);
auto answ1 = fast(n, in);
for (int u = 1; u <= n; ++u) {
printf("%d\n", answ1[u]);
}
return 0;
}