#include <iostream>
#include <algorithm>
#include <vector>
#include <queue>
#include <string>

#define amax(a, b) a = max(a, b)
#define amin(a, b) a = min(a, b)

using ll = long long;

using P = std::pair<int, bool>;
#define fi first
#define se second

struct floor {
    int id;
    bool used;
    bool in;
    bool has_tui;
};

int main() {
    int n;
    std::cin >> n;
    std::vector<floor> status(2*n, floor{-1, false, false, false});
    for (int i=0, ai, bi; i<n; i++) {
        std::cin >> ai >> bi;
        if (ai >= bi && bi > 0) {
            std::cout << "No" << '\n';
            return 0;
        }
        if (ai > 0) {
            if (status[ai-1].used) {
                std::cout << "No" << '\n';
                return 0;
            }
            status[ai-1] = floor{i, true, true, bi > 0};
        }
        if (bi > 0) {
            if (status[bi-1].used) {
                std::cout << "No" << '\n';
                return 0;
            }
            status[bi-1] = floor{i, true, false, ai > 0};
        }
    }
    std::vector<bool> dp(n+1, false);
    dp[0] = true;
    for (int i=1; i<=n; i++) {
        for (int j=0; j<i; j++) {
            if (!dp[j]) continue;
            int w = i - j;
            dp[i] = true;
            for (int k=0; k<w; k++) {
                if ((status[j*2+k].used && status[j*2+w+k].used && status[j*2+k].id == status[j*2+w+k].id)
                        || ( status[j*2+k].used && !status[j*2+w+k].used && !status[j*2+k].has_tui)
                        || (!status[j*2+k].used &&  status[j*2+w+k].used && !status[j*2+w+k].has_tui)
                        || (!status[j*2+k].used && !status[j*2+w+k].used)) {
                    continue;
                }
                dp[i] = false;
                break;
            }
            if (dp[i]) break;
        }
    }
    std::cout << (dp[n] ? "Yes" : "No") << '\n';
    return 0;
}
#include <bits/stdc++.h>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define chmin(x,y) x = min((x),(y))
#define chmax(x,y) x = max((x),(y))
#define popcount(x) __builtin_popcount(x)
using namespace std;
using ll = long long ;
using P = pair<int,int> ;
using pll = pair<long long,long long>;
const int INF = 1e9;
const long long LINF = 1e17;
const int MOD = 1000000007;
//const int MOD = 998244353;
const double PI = 3.14159265358979323846;

int main(){
    int n;
    cin >> n;
    vector<vector<int>> tree(n);
    rep(i,n-1){
        int a,b;
        cin >> a >> b;
        --a;--b;
        tree[a].push_back(b);
        tree[b].push_back(a);
    }
    auto longest = [&](auto&& longest,int i,int p) -> P {
        P res = {i,0};
        for(int j:tree[i]){
            if(j == p) continue;
            P tmp = longest(longest,j,i);
            tmp.second ++;
            if(tmp.second > res.second){
                res = tmp;
            }
        }
        return res;
    };
    auto s = longest(longest,0,-1);
    auto t = longest(longest,s.first,-1);

    vector<ll> e(n);
    int c = 1;
    vector<int> to_s(n,-1);
    auto tos = [&](auto&& tos,int i,int p) -> bool {
        if(to_s[i] != -1) return to_s[i] == 1;
        to_s[i] = (i == s.first ? 1 : 0); // false
        for(int j:tree[i]){
            if(j == p) continue;
            if(tos(tos,j,i)) to_s[i] = 1; // true
        }
        return to_s[i] == 1;
    };
    auto dfs = [&](auto&& dfs,int i,int p) -> void {
        e[i] = c;
        c++;
        int ind = -1;
        for(int j:tree[i]){
            if(j == p) continue;
            if(tos(tos,j,i)){
                ind = j;
                continue;
            }
            dfs(dfs,j,i);
            c++;
        }
        if(ind >= 0){
            dfs(dfs,ind,i);
            c++;
        }
        return;
    };
    dfs(dfs,t.first,-1);
    rep(i,n) cout << e[i] << " ";
    cout <<  endl;
    return 0;
}