#include <bits/stdc++.h>
using namespace std;
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MAXN = 1e5 + 100;
int N, sz[MAXN], pos[MAXN];
vector<int> g[MAXN];
long long ans = 0;
void getsz(int v = 0, int p = -1) {
  sz[v] = 1;
  for (int u : g[v]) {
    if (u ^ p) {
      getsz(u, v);
      sz[v] += sz[u];
      ans += 2 * min(N - sz[u], sz[u]);
    }
  }
}
int find_centroid(int v = 0, int p = -1, int tot = N) {
  for (int u : g[v]) {
    if (u != p && sz[u] * 2 > tot) {
      return find_centroid(u, v);
    }
  }
  return v;
}
vector<int> subtree;
void dfs(int v = 0, int p = -1) {
  subtree.push_back(v);
  for (int u : g[v]) {
    if (u ^ p) dfs(u, v);
  }
}
void solve(int v) {
  vector<vector<int>> nodes;
  for (int u : g[v]) {
    dfs(u, v);
    nodes.push_back(subtree);
    subtree.clear();
  }
  priority_queue<pair<int, int>, vector<pair<int, int>>> pq;
  for (int i = (0); i < (((int)(nodes).size())); i++) {
    pq.push({((int)(nodes[i]).size()), i});
  }
  while (!pq.empty()) {
    auto [sz1, i1] = pq.top();
    pq.pop();
    int a = nodes[i1].back();
    nodes[i1].pop_back();
    if (pq.empty()) {
      swap(pos[a], pos[v]);
      break;
    }
    auto [sz2, i2] = pq.top();
    pq.pop();
    int b = nodes[i2].back();
    nodes[i2].pop_back();
    swap(pos[a], pos[b]);
    if (((int)(nodes[i1]).size())) pq.push({((int)(nodes[i1]).size()), i1});
    if (((int)(nodes[i2]).size())) pq.push({((int)(nodes[i2]).size()), i2});
  }
  if (pos[v] == v) {
    swap(pos[v], pos[g[v][0]]);
  }
}
void solve() {
  cin >> N;
  for (int i = (0); i < (N - 1); i++) {
    int u, v;
    cin >> u >> v;
    --u, --v;
    g[u].push_back(v);
    g[v].push_back(u);
  }
  getsz();
  int root = find_centroid();
  iota(pos, pos + N, 0);
  solve(root);
  cout << ans << "\n";
  for (int i = (0); i < (N); i++) cout << pos[i] + 1 << " ";
}
int main() {
  ios_base::sync_with_stdio(false), cin.tie(nullptr);
  solve();
  return 0;
}
