#include <bits/stdc++.h>
template <typename Tp>
void in(Tp &x) {
  char ch = getchar(), f = 1;
  x = 0;
  while (ch != '-' && (ch < '0' || ch > '9')) ch = getchar();
  if (ch == '-') f = -1, ch = getchar();
  while (ch >= '0' && ch <= '9') x = x * 10 + ch - '0', ch = getchar();
  x *= f;
}
template <typename Tp>
bool chkmax(Tp &x, Tp y) {
  return x > y ? 0 : (x = y, 1);
}
template <typename Tp>
bool chkmin(Tp &x, Tp y) {
  return x < y ? 0 : (x = y, 1);
}
template <typename Tp>
Tp Max(Tp x, Tp y) {
  return x > y ? x : y;
}
template <typename Tp>
Tp Min(Tp x, Tp y) {
  return x < y ? x : y;
}
const long long MAXN = 100010;
long long BLOCK;
bool vis[MAXN];
long long n, type[MAXN], val[MAXN], all[MAXN], pos[MAXN << 1];
long long st[MAXN], ed[MAXN], fa[MAXN][20], depth[MAXN], tot, q, to[MAXN];
long long f[2][MAXN], ans[MAXN];
long long head[MAXN], data[MAXN << 1], nxt[MAXN << 1], cnt;
struct Que {
  bool is;
  long long l, r, add, id;
} qry[MAXN];
long long lca(long long x, long long y) {
  if (depth[x] < depth[y]) x ^= y ^= x ^= y;
  long long del = depth[x] - depth[y];
  for (long long i = del & -del; i; del ^= i, i = del & -del) x = fa[x][to[i]];
  if (x == y) return x;
  for (long long i = (19), i_END_ = (0); i >= i_END_; i--)
    if (fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];
  return fa[x][0];
}
void dfs(long long now, long long pa) {
  depth[now] = depth[pa] + 1;
  fa[now][0] = pa;
  for (long long i = 1; fa[now][i - 1]; i++)
    fa[now][i] = fa[fa[now][i - 1]][i - 1];
  st[now] = ++tot;
  pos[tot] = now;
  for (long long i = head[now]; i != -1; i = nxt[i])
    if (data[i] != pa) dfs(data[i], now);
  ed[now] = ++tot;
  pos[tot] = now;
}
bool cmp(Que &x, Que &y) {
  return (x.l / BLOCK < y.l / BLOCK) || x.l / BLOCK == y.l / BLOCK && x.r < y.r;
}
long long nowans;
void adds(long long x) {
  if (vis[pos[x]]) {
    vis[pos[x]] = false;
    nowans -= f[type[pos[x]] ^ 1][val[pos[x]]];
    f[type[pos[x]]][val[pos[x]]]--;
  } else {
    vis[pos[x]] = true;
    nowans += f[type[pos[x]] ^ 1][val[pos[x]]];
    f[type[pos[x]]][val[pos[x]]]++;
  }
}
void remove(long long x) {
  if (vis[pos[x]]) {
    vis[pos[x]] = false;
    nowans -= f[type[pos[x]] ^ 1][val[pos[x]]];
    f[type[pos[x]]][val[pos[x]]]--;
  } else {
    vis[pos[x]] = true;
    nowans += f[type[pos[x]] ^ 1][val[pos[x]]];
    f[type[pos[x]]][val[pos[x]]]++;
  }
}
void add(long long x, long long y) {
  nxt[cnt] = head[x];
  data[cnt] = y;
  head[x] = cnt++;
  nxt[cnt] = head[y];
  data[cnt] = x;
  head[y] = cnt++;
}
int main() {
  in(n);
  memset(head, -1, sizeof head);
  for (long long i = (1), i_END_ = (n); i <= i_END_; i++) in(type[i]);
  for (long long i = (1), i_END_ = (n); i <= i_END_; i++)
    in(val[i]), all[i] = val[i];
  for (long long i = (1), i_END_ = (n - 1); i <= i_END_; i++) {
    long long x, y;
    in(x);
    in(y);
    add(x, y);
  }
  std::sort(all + 1, all + n + 1);
  all[0] = std::unique(all + 1, all + n + 1) - all - 1;
  for (long long i = (1), i_END_ = (n); i <= i_END_; i++)
    val[i] = std::lower_bound(all + 1, all + all[0] + 1, val[i]) - all;
  dfs(1, 0);
  for (long long i = 1, tmp = 0; i <= n; i <<= 1, tmp++) to[i] = tmp;
  int alltot = 0;
  in(q);
  for (long long i = (1), i_END_ = (q); i <= i_END_; i++) {
    long long x, y;
    in(x);
    in(y);
    ++alltot;
    long long anc = lca(x, y);
    qry[alltot].id = i;
    if (anc == x || anc == y) {
      qry[alltot].is = false;
      long long t = anc == x ? y : x;
      qry[alltot].l = ed[t], qry[alltot].r = ed[anc];
    } else {
      if (ed[x] < st[y])
        qry[alltot].l = ed[x], qry[alltot].r = st[y];
      else
        qry[alltot].l = ed[y], qry[alltot].r = st[x];
      qry[alltot].is = true;
      qry[alltot].add = anc;
    }
  }
  BLOCK = sqrt(2 * n);
  std::sort(qry + 1, qry + alltot + 1, cmp);
  for (long long i = (qry[1].l), i_END_ = (qry[1].r); i <= i_END_; i++) adds(i);
  ans[qry[1].id] = nowans;
  if (qry[1].is) ans[qry[1].id] += f[type[qry[1].add] ^ 1][val[qry[1].add]];
  long long nowl = qry[1].l, nowr = qry[1].r;
  for (long long i = (2), i_END_ = (alltot); i <= i_END_; i++) {
    while (nowr < qry[i].r) adds(++nowr);
    while (nowl > qry[i].l) adds(--nowl);
    while (nowl < qry[i].l) remove(nowl++);
    while (nowr > qry[i].r) remove(nowr--);
    ans[qry[i].id] = nowans;
    if (qry[i].is) ans[qry[i].id] += f[type[qry[i].add] ^ 1][val[qry[i].add]];
  }
  for (long long i = (1), i_END_ = (q); i <= i_END_; i++)
    printf("%lld\n", ans[i]);
  return 0;
}
