#include <bits/stdc++.h>
using namespace std;
int block_Sz, m, n, res;
int ar[100007];
int br[100007];
long long ans[100007];
int ur[300007];
int cnt[300007];
int st[100007];
int ed[100007];
int lev[100007];
int id[2 * 100007];
int par[20][100007];
vector<int> adj[100007];
int tim;
void dfs(int u, int papa) {
  st[u] = ++tim;
  id[tim] = u;
  for (int i = 1; i < 20; i++) par[i][u] = par[i - 1][par[i - 1][u]];
  for (int i = 0; i < adj[u].size(); i++) {
    int v = adj[u][i];
    if (papa != v) {
      lev[v] = lev[u] + 1;
      par[0][v] = u;
      dfs(v, u);
    }
  }
  ed[u] = ++tim;
  id[tim] = u;
}
int find_lca(int u, int v) {
  if (lev[u] > lev[v]) swap(u, v);
  int df = lev[v] - lev[u];
  for (int i = 20 - 1; i >= 0; i--)
    if ((df & (1 << i))) v = par[i][v];
  if (u == v) return u;
  for (int i = 20 - 1; i >= 0; i--) {
    if (par[i][u] != par[i][v]) {
      u = par[i][u];
      v = par[i][v];
    }
  }
  return par[0][u];
}
int flag[300007];
int boy[300007];
long long ret;
long long ache[2][300007];
void adjust(int u) {
  int val = ar[u];
  int bb = boy[u];
  if (flag[u] == 0) {
    ret += ache[bb ^ 1][val];
    ache[bb][val]++;
  } else {
    ret -= ache[bb ^ 1][val];
    ache[bb][val]--;
  }
  flag[u] ^= 1;
}
struct QUERY {
  int x, y, z;
  int u, v;
  int id;
  int lca;
  bool flag;
  bool operator<(const QUERY& p) const {
    int x1 = (x - 1) / block_Sz + 1;
    int x2 = (p.x - 1) / block_Sz + 1;
    int y1 = ceil(1.0 * y / block_Sz);
    int y2 = ceil(1.0 * p.y / block_Sz);
    return (x1 < x2 || (x1 == x2 && y1 < y2) ||
            (x1 == x2 && y1 == y2 && z < p.z) ||
            (x1 == x2 && y1 == y2 && z == p.z && y < p.y));
  }
} block[100007];
void init(int n) {
  block_Sz = pow(n, 1.0 / 3.0);
  block_Sz *= block_Sz;
  for (int i = 1; i <= n; i++) adj[i].clear();
  tim = 0;
  res = 0;
  ret = 0;
  memset(par, 0, sizeof par);
  memset(flag, 0, sizeof flag);
}
int main() {
  int n;
  scanf("%d", &(n));
  ;
  init(n);
  int sz = 0;
  for (int i = 1; i <= n; i++) {
    scanf("%d", &(boy[i]));
  }
  for (int i = 1; i <= n; i++) {
    scanf("%d", &(ar[i]));
    ur[++sz] = ar[i];
    br[i] = ar[i];
  }
  for (int i = 1; i <= n - 1; i++) {
    int u, v;
    scanf("%d%d", &(u), &(v));
    adj[u].push_back(v);
    adj[v].push_back(u);
  }
  char ss[13];
  int len1 = 0;
  int len2 = 0;
  dfs(1, 0);
  int q;
  scanf("%d", &(q));
  ;
  for (int i = 1; i <= q; i++) {
    len2++;
    int u, v;
    scanf("%d%d", &(u), &(v));
    if (lev[u] > lev[v]) swap(u, v);
    block[len2].u = u;
    block[len2].v = v;
    block[len2].lca = find_lca(u, v);
    if (block[i].lca == u) {
      block[len2].x = st[u];
      block[len2].y = st[v];
      block[len2].flag = 0;
    } else {
      block[len2].x = ed[u];
      block[len2].y = st[v];
      block[len2].flag = 1;
    }
    block[len2].z = len1;
    block[len2].id = len2;
  }
  sort(ur + 1, ur + 1 + sz);
  for (int i = 1; i <= n; i++)
    ar[i] = lower_bound(ur + 1, ur + 1 + n, ar[i]) - ur;
  sort(block + 1, block + 1 + len2);
  int l = block[1].x;
  int r = l - 1;
  for (int i = 1; i <= len2; i++) {
    for (int j = r + 1; j <= block[i].y; j++) adjust(id[j]);
    for (int j = l - 1; j >= block[i].x; j--) adjust(id[j]);
    for (int j = r; j >= block[i].y + 1; j--) adjust(id[j]);
    for (int j = l; j <= block[i].x - 1; j++) adjust(id[j]);
    if (block[i].flag) {
      adjust(block[i].lca);
    }
    ans[block[i].id] = ret;
    if (block[i].flag) {
      adjust(block[i].lca);
    }
    l = block[i].x;
    r = block[i].y;
  }
  for (int i = 1; i <= len2; i++) printf("%lld\n", ans[i]);
  return 0;
}
