#include <bits/stdc++.h>
using namespace std;

#define all(x) (x).begin(), (x).end()
using lli = long long int;
template <typename T = int>
struct Segment {
  T l, r;
  Segment() : Segment(0, -1) {}
  Segment(const T& l, const T& r) : l(l), r(r) {}
  lli len() const { return r - l + 1; }
  bool valid() const { return r >= l; }
  bool In(const T& v) { return l <= v && v <= r; }
  Segment<T> Intersect(const Segment<T> other) const {
    return {max(l, other.l), min(r, other.r)};
  }
  void IntersectInPlace(const Segment<T> other) {
    l = max(l, other.l);
    r = min(r, other.r);
  }
};
struct Edge {
  int from;
  int to;
  int cost;
  int idx;

  Edge() {}
  Edge(int f, int t) : Edge(f, t, 1, -1) {}
  Edge(int f, int t, int c, int i) : from(f), to(t), cost(c), idx(i) {}

  inline int next(int v) const { return v ^ from ^ to; }
};

struct Graph {
  Graph() {}
  Graph(const vector<vector<Edge>>& g) : g(g) {}
  Graph(int n, const vector<Edge>& edges, bool unordered = true) : g(n) {
    for (const auto& e : edges) {
      g[e.from].push_back(e);
      if (unordered) {
        g[e.to].push_back(e);
      }
    }
  }

  inline int N() const { return g.size(); }

  vector<vector<Edge>> g;
};
vector<Edge> ReadEdges(int m, bool weighted = false) {
  vector<Edge> edges(m);
  for (int i = 0; i < m; ++i) {
    auto& e = edges[i];
    cin >> e.from >> e.to;
    e.idx = i;
    e.cost = 1;
    --e.from;
    --e.to;
    if (weighted) cin >> e.cost;
  }
  return edges;
}
struct Tree : public Graph {
  Tree() : Graph() {}
  Tree(const vector<vector<Edge>>& g) : Graph(g) {}
  Tree(int n, const vector<Edge>& edges, bool unordered = true)
      : Graph(n, edges, unordered) {}

  void dfs(int v, int parent, int d) {
    depth[v] = d;
    parents[v][0] = parent;
    tin[v] = time_++;
    for (int i = 1; i < L_; ++i) {
      parents[v][i] = parents[parents[v][i - 1]][i - 1];
    }
    for (const auto& e : g[v]) {
      if (e.next(v) == parent) continue;
      dfs(e.next(v), v, d + 1);
    }
    tout[v] = time_++;
  }

  void PrebuildLCA(int root) {
    if (!parents.empty()) return;
    while ((1 << L_) <= 2 * N()) ++L_;
    parents = vector<vector<int>>(N(), vector<int>(L_, root));
    depth.resize(N());
    tin.resize(N());
    tout.resize(N());
    dfs(root, root, 0);
  }

  bool IsParent(int a, int b) { return tin[a] <= tin[b] && tout[a] >= tout[b]; }

  int LCA(int a, int b) {
    if (IsParent(a, b)) return a;
    if (IsParent(b, a)) return b;
    for (int l = L_ - 1; l >= 0; --l) {
      if (!IsParent(parents[a][l], b)) {
        a = parents[a][l];
      }
    }
    return parents[a][0];
  }

  int Distance(int a, int b) {
    PrebuildLCA(0);
    int p = LCA(a, b);
    return depth[a] + depth[b] - 2 * depth[p];
  }

  int L_ = 1, time_ = 1;
  vector<int> depth, tin, tout;
  vector<vector<int>> parents;
};
Tree* ReadTree(bool unordered = true, bool weighted = false) {
  int n;
  cin >> n;
  return new Tree(n, ReadEdges(n - 1, weighted), unordered);
}

constexpr int DEFAULT = numeric_limits<int>::min() / 2;
using ST = Segment<int>;
Tree* g;
vector<int> values;
vector<bool> odd;
vector<ST> range;

bool fill(int v, int p) {
  if (p == -1) {
    odd[v] = values[v] & 1;
  } else {
    odd[v] = !odd[p];
  }
  if (values[v] != DEFAULT && ((values[v] & 1) != odd[v])) return false;
  for (const auto& e : g->g[v]) {
    int to = e.next(v);
    if (to == p) continue;
    if (!fill(to, v)) return false;
  }
  return true;
}

ST dfs(int v, int p) {
  if (values[v] != DEFAULT) {
    range[v] = {values[v], values[v]};
    return {values[v] - 1, values[v] + 1};
  }
  for (const auto& e : g->g[v]) {
    int to = e.next(v);
    if (to == p) continue;
    range[v].IntersectInPlace(dfs(to, v));
  }
  return range[v].valid() ? ST{range[v].l - 1, range[v].r + 1} : range[v];
}

void smear(int v, int p) {
  if (values[v] != DEFAULT) return;
  if (p == -1) {
    values[v] = range[v].l + ((range[v].l & 1) != odd[v]);
  } else if (range[v].In(values[p] - 1)) {
    values[v] = values[p] - 1;
  } else {
    values[v] = values[p] + 1;
  }
  for (const auto& e : g->g[v]) {
    int to = e.next(v);
    if (to == p) continue;
    smear(to, v);
  }
}

bool check(int v, int p) {
  bool ok = 1;
  for (const auto& e : g->g[v]) {
    int to = e.next(v);
    if (to == p) continue;
    ok &= (values[v] + 1 == values[to] || values[v] - 1 == values[to]) && check(to, v);
  }
  return ok;
}

int main() {
  ios_base::sync_with_stdio(false);
  g = ReadTree();
  int n = g->N();
  odd.resize(n, false);
  values.resize(n, DEFAULT);
  range.resize(n, ST{numeric_limits<int>::min() / 2, numeric_limits<int>::max() / 2});
  int m;
  cin >> m;
  while(m--) {
    int v, a;
    cin >> v >> a;
    values[v - 1] = a;
  }
  for (int i = 0; i < n; ++i) if (values[i] != DEFAULT) {
    if (!fill(i, -1)) {
      cout << "No";
      return 0;
    }
    break;
  }
  for (int i = 0; i < n; ++i) {
    if (values[i] == DEFAULT) {
      dfs(i, -1);
      if (!range[i].valid()) {
        cout << "No";
        return 0;
      }
      smear(i, -1);
    }
  }
  if (!check(0, -1)) {
    cout << "No";
    return 0;
  }
  cout << "Yes" << endl;
  for (auto& v : values) cout << v << '\n';
  return 0;
}

Measured memory_bytes: 16996