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 Rust (1.15.1) (judge verdict: Accepted)

// https://atcoder.jp/contests/arc095/tasks/arc095_d
//
#![allow(unused_imports)]
use std::io::*;
use std::fmt::*;
use std::str::*;
use std::cmp::*;
use std::collections::*;

macro_rules! input {
    (source = $s:expr, $($r:tt)*) => {
        let mut iter = $s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
    ($($r:tt)*) => {
        let s = {
            use std::io::Read;
            let mut s = String::new();
            std::io::stdin().read_to_string(&mut s).unwrap();
            s
        };
        let mut iter = s.split_whitespace();
        input_inner!{iter, $($r)*}
    };
}

macro_rules! input_inner {
    ($iter:expr) => {};
    ($iter:expr, ) => {};

    ($iter:expr, $var:ident : $t:tt $($r:tt)*) => {
        let $var = read_value!($iter, $t);
        input_inner!{$iter $($r)*}
    };
}

macro_rules! read_value {
    ($iter:expr, ( $($t:tt),* )) => {
        ( $(read_value!($iter, $t)),* )
    };

    ($iter:expr, [ $t:tt ; $len:expr ]) => {
        (0..$len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
    };

    ($iter:expr, [ next / $t:tt ]) => {
        {
            let len = read_value!($iter, usize);
            (0..len).map(|_| read_value!($iter, $t)).collect::<Vec<_>>()
        }
    };

    ($iter:expr, chars) => {
        read_value!($iter, String).chars().collect::<Vec<char>>()
    };

    ($iter:expr, usize1) => {
        read_value!($iter, usize) - 1
    };

    ($iter:expr, $t:ty) => {
        $iter.next().unwrap().parse::<$t>().expect("Parse error")
    };
}

#[allow(unused_macros)]
macro_rules! dvec {
    ($t:expr ; $len:expr) => {
        vec![$t; $len]
    };

    ($t:expr ; $len:expr, $($rest:expr),*) => {
        vec![dvec!($t; $($rest),*); $len]
    };
}

#[allow(unused_macros)]
macro_rules! ifv {
    ($t:expr, $a:expr, $b: expr) => {
        if $t { $a } else { $b }
    }
}

#[allow(unused_macros)]
macro_rules! fill {
    ($t:expr, $v:expr) => {
        for i in 0..$t.len() {
            $t[i] = $v;
        }
    };
}

#[allow(unused_macros)]
macro_rules! join {
    ($t:expr, $glue:expr) => {
        $t.into_iter().map(|w| w.to_string()).collect::<Vec<_>>().join($glue)
    };
}

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        println!(concat!($(stringify!($a), " = {:?}, "),*), $($a),*);
    }
}

type Graph = Vec<Vec<usize>>;

fn find_pair(g: &Graph) -> (usize, usize) {
    let (u, _) = dfs(0, None, g);
    let (v, _) = dfs(u, None, g);
    (u, v)
}

fn dfs(now: usize, par: Option<usize>, g: &Graph) -> (usize, i32) {
    let mut best = (now, 0);
    for &to in &g[now] {
        if Some(to) == par {
            continue;
        }
        let (r, t) = dfs(to, Some(now), g);
        if best.1 < t+1 {
            best = (r, t+1);
        }
    }
    best
}

fn dfsp(now: usize, par: Option<usize>, g: &Graph, parent: &mut Vec<Option<usize>>) {
    parent[now] = par;
    for &to in &g[now] {
        if Some(to) == par {
            continue;
        }
        dfsp(to, Some(now), g, parent);
    }
}

fn make(line: Vec<usize>, g: &Graph) -> Vec<usize> {
    let ln = line.len();
    let n = g.len();
    let mut w = vec![];
    let mut now = 1;
    for i in 0..ln {
        if 1 <= i && i <= ln-2 {
            let child = g[line[i]].len()-2;
            for c in 1..child+1 {
                w.push(now+c);
            }
            w.push(now);
            now += 1;
            now += child;
        } else {
            w.push(now);
            now += 1;
            assert!(g[line[i]].len() == 1);
        }
    }
    w
}


fn main() {
    input! {
        n: usize,
        edges: [(usize1, usize1); n-1]
    };

    let mut g = vec![vec![]; n];
    for (u, v) in edges {
        g[u].push(v);
        g[v].push(u);
    }
    let (mut f, mut t) = find_pair(&g);
    let mut parent = vec![None; n];
    dfsp(f, None, &g, &mut parent);

    let mut line = vec![];
    {
        let mut now = t;
        while let Some(p) = parent[now] {
            line.push(now);
            now = p;
        }
        line.push(f);
    }
    line.reverse();
    let ln = line.len();


    {
        let mut mark = vec![false; n];
        for i in 0..ln {
            let v = line[i];
            for &to in &g[v] {
                mark[to] = true;
            }
            mark[v] = true;
        }
        let mut ok = true;
        for i in 0..n {
            if !mark[i] {
                ok = false;
                break;
            }
        }
        if !ok {
            println!("-1");
            return;
        }
    }

    let w0 = make(line.clone(), &g);
    line.reverse();
    let w1 = make(line, &g);

    println!("{}", join!(min(w0, w1), " "));
}