#include <bits/stdc++.h>

#ifdef DEBUG
#include <Mylib/Debug/debug.cpp>
#else
#define dump(...)
#endif

/**
 * @title Graph template
 * @docs graph_template.md
 */
template <typename Cost = int> class Edge{
public:
  int from,to;
  Cost cost;
  Edge() {}
  Edge(int to, Cost cost): to(to), cost(cost){}
  Edge(int from, int to, Cost cost): from(from), to(to), cost(cost){}
};

template <typename T> using Graph = std::vector<std::vector<Edge<T>>>;
template <typename T> using Tree = std::vector<std::vector<Edge<T>>>;

template <typename T, typename C> void add_edge(C &g, int from, int to, T w = 1){
  g[from].emplace_back(from, to, w);
}

template <typename T, typename C> void add_undirected(C &g, int a, int b, T w = 1){
  add_edge<T, C>(g, a, b, w);
  add_edge<T, C>(g, b, a, w);
}

/**
 * @title Rooting
 * @docs rooting.md
 */
template <typename T>
void rooting(Tree<T> &tree, int cur, int par = -1){
  if(par != -1){
    for(auto it = tree[cur].begin(); it != tree[cur].end(); ++it){
      if(it->to == par){
        tree[cur].erase(it);
        break;
      }
    }
  }

  for(auto &e : tree[cur]){
    rooting(tree, e.to, cur);
  }
}



/**
 * @title Fixed point combinator
 * @docs fix_point.md
 */
template <typename F>
struct FixPoint : F{
  explicit constexpr FixPoint(F &&f) noexcept : F(std::forward<F>(f)){}

  template <typename... Args>
  constexpr auto operator()(Args &&... args) const {
    return F::operator()(*this, std::forward<Args>(args)...);
  }
};

template <typename F>
inline constexpr auto make_fix_point(F &&f){
  return FixPoint<F>(std::forward<F>(f));
}

template <typename F>
inline constexpr auto make_fix_point(F &f){
  return FixPoint<F>(std::forward<F>(f));
}





template <typename T>
struct Range{
  using opt = std::optional<T>;
  std::optional<std::pair<opt, opt>> value;

  Range(){}
  Range(opt l, opt r): value(std::make_pair(l, r)){}

  friend std::ostream& operator<<(std::ostream &s, const Range<T> &a){
    s << "[";
    if(a.value){
      if((a.value)->first) s << *((a.value)->first);
      else s << "-∞ ";
      s << ",";
      if((a.value)->second) s << *((a.value)->second);
      else s << "∞ ";
    }
    s << "]";
    return s;
  }

  bool is_null() const {
    return not value;
  }

  bool contains(T v) const {
    if(not value) return false;
    if(value->first and v < *(value->first)) return false;
    if(value->second and v > *(value->second)) return false;
    
    return true;
  }
};

template <typename T>
auto intersect(Range<T> a, Range<T> b){
  if(not a.value or not b.value) return Range<T>();
  std::optional<T> l, r;

  if((a.value)->first){
    l = *((a.value)->first);
  }

  if((b.value)->first){
    if(l) l = std::max(*l, *((b.value)->first));
    else l = *((b.value)->first);
  }

  if((a.value)->second){
    r = *((a.value)->second);
  }

  if((b.value)->second){
    if(r) r = std::min(*r, *((b.value)->second));
    else r = *((b.value)->second);
  }
  
  if(l and r){
    if(*l > *r){
      return Range<T>();
    }
  }

  return Range<T>(l, r);
}

template <typename T>
auto left_expand(Range<T> a, T x){
  if(a.value and (a.value)->first){
    *((a.value)->first) += x;
    if((a.value)->second and *((a.value)->first) > *((a.value)->second)){
      return Range<T>();
    }
  }
  
  return a;
}

template <typename T>
auto right_expand(Range<T> a, T x){
  if(a.value and (a.value)->second){
    *((a.value)->second) += x;
    if((a.value)->first and *((a.value)->first) > *((a.value)->second)){
      return Range<T>();
    }
  }
  
  return a;
}














void solve(){
  int N; std::cin >> N;

  Tree<int> tree(N);
  for(int i = 0; i < N-1; ++i){
    int a, b; std::cin >> a >> b;
    --a, --b;
    add_undirected(tree, a, b, 1);
  }


  int K; std::cin >> K;

  std::vector<int> P(N, -1);

  int root = 0;

  for(int i = 0; i < K; ++i){
    int v, p; std::cin >> v >> p;
    --v;
    P[v] = p;
    root = v;
  }

  rooting(tree, root);

  auto check =
    make_fix_point(
      [&](auto &&f, int cur, std::optional<std::pair<int, int>> p) -> bool {
        if(p and P[cur] != -1){
          int d = std::abs(P[cur] - (*p).first);
          if((*p).second < d or (*p).second % 2 != d % 2){
            return false;
          }
        }

        for(auto &e : tree[cur]){
          auto q = p;

          if(P[cur] != -1){
            q = {P[cur], 0};
          }

          if(q){
            (*q).second += 1;
          }
          
          if(not f(e.to, q)){
            return false;
          }
        }

        return true;
      }
    );

  if(not check(root, std::nullopt)){
    std::cout << "No" << "\n";
    return;
  }


  auto ar = Range<int>({}, {});
  std::vector<Range<int>> ranges(N, ar);

  auto rec =
    make_fix_point(
      [&](auto &&f, int cur) -> void {
        if(P[cur] != -1){
          ranges[cur] = Range<int>(P[cur], P[cur]);
        }

        for(auto &e : tree[cur]){
          f(e.to);
          auto r = left_expand(right_expand(ranges[e.to], 1), -1);
          ranges[cur] = intersect(ranges[cur], r);
        }
      }
    );

  rec(root);
  dump(ranges);

  for(auto r : ranges){
    if(r.is_null()){
      std::cout << "No" << "\n";
      return;
    }
  }

  std::vector<int> ans(N);

  auto f =
    make_fix_point(
      [&](auto &&f, int cur, int v) -> void {
        ans[cur] = v;

        for(auto &e : tree[cur]){
          if(ranges[e.to].contains(v - 1)){
            f(e.to, v - 1);
          }else{
            f(e.to, v + 1);
          }
        }
      }
    );

  f(root, (ranges[root].value)->first.value());

  std::cout << "Yes" << "\n";
  for(auto x : ans){
    std::cout << x << "\n";
  }
}




int main(){
  solve();

  return 0;
}


Measured memory_bytes: 26908