#include <bits/stdc++.h>
using namespace std;

using ll = long long;
using ull = unsigned long long;
using ld = long double;
#define REP(NAME, NUM) for (int NAME = 0; NAME < (NUM); ++NAME)
#define BREP(NAME, NUM) for (int NAME = (NUM)-1; NAME >= 0; --NAME)
#define VEC(TYPE, A, NAME, INIT) vector<TYPE> NAME(A, INIT)
#define VEC2(TYPE, A, B, NAME, INIT) vector<vector<TYPE>> NAME(A, vector<TYPE>(B, (INIT)))

// --------------------------------
// 標準入力から木のデータ（辺）を作る
// --------------------------------
void makeTree( vector< vector<int> >* pEdge, int nodeNum )
{
    REP(i, nodeNum - 1)
    {
        int a, b;
        cin >> a >> b;
        (*pEdge)[a-1].push_back(b-1);
        (*pEdge)[b-1].push_back(a-1);
    }
    REP( i, nodeNum )
        sort((*pEdge)[i].begin(), (*pEdge)[i].end(), less<int>());
}

// --------------------------------
// Node同士が直接辺で繋がっているかを判定する
// --------------------------------
bool isEdge(const vector<vector<int>> &edge, int nodeA, int nodeB)
{
    for( const auto& nextNodeIdx : edge[nodeA] )
    {
        if( nextNodeIdx == nodeB )
            return true;
    }
    return false;
}

// --------------------------------
// Nodeが辺を一つしか持たない葉かを判定する
// --------------------------------
int getLeaf(    const vector<vector<int>> &edge, 
                int searchStartNodeIdx,
                int nodeNum)
{
    REP( i, nodeNum )
    {
        int searchNodeIdx = (searchStartNodeIdx + i) % nodeNum;
        if (edge[searchNodeIdx].size() == 1)
            return searchNodeIdx;
    }
    return -1;
}

// --------------------------------
// 最長道を計算する
// --------------------------------
pair<int, int> visitTree_(  const vector<vector<int>> &edge,
                            int prevNodeIdx,
                            int curNodeIdx)
{
    pair<int /* Weight */, int /* LongestNodeIdx */>
        tmp(0, -1),
        max(0, curNodeIdx);
    for (const auto &nextNodeIdx : edge[curNodeIdx])
        if (nextNodeIdx != prevNodeIdx)
        {
            tmp = visitTree_(edge, curNodeIdx, nextNodeIdx);
            ++tmp.first;
            if (max.first < tmp.first)
                max = tmp;
        }
    return max;
}
bool visitTreeForRoad_( deque<int>* pRoad,
                        const vector<vector<int>> &edge,
                        int prevNodeIdx,
                        int curNodeIdx,
                        int goalNodeIdx)
{
    for (const auto &nextNodeIdx : edge[curNodeIdx])
    {
        if (nextNodeIdx != prevNodeIdx)
        {
            pRoad->push_back(nextNodeIdx);
            if( nextNodeIdx == goalNodeIdx )
                return true;
            if( visitTreeForRoad_(  pRoad, edge, 
                                    curNodeIdx, nextNodeIdx, goalNodeIdx) )
                return true;
            pRoad->pop_back();
        }
    }
    return false;
}
void calcRoad(deque<int> * pRoad,
                const vector<vector<int>> &edge,
                int nodeNum)
{
    pair<int, int> max( 0, -1 );
    max = visitTree_(edge, -1, 0);
    int startNodeIdx = max.second;
    max = visitTree_(edge, -1, startNodeIdx);
    int lastNodeIdx = max.second;

    pRoad->push_back(startNodeIdx);
    visitTreeForRoad_(  pRoad, edge, 
                        -1, startNodeIdx, lastNodeIdx);
}

// --------------------------------
// 最長道を計算する2
// Catepillarであるかの判定もしている
// --------------------------------
bool calcRoadPlus_(deque<int> * pRoad,
                    const vector<vector<int>> &edge,
                    vector<int> &isPassedNode,
                    vector<int> &curSearchNode)
{
    for (const auto &nextNodeIdx : edge[curSearchNode.back()])
    {
        if (!(isPassedNode[nextNodeIdx] == 0))
            continue;

        isPassedNode[nextNodeIdx] = 1; // searched

        curSearchNode.push_back(nextNodeIdx);

        if (curSearchNode.size() >= 3)
        {
            int newRoadNodeIdx = curSearchNode[curSearchNode.size() - 2];
            if (isPassedNode[newRoadNodeIdx] == 1)
            {
                isPassedNode[newRoadNodeIdx] = 2;
                if (pRoad->size() == 0)
                    pRoad->push_back(newRoadNodeIdx);
                else if (isEdge(edge, newRoadNodeIdx, (*pRoad).front()))
                    pRoad->push_front(newRoadNodeIdx);
                else if (isEdge(edge, newRoadNodeIdx, (*pRoad).back()))
                    pRoad->push_back(newRoadNodeIdx);
                else
                    return false;
            }
        }

        if (!calcRoadPlus_(pRoad, edge, isPassedNode, curSearchNode))
            return false;

        curSearchNode.pop_back();
    }
    return true;
}
bool calcRoadPlus(deque<int> * pRoad,
                    const vector<vector<int>> &edge,
                    int nodeNum)
{
    vector<int> isPassedNode(nodeNum, 0);
    vector<int> curSearchNode(0, 0);

    int leafIdx = getLeaf(edge, 0, nodeNum);
    isPassedNode[leafIdx] = 1;
    curSearchNode.push_back(leafIdx);

    if (!calcRoadPlus_(pRoad, edge, isPassedNode, curSearchNode))
    {
        pRoad->clear();
        return false;
    }

    if (pRoad->size() == 0)
    {
        pRoad->push_back(0);
        pRoad->push_back(edge[0][0]);
        return true;
    }

    for (const auto &nextNodeIdx : edge[pRoad->front()])
    {
        if (pRoad->size() == 1 || nextNodeIdx != pRoad->at(1))
        {
            pRoad->push_front(nextNodeIdx);
            break;
        }
    }
    for (const auto &nextNodeIdx : edge[pRoad->back()])
    {
        if (pRoad->size() == 1 || 
            nextNodeIdx != pRoad->at(pRoad->size() - 2))
        {
            pRoad->push_back(nextNodeIdx);
            break;
        }
    }
    return true;
}

void createAnswer(  vector<int>* pAnswer,
                    const deque<int> &road,
                    const vector<vector<int>> &edge)
{
    int cnt = 0;
    pAnswer->push_back( cnt + 1 );
    for (int i = 1; i < road.size(); ++i)
    {
        int cnt2 = 0;
        if (i < road.size() - 1)
        {
            for (const auto &next : edge[road[i]])
            {
                if (!(next == road[i + 1] || next == road[i - 1]))
                    ++cnt2;
            }
        }

        ++cnt;
        for (int j = cnt + 1; j <= cnt + cnt2; ++j)
        {
            pAnswer->push_back( j + 1 );
        }
        pAnswer->push_back( cnt + 1 );
        cnt += cnt2;
    }
}

int main()
{
    int n;
    cin >> n;

    VEC2(int, n, 0, edge, -1);
    makeTree(&edge, n);

    deque<int> road;
    calcRoad(&road, edge, n);
    
    bool isSuccess = true;
    REP(i, road.size())
    {
        REP( j, edge[road[i]].size() )
        {
            int edge_ = edge[road[i]][j];
            if( i > 0 && edge_ == road[i-1] ){}
            else if( i < road.size() - 1 && edge_ == road[i+1] ){}
            else
            {
                if( edge[edge_].size() >= 2 )
                {
                    isSuccess = false;
                    break;
                }
            }
        }
        if( !isSuccess )
            break;
    }

    if (!isSuccess)
        cout << "-1" << endl;
    else
    {
        vector<int> ans0, ans1;
        createAnswer(&ans0, road, edge);
        reverse(road.begin(), road.end());
        createAnswer(&ans1, road, edge);

        bool is0 = true;
        REP( i, ans0.size() )
        {
            if (ans0[i] < ans1[i])
            {
                is0 = true;
                break;
            }
            else if (ans0[i] > ans1[i])
            {
                is0 = false;
                break;
            }
        }
        if (is0)
        {
            cout << ans0[0];
            for (int i = 1; i < ans0.size(); ++i)
                cout << " " << ans0[i];
        }
        else
        {
            cout << ans1[0];
            for (int i = 1; i < ans1.size(); ++i)
                cout << " " << ans1[i];
        }
    }

    return 0;
}


Measured memory_bytes: 15480