Problem:
Score : 900 points

Problem Statement

Takahashi has an ability to generate a tree using a permutation (p_1,p_2,...,p_n) of (1,2,...,n), in the following process:

First, prepare Vertex 1, Vertex 2, ..., Vertex N.
For each i=1,2,...,n, perform the following operation:

If p_i = 1, do nothing.

If p_i \neq 1, let j' be the largest j such that p_j < p_i. Span an edge between Vertex i and Vertex j'.

Takahashi is trying to make his favorite tree with this ability.
His favorite tree has n vertices from Vertex 1 through Vertex n, and its i-th edge connects Vertex v_i and w_i.
Determine if he can make a tree isomorphic to his favorite tree by using a proper permutation.
If he can do so, find the lexicographically smallest such permutation.

Notes

For the definition of isomorphism of trees, see wikipedia. Intuitively, two trees are isomorphic when they are the "same" if we disregard the indices of their vertices.

Constraints

2 \leq n \leq 10^5

1 \leq v_i, w_i \leq n

The given graph is a tree.

Input

Input is given from Standard Input in the following format:

n
v_1 w_1
v_2 w_2
:
v_{n-1} w_{n-1}

Output

If there is no permutation that can generate a tree isomorphic to Takahashi's favorite tree, print -1.
If it exists, print the lexicographically smallest such permutation, with spaces in between.

Sample Input 1

6
1 2
1 3
1 4
1 5
5 6

Sample Output 1

1 2 4 5 3 6

If the permutation (1, 2, 4, 5, 3, 6) is used to generate a tree, it looks as follows:

This is isomorphic to the given graph.

Sample Input 2

6
1 2
2 3
3 4
1 5
5 6

Sample Output 2

1 2 3 4 5 6

Sample Input 3

15
1 2
1 3
2 4
2 5
3 6
3 7
4 8
4 9
5 10
5 11
6 12
6 13
7 14
7 15

Sample Output 3

-1

Solution in C++14 (GCC 5.4.1) (judge verdict: Runtime Error)

// G++ MACRO.CPP -STD=C++17
#include <bits/stdc++.h>
typedef long long ll;
const int INF = 1e9;
const int MOD = 1e9+7;
const ll LINF = 1e18;
using namespace std;
 
#define dump(x)  cout << #x << " = " << (x) << endl;
#define YES(n) cout << ((n) ? "YES" : "NO"  ) << endl
#define Yes(n) cout << ((n) ? "Yes" : "No"  ) << endl
#define POSSIBLE(n) cout << ((n) ? "POSSIBLE" : "IMPOSSIBLE"  ) << endl
#define Possible(n) cout << ((n) ? "Possible" : "Impossible"  ) << endl
#define possible(n) cout << ((n) ? "possible" : "impossible"  ) << endl
 
#define SANKOU(n,a,b) cout << ((n) ? (#a) : (#b) ) << endl
 
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) for(int i=0;i<(n);++i)
#define REPR(i,n) for(int i=n;i>=0;i--)
 
#define FOREACH(x,a) for(auto& (x) : (a) )
 
#define WFA(d,v) REP(k,v)REP(i,v)REP(j,v)d[i][j]=min(d[i][j],d[i][k]+d[k][j])
 
#define SCOUT(x) cout<<(x)<<" "
#define ENDL cout<<endl
 
#define VECCIN(x) for(auto&youso_: (x) )cin>>youso_
#define VECIN2(x,y) REP(i,x.size())cin>>x[i]>>y[i]
#define VECCOUT(x) if(1){for(auto tt=x.begin();tt!=x.end();tt++){if(tt!=x.begin())cout<<" ";cout<<(*tt);}cout<<endl;}
 
#define ALL(obj) (obj).begin(),(obj).end()
 
#define EXIST(n,x) (find(ALL(n),x)!=n.end())
#define UNIQUE(obj) sort(ALL( obj )); obj.erase(unique(ALL(obj)),obj.end())
#define EN(x) if(1){cout<<#x<<endl;return 0;}
#define COUT(x) cout<<(x)<<endl
void CINT(){}
template <class Head,class... Tail>
void CINT(Head&& head,Tail&&... tail){
    cin>>head;
    CINT(move(tail)...);
}
#define CIN(...) int __VA_ARGS__;CINT(__VA_ARGS__)
#define LCIN(...) ll __VA_ARGS__;CINT(__VA_ARGS__)
#define SCIN(...) string __VA_ARGS__;CINT(__VA_ARGS__)
 
template <class T = ll>
T IN(){T x;cin>>x;return (x);}
 
template <class Head>
void VT(Head head){}
template <class Head,class Seco,class... Tail>
void VT(Head&& head,Seco&& seco,Tail&&... tail){
    seco.resize(head);
    VT(head,move(tail)...);
}
void VT2(){}
template <class Head,class... Tail>
void VT2(Head&& head,Tail&&... tail){
  VECCIN(head);
  VT2(move(tail)...);
}
 
template <class Head>
void VT3(Head&& head){}
template <class Head,class Seco,class... Tail>
void VT3(Head&& head,Seco&& seco,Tail&&... tail){
  seco[head]=IN();
  VT3(head,move(tail)...);
}
 
#define VC1(n,...) V __VA_ARGS__;VT(n,__VA_ARGS__);VT2(__VA_ARGS__); //aaabbbccc
#define VC2(n,...) V __VA_ARGS__;VT(n,__VA_ARGS__);REP(i,n)VT3(i,__VA_ARGS__); //abcabcabc
 
// #include <boost/multiprecision/cpp_int.hpp>
// using namespace boost::multiprecision; // cpp_int
 
#define P pair<ll,ll>
#define V vector<ll>
#define M map<ll,ll>
#define S set<ll>
 
#define pb(a) push_back(a)
#define mp make_pair
 class SegmentTree{//RMQ 最小値を出すやつ
  public:
  SegmentTree(int n,V v);
  void updateVal(int pos,int val);
  int calcVal(int st,int en);//半開区間 3,6なら3,4,5の最小値
  vector<int> elements;
  int pnum;
};

SegmentTree::SegmentTree(int n,V v){
  pnum=1;while(pnum<n)pnum*=2;
  elements=vector<int>(pnum*2-1,-MOD);
  
  REP(i,n)updateVal(i,v[i]);
}

void SegmentTree::updateVal(int pos,int val){
  function<void(int)> f = [&](int pos_l){
    elements[pos_l]=max(elements[pos_l*2+1],elements[pos_l*2+2]);
    if(pos_l)f((pos_l-1)/2);
  };
  int num = pos+pnum-1;
  elements[num]=val;
  if(num)f((num-1)/2);
}

int SegmentTree::calcVal(int st,int en){
  function<int(int,int,int,int,int)> f = [&](int st_l,int en_l,int node,int l,int r){
    if(r <= st_l || en_l <= l)return -MOD;//交差しない
    if(st_l <= l && r <= en_l)return elements[node];
    int vl = f(st_l,en_l,node*2+1,l,(l+r)/2);
    int vr = f(st_l,en_l,node*2+2,(l+r)/2,r);
    return max(vl,vr);
  };
  return f(st,en,0,0,pnum);
}


 
int main(){

  CIN(n);VC2(n-1,a,b);
  REP(i,n){a[i]--;b[i]--;}
  vector<V> edges(n);
  REP(i,n-1){edges[a[i]].pb(b[i]);edges[b[i]].pb(a[i]);}
  int root=0;
  REP(i,n)
    if(edges[i].size()==1){
      root=i;break;
    }
  
  vector<V> ed(n);
  V tai(1,root);
  function<void(int)> dfs = [&](int pos){
    FOREACH(xx,edges[pos])
      if(ed[xx].empty()){
        tai.pb(xx);
        ed[pos].pb(xx);
        dfs(xx);
      }
  };
  dfs(root);

  deque<int> ans;
  ans.pb(root);
  V flag(n,false);flag[root]=true;
  queue<int> que;
  que.push(root);

  while(!que.empty()){
    int t = que.front();que.pop();
    FOREACH(xx,ed[t]){
      if(flag[xx])continue;

      //ここに処理
      bool f = false;
      FOREACH(yy,ed[xx])
        if(!flag[yy])f=true;//未探索木があるなら
      
      if(f)
        ans.pb(xx);
      else
        ans.push_front(xx);

      que.push(xx);
    }
  }

  SegmentTree seg(n,V(n,0));
  REP(i,n)
    seg.updateVal(ans[i], i);
  FOR(i,1,n){
    int value = seg.calcVal(0,i);
    bool ff = false;
    FOREACH(xx,edges[i])
      if(xx == ans[value])ff = true;
    if(!ff)EN(-1);
  }
  VECCOUT(ans);



  return 0;
}