#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <cmath>
#include <complex>
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional>
#include <iomanip>
#include <locale>
#include <iostream>
#include <map>
#include <memory>
#include <new>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <sstream>
#include <string>
#include <tuple>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>

#define REP(i,n) for(int i=0;i<(int)(n);i++)
#define ALL(x) (x).begin(),(x).end()

using namespace std;

using ll = long long;
using ld = long double;

template <typename T> T &chmin(T &a, const T &b) { return a = min(a, b); }
template <typename T> T &chmax(T &a, const T &b) { return a = max(a, b); }
template <typename T> int len(const T &x) { return x.size(); }

template<typename T>
vector<T> table(int n, T v) { return vector<T>(n, v); }

template <class... Args>
auto table(int n, Args... args) {
  auto val = table(args...);
  return vector<decltype(val)>(n, move(val));
}

struct yes_no : numpunct<char> {
  string_type do_truename()  const { return "Yes"; }
  string_type do_falsename() const { return "No"; }
};

using Graph = vector<vector<int>>;

void bfs01(Graph &g, vector<int> &d, int s) {
  using Weight = int;
  const int INF = 1e9;
  d.assign(g.size(), INF);
  d[s] = 0;
  using P = pair<Weight,int>;
  deque<P> que;
  que.push_back(P(0, s));
  while (!que.empty()) {
    P top = que.front(); que.pop_front();
    Weight dist = top.first; int v = top.second;
    if (d[v] < dist) continue;
    REP(i, g[v].size()) {
      int e = g[v][i];
      if (d[e] > d[v] + 1) {
        d[e] = d[v] + 1;
        que.push_back(P(d[e], e));
      }
    }
  }
}

bool visited[100100];

vector<int> vec;

bool dfs(const Graph &g, int v) {
  // cout << v << endl;
  visited[v] = true;
  vector<int> x, y;
  for (int w: g[v]) {
    if (visited[w]) continue;
    if (g[w].size() == 1) x.push_back(w);
    else y.push_back(w);
  }
  if (y.size() > 1) return false;
  const int n = vec.size();
  if (y.empty()) {
    REP(i,x.size()-1) vec.push_back(vec.size() + 1);
    vec.push_back(n);
    vec.push_back(vec.size());
    return true;
  }
  else {
    for (int w: x) {
      visited[w] = true;
      vec.push_back(vec.size() + 1);
    }
    vec.push_back(n);
    for (int w: y) {
      return dfs(g, w);
    }
  }
  return true;
}

void solve(ll n, vector<ll> v, vector<ll> w) {
  Graph g(n);
  REP(i,n-1) {
    int s = v[i] - 1, t = w[i] - 1;
    g[s].push_back(t);
    g[t].push_back(s);
  }
  vector<int> d1, d2;
  bfs01(g, d1, 0);
  const int v1 = max_element(ALL(d1)) - begin(d1);
  bfs01(g, d2, v1);
  const int v2 = max_element(ALL(d2)) - begin(d2);
  bool res = dfs(g, v1);
  vector<int> vec1 = (res ? vec : vector<int>(1, 999999999));
  vec.clear();
  memset(visited, 0, sizeof(visited));
  res = dfs(g, v2);
  vector<int> vec2 = (res ? vec : vector<int>(1, 999999999));
  if (vec2 < vec1) vec1 = vec2;
  if (vec1[0] == 999999999) cout << -1 << endl;
  else {
    REP(i,n) cout << vec1[i] + 1 << " \n"[i == n - 1];
  }
}

int main() {
  locale loc(locale(), new yes_no);
  cout << boolalpha << setprecision(12) << fixed;
  cout.imbue(loc);
	ll n;
	scanf("%lld", &n);
	vector<ll> v((n-1)-1+1);
	vector<ll> w((n-1)-1+1);
	for (int i = 0 ; i <= (n-1)-1 ; i++) {
	  scanf("%lld", &v[i]);
	  scanf("%lld", &w[i]);
	}
	solve(n, v, w);
	return 0;
}


Measured memory_bytes: 26744