#include <bits/stdc++.h>
using namespace std;
#define rep(i,n) for (int i = 0; i < int(n); i++)
#define rep1(i,n) for (int i = 1; i <= int(n); i++)
#define repR(i,n) for (int i = int(n)-1; i >= 0; i--)
#define rep1R(i,n) for (int i = int(n); i >= 1; i--)
#define all(x) (x).begin(), (x).end()
#define pb push_back
#define eb emplace_back
#define mp make_pair
#define fst first
#define snd second
#define cauto const auto
#ifdef LOCAL
#define dump(...) cerr << "[" << __LINE__ << ":" << __FUNCTION__ << "] ", _dmp_(#__VA_ARGS__, __VA_ARGS__);
void _dmp_(const char*) { cerr << endl; }
template <class T, class... U>
void _dmp_(const char *s, T const& x, U const& ...y) { const char *o = "({[", *e = "]})"; for (int i = 0; *s != '\0'; cerr << *s++) { if (count(o,o+3,*s)) i++; if (count(e,e+3,*s)) i--; if (!i && *s == ',') break; } cerr << " = " << x; if (*s == ',') cerr << ", ", s++; _dmp_(s, y...); }
#else
#define dump(...)
#endif
using ll = long long;
#define int ll
template <class T> using pque_max = priority_queue<T>;
template <class T> using pque_min = priority_queue<T, vector<T>, greater<T> >;
#define CONAINER_OUTPUT os << "{"; for (auto const& x : v) os << " " << x; return os << " }";
template <class T> ostream& operator<<(ostream& os, vector<T> const& v) { CONAINER_OUTPUT }
template <class T> ostream& operator<<(ostream& os, deque<T> const& v) { CONAINER_OUTPUT }
template <class T> ostream& operator<<(ostream& os, set<T> const& v) { CONAINER_OUTPUT }
template <class T, class U> ostream& operator<<(ostream& os, map<T,U> const& v) { CONAINER_OUTPUT }
#undef CONAINER_OUTPUT
template <class T> istream& operator>>(istream& is, vector<T>& v) { for (auto& x : v) is >> x; return is; }
template <class T, class S> ostream& operator<<(ostream& os, pair<T,S> const& p) { return os << "(" << p.first << ", " << p.second << ")"; }
template <class T, class S> istream& operator>>(istream& is, pair<T,S> const& p) { return is >> p.first >> p.second; }
struct _Init_ { _Init_() { cin.tie(nullptr); ios::sync_with_stdio(false); cout << fixed << setprecision(20); } } _init_;

template <class T> void quit(T const& x) { cout << x << endl; exit(0); }
template <class T> bool chmin(T& x, T const& y) { if (x > y) { x = y; return true; } return false; }
template <class T> bool chmax(T& x, T const& y) { if (x < y) { x = y; return true; } return false; }
template <class It> auto sumof(It b, It e) { return accumulate(b,e,typename iterator_traits<It>::value_type{}); }
#define YesNo(c) ((c) ? "Yes" : "No")
////////////////////////////////
int n,k;
vector<vector<int> > g;
vector<int> used;
vector<pair<int,int> > pa;
vector<int> val;
const pair<int,int> def(-1e9,-1e9);

using P = pair<int,int>;

P merge(P p, P q) {
    if (p > q) swap(p,q);
    if (p == def) return q;
    if ((p.fst-q.fst)&1) quit("No");
    int a = max(p.fst,q.fst);
    int b = min(p.snd,q.snd);
    if (a > b) quit("No");
    return {a,b};
}

void dfs1(int v) {
    used[v] = 1;
    for (int y : g[v]) {
        if (used[y]) continue;
        dfs1(y);
        auto p = pa[y];
        pa[v] = merge(pa[v], p == def ? def : mp(p.fst-1,p.snd+1));
    }
}

void dfs2(int v) {
    used[v] = 1;
    assert(pa[v] != def);
    val[v] = pa[v].snd;
    for (int y : g[v]) {
        if (used[y]) continue;
        pa[y] = merge(pa[y], mp(val[v]-1,val[v]+1));
        dfs2(y);
    }
}

int32_t main() {
    cin >> n;
    g.resize(n); used.resize(n); val.resize(n); pa.assign(n,def);
    rep (i,n-1) {
        int a,b; cin >> a >> b; a--,b--;
        g[a].push_back(b);
        g[b].push_back(a);
    }
    cin >> k;
    rep (i,k) {
        int v,p; cin >> v >> p; v--;
        pa[v] = mp(p,p);
    }
    used.assign(n,0); dfs1(0);
    used.assign(n,0); dfs2(0);
    cout << "Yes\n";
    rep (i,n) cout << val[i] << "\n";    
}


Measured memory_bytes: 14208