#include <bits/stdc++.h>
using namespace std;
set<int> tree[100002];
int subsz[100002], parent[100002];
int nn;
vector<int> G[100002];
int ans[100002];
void dfs1(int u, int p) {
  subsz[u] = 1;
  nn++;
  for (auto it = tree[u].begin(); it != tree[u].end(); it++) {
    if (*it != p) {
      dfs1(*it, u);
      subsz[u] += subsz[*it];
    }
  }
}
int dfs2(int u, int p) {
  for (auto it = tree[u].begin(); it != tree[u].end(); it++) {
    if (*it != p && subsz[*it] > (nn / 2)) {
      return dfs2(*it, u);
    }
  }
  return u;
}
void decompose(int root, int p) {
  nn = 0;
  dfs1(root, root);
  int centroid = dfs2(root, root);
  if (p == -1) p = centroid;
  parent[centroid] = p;
  for (auto it = tree[centroid].begin(); it != tree[centroid].end(); it++) {
    tree[*it].erase(centroid);
    decompose(*it, centroid);
  }
}
void ar_koto_dfs(int x) {
  for (int u : G[x]) {
    ans[u] = ans[x] + 1;
    ar_koto_dfs(u);
  }
}
int main() {
  int n;
  scanf("%d", &n);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d%d", &u, &v);
    tree[u].insert(v);
    tree[v].insert(u);
  }
  decompose(1, -1);
  int root;
  for (int i = 1; i <= n; i++) {
    if (parent[i] == i)
      root = i;
    else
      G[parent[i]].push_back(i);
  }
  ar_koto_dfs(root);
  for (int i = 1; i <= n; i++) printf("%c ", ans[i] + 'A');
  return 0;
}
