#include<iostream>
#include<algorithm>
#include<vector>
using namespace std;


int64_t N;
int64_t K;
vector<int64_t> G[100000];
int64_t P[100000];
const int64_t INF = 1e9+1;
vector<int64_t> v[100000];

vector<int64_t> solv1(int64_t a,int64_t b){//頂点a について(b->aという向き) bのありうるパターンについて返す
    bool flag=true;//目的の木を作れるかどうか判定
    vector<int64_t> ret;
    if(b != -1 && G[a].size()==1){//葉の時
        if(P[a]!=INF){
            v[a].push_back(P[a]);
            ret.push_back(P[a]-1);
            ret.push_back(P[a]+1);
        }
    }else{
        for(int i=0;i<G[a].size();i++){
            if(G[a][i]!=b){
                vector<int64_t> tmp = solv1(G[a][i],a);//葉について先に処理する。
                if(tmp.size()!=0 && tmp[0]==INF){
                    flag=false;
                }else{
                    if(tmp.size()!=0){//葉に値の決まっている頂点があった時
                        if(P[a]!=INF){
                            int64_t x = P[a]-tmp[0];
                            int64_t y = P[a]-tmp[1];
                            if(x%2 != 0 || y%2 != 0){
                                flag=false;
                            }
                        }
                        if(v[a].size()==0){
                            v[a]=tmp;
                        }else{
                            sort(v[a].begin(),v[a].end());
                            sort(tmp.begin(),tmp.end());
                            if(tmp[1]<v[a][0] || v[a][1]<tmp[0]){
                                flag=false;
                            }else{
                                v[a][0]=max(tmp[0],v[a][0]);
                                v[a][1]=min(tmp[1],v[a][1]);
                            }
                        }
                    }
                }
            }
        }//これでv[a]がもとまった。次に、returnの処理をする。
        if(flag){
            if(P[a]!=INF){
                if(v[a].size()!=0){
                    if(P[a]<v[a][0] || P[a]>v[a][1]){
                        flag=false;
                    }else{
                        v[a].clear();
                        v[a].push_back(P[a]);
                        ret.push_back(P[a]-1);
                        ret.push_back(P[a]+1);
                    }
                }else{
                    v[a].push_back(P[a]);
                    ret.push_back(P[a]-1);
                    ret.push_back(P[a]+1);
                }
            }else{
                if(v[a].size()!=0){
                    ret.push_back(v[a][0]-1);
                    ret.push_back(v[a][1]+1);
                }
            }
        }
        if(!flag){
            ret.push_back(INF);
            ret.push_back(INF);
        }
    }
    return ret;
}
void solv2(int64_t a,int64_t c,int64_t b){//b->aへcがきた。(P[b]=c)
    if(b==-1){
        P[a]=v[a][0];
        for(int i=0;i<G[a].size();i++){
            solv2(G[a][i],P[a],a);
        }
    }else{
        if(P[a]==INF){
            if(v[a].size()==0){
                P[a]=c-1;
            }else if(v[a].size()==1){
                P[a]=v[a][0];
            }else{
                if(v[a][0]<= c-1 && c-1<= v[a][1]){
                    P[a]=c-1;
                }
                if(v[a][0]<= c+1 && c+1 <= v[a][1]){
                    P[a]=c+1;
                }
            }
        }
        for(int i=0;i<G[a].size();i++){
            if(G[a][i]!=b){
                solv2(G[a][i],P[a],a);
            }
        }
    }
}



int main(){
    cin>>N;
    for(int i=0;i<N-1;i++){
        int64_t a,b;
        cin>>a>>b;
        a--; b--;
        G[a].push_back(b);
        G[b].push_back(a);
    }
    cin>>K;
    fill(P,P+N,INF);
    for(int i=0;i<K;i++){
        int64_t a,b;
        cin>>a>>b;
        a--;
        P[a]=b;
    }
    vector<int64_t> tmp=solv1(0,-1);
    if(tmp[0]!=INF){
        cout<<"Yes"<<endl;
        solv2(0,0,-1);
        for(int i=0;i<N;i++){
            cout<<P[i]<<endl;
        }
    }else{
        cout<<"No"<<endl;
    }
    return 0;
}


Measured memory_bytes: 25088