#include <bits/stdc++.h>
using namespace std;
const int MAXN = 1e5 + 5;
const int MAXP = 22;
int n;
long long a[MAXN], b[MAXN];
vector<int> graph[MAXN];
void read_input() {
  cin >> n;
  for (int i = 1; i <= n; i++) {
    cin >> a[i];
  }
  for (int i = 1; i <= n; i++) {
    cin >> b[i];
  }
  int v, w;
  for (int i = 0; i < n - 1; i++) {
    cin >> v >> w;
    graph[v].push_back(w);
    graph[w].push_back(v);
  }
}
int par[MAXN][MAXP];
int depth[MAXN], eul[MAXN * 2], in[MAXN], out[MAXN];
int timer;
void dfs(int v, int p = 0, int dp = 1) {
  par[v][0] = p;
  for (int i = 1; i < MAXP; i++) {
    par[v][i] = par[par[v][i - 1]][i - 1];
  }
  depth[v] = dp;
  in[v] = timer;
  eul[timer++] = v;
  for (auto x : graph[v]) {
    if (x != p) {
      dfs(x, v, dp + 1);
    }
  }
  out[v] = timer;
  eul[timer++] = v;
}
int lca(int v, int w) {
  if (depth[v] < depth[w]) swap(v, w);
  for (int i = MAXP - 1; i >= 0; i--) {
    if (depth[par[v][i]] >= depth[w]) {
      v = par[v][i];
    }
  }
  if (v == w) return v;
  for (int i = MAXP - 1; i >= 0; i--) {
    if (par[v][i] != par[w][i]) {
      v = par[v][i];
      w = par[w][i];
    }
  }
  return par[v][0];
}
int LZ;
struct query {
  int l, r;
  int ind;
  query(int _l, int _r, int _ind) {
    l = _l;
    r = _r;
    ind = _ind;
  }
  bool operator<(query other) const {
    if (l / LZ == other.l / LZ)
      return ((l / LZ) & 1) ? r > other.r : r < other.r;
    return l / LZ < other.l / LZ;
  }
};
long long temp = 0;
int br[MAXN];
unordered_map<int, int> cnt[2];
void calc(int tr, int type) {
  int pol = a[tr];
  int chis = b[tr];
  br[tr] += type;
  if (br[tr] == 0 || br[tr] == 2) {
    temp -= (1LL * cnt[0][chis] * cnt[1][chis]);
    cnt[pol][chis]--;
    temp += (1LL * cnt[0][chis] * cnt[1][chis]);
  } else {
    temp -= (1LL * cnt[0][chis] * cnt[1][chis]);
    cnt[pol][chis]++;
    temp += (1LL * cnt[0][chis] * cnt[1][chis]);
  }
}
long long ans[MAXN];
int bonus[MAXN];
void solve() {
  dfs(1);
  int q;
  cin >> q;
  int ve, w;
  LZ = sqrt(timer);
  vector<query> v;
  for (int i = 0; i < q; i++) {
    cin >> ve >> w;
    int lc = lca(ve, w);
    if (lc == ve || lc == w) {
      if (in[ve] > in[w]) swap(ve, w);
      v.push_back(query(in[ve], in[w], i));
    } else {
      if (out[ve] > in[w]) swap(ve, w);
      v.push_back(query(out[ve], in[w], i));
      bonus[i] = lc;
    }
  }
  sort(v.begin(), v.end());
  int L = 0, R = -1;
  for (int i = 0; i < v.size(); i++) {
    while (R < v[i].r) {
      calc(eul[R + 1], +1);
      R++;
    }
    while (L > v[i].l) {
      calc(eul[L - 1], +1);
      L--;
    }
    while (L < v[i].l) {
      calc(eul[L], -1);
      L++;
    }
    while (R > v[i].r) {
      calc(eul[R], -1);
      R--;
    }
    if (bonus[v[i].ind]) {
      calc(eul[in[bonus[v[i].ind]]], 1);
      ans[v[i].ind] += temp;
      calc(eul[in[bonus[v[i].ind]]], -1);
    } else
      ans[v[i].ind] += temp;
  }
  for (int i = 0; i < q; i++) {
    cout << ans[i] << endl;
  }
}
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  read_input();
  solve();
  return 0;
}
