#include <bits/stdc++.h>
#define err(args...) {}
#ifdef DEBUG
#include "_debug.cpp"
#endif
using namespace std;
using ll = long long;
using ld = long double;
template <typename T> using lim = numeric_limits<T>;
template <typename T> istream& operator>>(istream& is, vector<T>& a) { for(T& x : a) { is >> x; } return is; }
template <bool Directed, typename TEdge, bool Index> struct graph {
    using EType = TEdge;
    vector<TEdge> edges;
    vector<vector<int>> adj;
    graph(int n) : adj(n + Index) {}
    graph(int n, int m) : graph(n) { edges.reserve(m << not Directed); }
    TEdge& operator()(int e) { return edges[e]; }
    vector<int>& operator[](int u) { return adj[u]; }
    int size() { return adj.size() - Index; }
    void add_edge(const TEdge& e) {
        adj[e.u].push_back(edges.size());
        edges.push_back(e);
        if(not Directed) {
            adj[e.v].push_back(edges.size());
            edges.push_back(e.reverse());
        }
    }
};
struct edge {
    int u, v;
    edge reverse() const { return {v, u}; }
    friend ostream& operator<<(ostream& os, const edge& e) {
        return os << "(" << e.u << ", " << e.v << ")";
    }
};
template <bool Directed, typename TEdge, bool Index>
pair<vector<int>, vector<int>> bfs(graph<Directed, TEdge, Index>& g, const vector<int>& s) {
    vector<int> d(g.adj.size(), -1), p(g.adj.size(), -1);
    queue<int> q;
    for(int u : s) {
        d[u] = 0;
        q.push(u);
    }
    while(not q.empty()) {
        int u = q.front(); q.pop();
        for(int e : g[u]) {
            if(d[g(e).v] == -1) {
                d[g(e).v] = d[g(e).u] + 1, p[g(e).v] = e;
                q.push(g(e).v);
            }
        }
    }
    return {d, p};
}
template <bool Directed, typename TEdge, bool Index>
pair<vector<int>, vector<int>> bfs(graph<Directed, TEdge, Index>& g, int s) { 
    return bfs(g, vector<int>{s});
}
template <bool Directed, typename TEdge, bool Index>
vector<int> construct_path(graph<Directed, TEdge, Index>& g, const vector<int>& parent, int t) {
    vector<int> ans = {t};
    while(parent[ans.back()] != -1) {
        ans.push_back(g(parent[ans.back()]).u);
    }
    reverse(ans.begin(), ans.end());
    return ans;
}
template <bool Index> vector<int> get_diameter(int n, graph<0, edge, Index>& g) {
    auto d = bfs(g, Index);
    auto d2 = bfs(g, max_element(d.first.begin(), d.first.end()) - d.first.begin());
    return construct_path(g, d2.second, max_element(d2.first.begin(), d2.first.end()) - d2.first.begin());
}
bool valid(int n, graph<0, edge, 1>& g, vector<int>& diameter) {
    set<int> diameter_set(diameter.begin(), diameter.end());
    bool ans = true;
    for(int u = 1; u <= n; u++) {
        ans &= diameter_set.count(u) or (g[u].size() == 1 and diameter_set.count(g(g[u][0]).v));
    }
    return ans;
}
vector<int> make_p(int n, graph<0, edge, 1>& g, int root) {
    vector<int> p, index(n + 1);
    int id = 1;
    function<void(int, int)> dfs = [&](int u, int from) {
        sort(g[u].begin(), g[u].end(), [&](int e1, int e2) {
            return g[g(e1).v].size() < g[g(e2).v].size();
        });
        for(int e : g[u]) {
            if(g(e).v != from) {
                p.push_back(index[g(e).v] = id++);
            }
        }
        p.push_back(index[u]);
        swap(p[p.size() - 2], p[p.size() - 1]);
        for(int e : g[u]) {
            if(g(e).v != from and g[g(e).v].size() > 1) {
                p.pop_back();
                dfs(g(e).v, u);
            }
        }
    };
    index[root] = id++;
    dfs(root, 0);
    return p;
}
int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    int n;
    cin >> n;
    if(n == 2) {
        cout << "1 2" << endl;
    } else {
        graph<0, edge, 1> g(n, n - 1);
        for(int i = 1; i < n; i++) {
            int u, v;
            cin >> u >> v;
            g.add_edge({u, v});
        }
        auto diameter = get_diameter(n, g);
        if(valid(n, g, diameter)) {
            vector<int> p = min(make_p(n, g, diameter[0]), make_p(n, g, diameter.back()));
            for(int u = 0; u < n; u++) {
                if(u) cout << " ";
                cout << p[u];
            }
            cout << endl;
        } else {
            cout << -1 << endl;
        }
    }
    return 0;
}


Measured memory_bytes: 20348