#include <bits/stdc++.h>
using namespace std;
struct LCA {
  int logn;
  vector<int> depth;
  vector<vector<int> > lca;
  vector<vector<int> > *edges;
  LCA(int n, vector<vector<int> > *edges) {
    logn = log(n) / log(2) + 1;
    depth.resize(n + 1, 0);
    lca.resize(n + 1, vector<int>(logn, 0));
    this->edges = edges;
    build();
  }
  void dfs(int u, int p) {
    lca[u][0] = p;
    for (int i = 1; i < logn; i++) {
      lca[u][i] = lca[lca[u][i - 1]][i - 1];
    }
    depth[u] = depth[p] + 1;
    for (auto &v : (*edges)[u]) {
      if (p != v) {
        dfs(v, u);
      }
    }
  }
  int parent(int v, int h) {
    for (int i = logn - 1; i >= 0; i--) {
      if (h & (1 << i)) {
        v = lca[v][i];
      }
    }
    return v;
  }
  int lessParent(int u, int p) { return parent(u, depth[u] - depth[p] - 1); }
  int get(int u, int v) {
    if (depth[u] > depth[v]) {
      swap(u, v);
    }
    int h = depth[v] - depth[u];
    v = parent(v, h);
    if (u == v) {
      return u;
    }
    for (int i = logn - 1; i >= 0; i--) {
      if (lca[u][i] != lca[v][i]) {
        u = lca[u][i];
        v = lca[v][i];
      }
    }
    return lca[u][0];
  }
  void build() { dfs(1, 0); }
} * lca;
struct GraphBuilder {
  enum DIRECT {
    UP = 0,
    DOWN,
  };
  int n;
  int k;
  vector<vector<int> > *e;
  vector<pair<int, int> > edges;
  set<pair<int, int> > cache;
  vector<vector<int> > addedVertices;
  vector<vector<int> > deletedVertices;
  LCA *lca;
  struct Node {
    int id;
    Node *leftChild;
    Node *rightChild;
    Node(int v, Node *l, Node *r) {
      id = v;
      leftChild = l;
      rightChild = r;
    }
  };
  vector<pair<Node *, Node *> > root;
  GraphBuilder(int m, vector<vector<int> > *e) {
    k = 2 * m - 1;
    n = 2 * m - 1;
    this->e = e;
    lca = new LCA(e->size() - 1, e);
    addedVertices.resize(e->size());
    deletedVertices.resize(e->size());
    for (int i = 0; i < m; i++) {
      for (int j = 0; j < 2; j++) {
        int u, v;
        scanf("%d %d", &u, &v);
        int p = lca->get(u, v);
        if (u != p) {
          addedVertices[u].push_back((i << 1) | j);
          deletedVertices[lca->lessParent(u, p)].push_back((i << 1) | j);
        }
        if (v != p) {
          addedVertices[v].push_back((i << 1) | j);
          deletedVertices[lca->lessParent(v, p)].push_back((i << 1) | j);
        }
      }
    }
    root.resize(e->size(), {0, 0});
    dfs(1, 0);
  }
  void dfs(int u, int p) {
    for (auto &v : (*e)[u]) {
      if (v != p) {
        dfs(v, u);
        root[u].first = merge(root[u].first, root[v].first, DOWN);
        root[u].second = merge(root[u].second, root[v].second, UP);
      }
    }
    for (auto &x : addedVertices[u]) {
      root[u].first = addVertex(0, n, root[u].first, (x ^ 1), DOWN);
      root[u].second = addVertex(0, n, root[u].second, x, UP);
    }
    for (auto &x : deletedVertices[u]) {
      root[u].first = delVertex(0, n, root[u].first, (x ^ 1), DOWN);
      root[u].second = delVertex(0, n, root[u].second, x, UP);
      if (root[u].first) {
        add(x, root[u].first->id);
      }
      if (root[u].second) {
        add(root[u].second->id, (x ^ 1));
      }
    }
  }
  void add(int u, int v) { edges.push_back({u, v}); }
  void addEdge(Node *p, int direct) {
    if (direct == DOWN) {
      if (p->leftChild) {
        add(p->id, p->leftChild->id);
      }
      if (p->rightChild) {
        add(p->id, p->rightChild->id);
      }
    } else {
      if (p->leftChild) {
        add(p->leftChild->id, p->id);
      }
      if (p->rightChild) {
        add(p->rightChild->id, p->id);
      }
    }
  }
  Node *addVertex(int l, int r, Node *p, int v, int direct) {
    if (!p) {
      p = new Node(0, 0, 0);
    }
    if (l == r) {
      return new Node(v, 0, 0);
    } else {
      int mid = (l + r) >> 1;
      Node *newNode = new Node(++k, p->leftChild, p->rightChild);
      if (v <= mid) {
        newNode->leftChild = addVertex(l, mid, p->leftChild, v, direct);
      } else {
        newNode->rightChild = addVertex(mid + 1, r, p->rightChild, v, direct);
      }
      addEdge(newNode, direct);
      return newNode;
    }
  }
  Node *delVertex(int l, int r, Node *p, int v, int direct) {
    if (l == r) {
      return 0;
    } else {
      int mid = (l + r) >> 1;
      Node *newNode = new Node(++k, p->leftChild, p->rightChild);
      if (v <= mid) {
        newNode->leftChild = delVertex(l, mid, p->leftChild, v, direct);
      } else {
        newNode->rightChild = delVertex(mid + 1, r, p->rightChild, v, direct);
      }
      if (!newNode->leftChild && !newNode->rightChild) {
        return 0;
      }
      addEdge(newNode, direct);
      return newNode;
    }
  }
  Node *merge(Node *p1, Node *p2, int direct) {
    if (!p1 || !p2) {
      return p1 ? p1 : p2;
    } else {
      Node *left = merge(p1->leftChild, p2->leftChild, direct);
      Node *right = merge(p1->rightChild, p2->rightChild, direct);
      Node *newNode = new Node(++k, left, right);
      addEdge(newNode, direct);
      return newNode;
    }
  }
};
struct SAT {
  int n;
  vector<int> st;
  vector<int> mark;
  vector<int> group;
  vector<vector<int> > edges;
  vector<vector<int> > revEdges;
  SAT(int n, vector<pair<int, int> > &e) {
    this->n = n + 1;
    mark.resize(n + 1, 0);
    group.resize(n + 1, 0);
    edges.resize(n + 1);
    revEdges.resize(n + 1);
    for (auto &p : e) {
      addEdge(p.first, p.second);
    }
  }
  void addEdge(int u, int v) {
    edges[u].push_back(v);
    revEdges[v].push_back(u);
  }
  void dfs1(int u) {
    mark[u] = 1;
    for (auto &v : edges[u]) {
      if (mark[v] == 0) {
        dfs1(v);
      }
    }
    st.push_back(u);
  }
  void dfs2(int u, int k) {
    group[u] = k;
    for (auto &v : revEdges[u]) {
      if (group[v] == 0) {
        dfs2(v, k);
      }
    }
  }
  void solve() {
    for (int i = 0; i < n; i++) {
      if (mark[i] == 0) {
        dfs1(i);
      }
    }
    int k = 0;
    for (int i = st.size() - 1; i >= 0; i--) {
      int u = st[i];
      if (group[u] == 0) {
        k++;
        dfs2(u, k);
      }
    }
  }
  void answer(int m) {
    for (int i = 0; i < 2 * m; i += 2) {
      if (group[i] == group[i | 1]) {
        printf("NO");
        return;
      }
    }
    printf("YES\n");
    for (int i = 0; i < 2 * m; i += 2) {
      printf("%d\n", (group[i] > group[i | 1]) ? 1 : 2);
    }
  }
};
int main() {
  int n;
  scanf("%d", &n);
  vector<vector<int> > edges(n + 1);
  for (int i = 1; i < n; i++) {
    int u, v;
    scanf("%d %d", &u, &v);
    edges[u].push_back(v);
    edges[v].push_back(u);
  }
  int m;
  scanf("%d", &m);
  GraphBuilder builder(m, &edges);
  SAT solver(builder.k, builder.edges);
  solver.solve();
  solver.answer(m);
}
