#include <bits/stdc++.h>
using namespace std;
const int N = 1e5 + 10;
const int INF = 1e9 + 10;
int n, current;
pair<int, int> best;
int ans[N], block[N], sz[N];
vector<int> tree[N], tree_c[N];
int dfs1(int i, int parent) {
  sz[i] = 1;
  for (int k = 0; k < tree[i].size(); ++k) {
    int j = tree[i][k];
    if (j != parent and !block[j]) sz[i] += dfs1(j, i);
  }
  return sz[i];
}
void dfs2(int i, int parent) {
  int highest = current - sz[i];
  for (int k = 0; k < tree[i].size(); ++k) {
    int j = tree[i][k];
    if (j == parent or block[j]) continue;
    dfs2(j, i);
    highest = max(highest, sz[j]);
  }
  if (highest < best.first) best = make_pair(highest, i);
}
int find_centroid(int i) {
  current = dfs1(i, 0);
  best = make_pair(INF, 0);
  dfs2(i, 0);
  return best.second;
}
int build(int i, int deep) {
  int centroid = find_centroid(i);
  block[centroid] = 1;
  for (int k = 0; k < tree[centroid].size(); ++k) {
    int j = tree[centroid][k];
    if (block[j]) continue;
    j = build(j, deep + 1);
    tree_c[centroid].push_back(j);
    tree_c[j].push_back(centroid);
  }
  return centroid;
}
bool solve(int root) {
  ans[root] = 0;
  queue<pair<int, int> > q;
  q.push(make_pair(root, -1));
  while (!q.empty()) {
    int i = q.front().first;
    int parent = q.front().second;
    q.pop();
    for (int k = 0; k < tree_c[i].size(); ++k) {
      int j = tree_c[i][k];
      if (j == parent) continue;
      if (ans[i] + 1 > 25) return false;
      ans[j] = ans[i] + 1;
      q.push(make_pair(j, i));
    }
  }
  return true;
}
int main() {
  scanf("%d", &n);
  for (int i = 1; i < n; ++i) {
    int x, y;
    scanf("%d %d", &x, &y);
    --x, --y;
    tree[x].push_back(y);
    tree[y].push_back(x);
  }
  int root = build(0, 0);
  if (!solve(root))
    printf("Impossible!\n");
  else {
    for (int i = 0; i < n; ++i) {
      if (i) printf(" ");
      printf("%c", ans[i] + 'A');
    }
    printf("\n");
  }
  return 0;
}
