// 解き直し.
// https://img.atcoder.jp/data/arc/063/editorial.pdf
#include <bits/stdc++.h>
using namespace std;
using vvi = vector<vector<int>>;
using P = pair<int, int>;
#define repex(i, a, b, c) for(int i = a; i < b; i += c)
#define repx(i, a, b) repex(i, a, b, 1)
#define rep(i, n) repx(i, 0, n)
#define repr(i, a, b) for(int i = a; i >= b; i--)
#define pb push_back
#define a first
#define b second
const int LIMIT = 101010;
int d[LIMIT];   // 根 からの 距離 を 保存.
int p[LIMIT];   // 頂点に書き込んだ整数(0以上).
int l[LIMIT];   // 頂点に書き込める最小値.
int r[LIMIT];   // 頂点に書き込める最大値.
int ans[LIMIT]; // 頂点に書き込み整数.

// グラフを幅優先探索する.
// https://ja.wikipedia.org/wiki/幅優先探索
// ※bfsの動作確認用.
// @param G: グラフ.
// @param s: グラフの探索開始頂点.
// @param d: 探索開始地点からの距離.
// @return: 特に無し.
void bfs(vvi &G, int s, int* d){
    // 1. 空のキュー.
    queue<int> q;
    
    // 2. 訪問済みフラグ設定.
    // ※スタート地点は, 距離ゼロを指定.
    d[s] = 0;
    
    // 3. 探索地点 s をキュー q に追加.
    q.push(s);
    while(!q.empty()){
        // 4. キューから取り出す.
        int u = q.front();
        q.pop();
        
        // 5. 取り出した要素を処理.
        for(auto &e : G[u]){
            // 6. 訪問済であれば, 処理をスキップ.
            if(d[e])            continue;
            if(!d[e] && e != s) d[e] = d[u] + 1, q.push(e);
        }
    }
    return;
}

int main(){
    
    // 1. 入力情報.
    int N;
    scanf("%d", &N);
    vvi G(N);
    rep(i, N - 1){
        int a, b;
        scanf("%d %d", &a, &b);
        a--, b--;
        G[a].pb(b);
        G[b].pb(a);
    }
    int K, root = -1;
    scanf("%d", &K);
    rep(i, LIMIT) p[i] = -1;
    rep(i, K){
        int a, b;
        scanf("%d %d", &a, &b);
        a--;
        p[a] = b;
        if(root == -1) root = a; // 根を取得.
    }
    assert(root != -1);
    
    // 2. 区間初期化.
    rep(i, N) l[i] = -1010101010, r[i] = 1010101010;
    rep(i, N) if(p[i] != -1) l[i] = p[i], r[i] = p[i];
    
    // 3. 根 から 各頂点までの距離を計算.
    bfs(G, root, d);
    // rep(i, N) printf("%d ", d[i]);
    // puts("");
    
    // 4. 偶奇の制約を満たすか確認.
    int sign = p[root] & 1;
    bool f = true;
    rep(i, N){
        // すでに書き込みある頂点で確認.
        if(p[i] != -1){
            // 根 からの 距離の偶奇で分岐.
            if(d[i] & 1){
                // 根からの距離が, 奇数の場合に, 根に書かれた整数の偶奇と同じ場合.
                if((p[i] & 1) == sign){
                    f = false;
                    break;
                }
            }else{
                // 根からの距離が, 偶数の場合に, 根に書かれた整数の偶奇と異なる場合.
                if((p[i] & 1) != sign){
                    f = false;
                    break;
                }
            }
        }
    }
    if(!f){
        puts("No");
        return 0;
    }
    
    // 5. 根 から 遠い順, 近い順 に並び替え.
    // {距離, 頂点番号}
    priority_queue<P> fPq;
    priority_queue<P, vector<P>, greater<P>> nPq;
    rep(i, N){
        // {距離, 頂点番号}
        fPq.push({d[i], i});
        nPq.push({d[i], i});
    }
    
    // 6. 区間更新.
    while(!fPq.empty()){
        // 6-1. 頂点 v を一つ取り出す.
        P x = fPq.top();
        fPq.pop();
        
        // 6-2. 頂点 v の 頂点番号は？
        int v = x.b;
        
        // 6-4. 頂点 v の 親頂点 の 区間 を 更新.
        for(auto &u : G[v]){
            // 頂点 v の 親頂点 u を 選択.
            if(d[u] < d[v]){
                // 区間を更新.
                l[u] = max(l[u], l[v] - 1);
                r[u] = min(r[u], r[v] + 1);
            }
        }
    }
    // rep(i, N) printf("%d %d %d\n", i, l[i], r[i]);
    
    // 7. 根の区間を確認.
    if(l[root] > r[root]){
        puts("No");
        return 0;
    }
    
    // 8. 各頂点に書き出す整数を保存.
    while(!nPq.empty() && f){
        // 8-1. 頂点 v を一つ取り出す.
        P x = nPq.top();
        nPq.pop();
        
        // 8-2. 頂点 v の 頂点番号は？
        int v = x.b;
        
        // random2_05.txt, random2_06.txt で WA版だったため, ロジック追加.
        // 8-3. 頂点 v の 区間 を確認.
        if(l[v] > r[v]){
            // random2_05.txt の 場合は, 以下のケースで, 成立しない区間 を 確認できた.
            // l[58966]=499995 r[58966]=499993
            // printf("l[%d]=%d r[%d]=%d\n", v, l[v], v, r[v]);
            f = false;
            break;
        }
        
        // 8-4. 頂点 v の 値 を 設定.
        if(p[v] != -1) ans[v] = p[v];
        
        // 8-5. 頂点 v の 親頂点 の 区間 から, 子頂点 に 書き込む値を絞り込む.
        if(p[v] == -1){
            int pVal = 1010101010;
            for(auto &u : G[v]){
                // 頂点 v の 親頂点 u の 整数 を 保存(※親頂点は, 一つの筈).
                if(d[u] < d[v]){
                    pVal = ans[u];
                    break;
                }
            }
            assert(pVal != 1010101010);
            
            // 区間と照合して, 条件に合うものを設定.
            // なければ, false.
            int pLVal = pVal - 1;
            int pRVal = pVal + 1;
            if(pLVal >= l[v] && pLVal <= r[v])      ans[v] = pLVal;
            else if(pRVal >= l[v] && pRVal <= r[v]) ans[v] = pRVal;
            else                                    f = false;
        }
    }
    
    // 9. 出力.
    if(f){
        puts("Yes");
        rep(i, N) printf("%d\n", ans[i]);
    }else{
        puts("No");
    }
    return 0;
    
}

Measured memory_bytes: 12960