import java.io.*;

import java.util.*;
import java.util.Map.Entry;

import javax.swing.text.InternationalFormatter;

import java.math.*;

public class template {

	public static PrintWriter out;
	static int size = 0;
	static TreeMap<Long, Long> hm;
	static ArrayList<Integer>[] a;
	static boolean b = false;

	public static void main(String[] args) throws IOException {

		Reader scn = new Reader();

		int n = scn.nextInt(), q = scn.nextInt();

		int[] a = new int[n + 1];

		while (q-- != 0) {

			int t = scn.nextInt(), k = scn.nextInt(), d = scn.nextInt();

			int sum = 0;
			for (int i = 1; i <= n && k > 0; i++) {

				if (t >= a[i]) {
					a[i] = t + d;
					k--;
					sum += i;
				}
			}

			if (k == 0)
				System.out.println(sum);
			else
				System.out.println(-1);

		}

	}

	// _________________________TEMPLATE_____________________________________________________________

	// private static int gcd(int a, int b) {
	// if(a== 0)
	// return b;
	//
	// return gcd(b%a,a);
	// }

	// static class comp implements Comparator<pair> {
	//
	// @Override
	// public int compare(pair o1, pair o2) {
	// return o2.b - o1.b;
	// }
	//
	// }

	static class pair implements Comparable<pair> {
		int o = Integer.MAX_VALUE;
		int e = Integer.MAX_VALUE;

		// pair(int a, int b) {
		// min = a;
		// max = b;
		// }

		@Override
		public int compareTo(pair o) {

			return (int) (this.o - o.o);

		}
	}

	public static class Reader {
		final private int BUFFER_SIZE = 1 << 16;
		private DataInputStream din;
		private byte[] buffer;
		private int bufferPointer, bytesRead;

		public Reader() {
			din = new DataInputStream(System.in);
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public Reader(String file_name) throws IOException {
			din = new DataInputStream(new FileInputStream(file_name));
			buffer = new byte[BUFFER_SIZE];
			bufferPointer = bytesRead = 0;
		}

		public String readLine() throws IOException {
			byte[] buf = new byte[100000 + 1]; // line length
			int cnt = 0, c;
			while ((c = read()) != -1) {
				if (c == '\n')
					break;
				buf[cnt++] = (byte) c;
			}
			return new String(buf, 0, cnt);
		}

		public int nextInt() throws IOException {
			int ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (neg)
				return -ret;
			return ret;
		}

		public long nextLong() throws IOException {
			long ret = 0;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();
			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');
			if (neg)
				return -ret;
			return ret;
		}

		public double nextDouble() throws IOException {
			double ret = 0, div = 1;
			byte c = read();
			while (c <= ' ')
				c = read();
			boolean neg = (c == '-');
			if (neg)
				c = read();

			do {
				ret = ret * 10 + c - '0';
			} while ((c = read()) >= '0' && c <= '9');

			if (c == '.') {
				while ((c = read()) >= '0' && c <= '9') {
					ret += (c - '0') / (div *= 10);
				}
			}

			if (neg)
				return -ret;
			return ret;
		}

		private void fillBuffer() throws IOException {
			bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
			if (bytesRead == -1)
				buffer[0] = -1;
		}

		private byte read() throws IOException {
			if (bufferPointer == bytesRead)
				fillBuffer();
			return buffer[bufferPointer++];
		}

		public void close() throws IOException {
			if (din == null)
				return;
			din.close();
		}

		public int[] nextIntArray(int n) throws IOException {
			int[] arr = new int[n];
			for (int i = 0; i < n; i++) {
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n) throws IOException {
			long[] arr = new long[n];
			for (int i = 0; i < n; i++) {
				arr[i] = nextLong();
			}
			return arr;
		}

		public int[][] nextInt2DArray(int m, int n) throws IOException {
			int[][] arr = new int[m][n];
			for (int i = 0; i < m; i++) {
				for (int j = 0; j < n; j++)
					arr[i][j] = nextInt();
			}
			return arr;
		}

	}

}


import java.util.*;
import java.io.*;

public class Main {

  public static void main(String[] args) throws Exception {
    Scanner in = new Scanner(System.in);
    PrintWriter out = new PrintWriter(System.out);

    int n = in.nextInt();
    int q = in.nextInt();

    int servers[] = new int[128];

    for (int i = 0; i < q; ++i) {
      int t = in.nextInt();
      int k = in.nextInt();
      int d = in.nextInt();

      int free = 0;
      for (int j = 1; j <= n; ++j)
        free += (t >= servers[j]) ? 1 : 0;

      int sum = 0;
      if (free >= k)
        for (int j = 1; k > 0 && j <= n; ++j)
          if (t >= servers[j] && k-- > 0) {
            servers[j] = t + d;
            sum += j;
          }

      out.println(k <= 0 ? sum : -1);
    }
    out.flush();
  }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Servers {
	static class Task implements Comparable<Task> {
		int t, k, d;
		Task(int a, int b, int c) {
			t = a; k = b; d = c;
		}
		@Override
		public int compareTo(Task tk) {
			return t - tk.t;
		}
	}
	public static void main(String[] args) throws NumberFormatException, IOException {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int q = sc.nextInt();

		int free[] = new int[n];
		Arrays.fill(free, 1);
		Task[] tk = new Task[q];
		for(int i = 0; i < q; i++) {
			tk[i] = new Task(sc.nextInt(), sc.nextInt(), sc.nextInt());
		}

		Arrays.sort(tk);

		PrintWriter out = new PrintWriter(System.out);

		for(int i = 0; i < q; i++) {
			ArrayList<Integer> servers = new ArrayList<Integer>();
			for(int j = 0; j < n; j++) {
				if(free[j] <= tk[i].t)
					servers.add(j + 1);
				if(servers.size() == tk[i].k)
					break;
			}

			if(servers.size() < tk[i].k)
				out.println(-1);
			else {
				for(int s : servers)
					free[s - 1] = tk[i].t + tk[i].d;
				out.println(sum(servers));
			}
		}
		out.flush();
		out.close();
	}
	private static int sum(ArrayList<Integer> a) {
		int sum = 0;
		for(int x : a)
			sum += x;
		return sum;
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(FileReader f) {
			br = new BufferedReader(f);
		}

		public boolean ready() throws IOException {
			return br.ready();
		}

		Scanner(InputStream s) {
			br = new BufferedReader(new InputStreamReader(s));
		}

		String next() throws IOException {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		String nextLine() throws IOException {
			return br.readLine();
		}

		int nextInt() throws NumberFormatException, IOException {
			return Integer.parseInt(next());
		}

		long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
	}
}


import java.io.*;
import java.util.*;
public class C747 {

	public static void main(String[] args) throws Exception{
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(f.readLine());

		int n = Integer.parseInt(st.nextToken());
		int q = Integer.parseInt(st.nextToken());

		int[][] qs = new int[q][3];
		long[] free = new long[n];

		for(int i = 0;i<q;i++){
			st = new StringTokenizer(f.readLine());
			qs[i][0] = Integer.parseInt(st.nextToken());
			qs[i][1] = Integer.parseInt(st.nextToken());
			qs[i][2] = Integer.parseInt(st.nextToken());
		}

		for(int i = 0;i<q;i++){
			int counter = 0;
			int sum = 0;
			for(int j = 0;j<n;j++){
				if(free[j]<=qs[i][0]){
					counter++;
					sum += j+1;
					free[j] = qs[i][0] + qs[i][2];
				}
				if(counter == qs[i][1]) break;
			}
			if(counter < qs[i][1]) System.out.println(-1);
			else System.out.println(sum);
		}
	}

}


import java.io.*;
import java.util.*;
public class C747 {

	public static void main(String[] args) throws Exception{
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(f.readLine());

		int n = Integer.parseInt(st.nextToken());
		int q = Integer.parseInt(st.nextToken());

		int[][] qs = new int[q][3];
		int[] free = new int[n];

		for(int i = 0;i<q;i++){
			st = new StringTokenizer(f.readLine());
			qs[i][0] = Integer.parseInt(st.nextToken());
			qs[i][1] = Integer.parseInt(st.nextToken());
			qs[i][2] = Integer.parseInt(st.nextToken());
		}

		Arrays.fill(free, 1);

		for(int i = 0;i<q;i++){
			int counter = 0;
			int sum = 0;
			for(int j = 0;j<n;j++){
				if(free[j]<=qs[i][0]){
					counter++;
					sum += j+1;
					free[j] = qs[i][0] + qs[i][2];
				}
				if(counter == qs[i][1]) break;
			}
			if(counter < qs[i][1]) System.out.println(-1);
			else System.out.println(sum);
		}
	}

}


import java.io.*;
import java.util.*;
public class C747 {

	public static void main(String[] args) throws Exception{
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(f.readLine());

		int n = Integer.parseInt(st.nextToken());
		int q = Integer.parseInt(st.nextToken());

		int[][] qs = new int[q][3];
		long[] free = new long[n];

		for(int i = 0;i<q;i++){
			st = new StringTokenizer(f.readLine());
			qs[i][0] = Integer.parseInt(st.nextToken());
			qs[i][1] = Integer.parseInt(st.nextToken());
			qs[i][2] = Integer.parseInt(st.nextToken());
		}

		Arrays.fill(free, 1);

		for(int i = 0;i<q;i++){
			int counter = 0;
			int sum = 0;
			for(int j = 0;j<n;j++){
				if(free[j]<=qs[i][0]){
					counter++;
					sum += j+1;
					free[j] = qs[i][0] + qs[i][2];
				}
				if(counter == qs[i][1]) break;
			}
			if(counter < qs[i][1]) System.out.println(-1);
			else System.out.println(sum);
		}
	}

}


import java.io.*;
import java.util.*;
public class C747 {

	public static void main(String[] args) throws Exception{
		BufferedReader f = new BufferedReader(new InputStreamReader(System.in));

		StringTokenizer st = new StringTokenizer(f.readLine());

		int n = Integer.parseInt(st.nextToken());
		int q = Integer.parseInt(st.nextToken());

		int[][] qs = new int[q][3];
		long[] free = new long[n];

		for(int i = 0;i<q;i++){
			st = new StringTokenizer(f.readLine());
			qs[i][0] = Integer.parseInt(st.nextToken());
			qs[i][1] = Integer.parseInt(st.nextToken());
			qs[i][2] = Integer.parseInt(st.nextToken());
		}

		for(int i = 0;i<q;i++){
			int counter = 0;
			int sum = 0;
			for(int j = 0;j<n;j++){
				if(free[j]<=qs[i][0]){
					counter++;
				}
				if(counter == qs[i][1]) break;
			}
			if(counter < qs[i][1]){
				System.out.println(-1);
				continue;
			}
			counter = 0;
			for(int j = 0;j<n;j++){
				if(free[j]<=qs[i][0]){
					sum += j+1;
					free[j] = qs[i][0] + qs[i][2];
					counter ++;
				}
				if(counter == qs[i][1]) break;
			}
			System.out.println(sum);
		}
	}

}


import java.io.*;
import java.util.*;

public class C
{

	static StringBuilder st = new StringBuilder();

	public static void main(String[] args) throws Exception {

		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt();
		int q = sc.nextInt();

		PriorityQueue<Integer> pq = new PriorityQueue<>();

		PriorityQueue<Interval> interval = new PriorityQueue<>() ;

		for(int i = 1 ; i<= n ; i++)pq.add(i);

		int [] ans = new int [q] ;
		for(int i = 0 ; i < q ; i++)
		{
			int t = sc.nextInt() , k = sc.nextInt() , d = sc.nextInt() ;

			Interval f = new Interval(t, 1 , i , k);
			Interval s = new Interval(t + d, -1 , i , k);
			f.taken = s.taken ;
			interval.add(f);
			interval.add(s);

		}

		while(!interval.isEmpty())
		{
			Interval curr = interval.poll();
			if(curr.type == 1)
			{
				if(curr.servers > pq.size())
					ans[curr.q_num] = -1 ;
				else
				{
					int sum = 0 ;

					while(curr.servers -->0)
					{
						int x = pq.poll() ;
						sum += x ;
						curr.add(x);
					}
					ans[curr.q_num] = sum ;
				}
			}
			else
			{
				for(int x : curr.taken)
					pq.add(x);
			}

		}

		for(int x : ans)
			out.println(x);

		out.flush();
		out.close();

	}

	static class Interval implements Comparable<Interval>
	{
		int time , type ;
		ArrayList<Integer> taken ;
		int q_num , servers;
		public Interval(int a , int b , int num , int s)
		{
			time = a ; type = b ;
			taken = new ArrayList<>() ;
			q_num = num ;
			servers = s ;

		}
		void add(int x)
		{
			taken.add(x);
		}
		@Override
		public int compareTo(Interval o)
		{
			return time != o.time ? time - o.time : type - o.type;
		}
	}

	static class Scanner {
		BufferedReader br;
		StringTokenizer st;

		Scanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() throws Exception {
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		int nextInt() throws Exception {
			return Integer.parseInt(next());
		}

		long nextLong() throws Exception {
			return Long.parseLong(next());
		}

		double nextDouble() throws Exception {
			return Double.parseDouble(next());
		}

	}

	static void shuffle(int[] a) {
		int n = a.length;
		for (int i = 0; i < n; i++) {
			int r = i + (int) (Math.random() * (n - i));
			int tmp = a[i];
			a[i] = a[r];
			a[r] = tmp;
		}
	}

}


#include <algorithm>
#include <iostream>
#include <cassert>
#include <iomanip>
#include <string>
#include <vector>
#include <stack>
#include <queue>
#include <cmath>
#include <map>
#include <set>
using namespace std;
#define x first
#define y second
typedef long long lli;
const int maxn = 1e5 + 5;
const int K = 320;
const int logn = 21;
int n, q;
int x[maxn], y[maxn];
int a[maxn], f[maxn];
vector<int> g[maxn], v;

int dep[maxn];
int Time = 0;
int in[maxn], out[maxn];
int arr[maxn * 2], p[maxn][logn];

int cnt[maxn][2], vis[maxn];
lli cur = 0;
lli ans[maxn];

struct data
{
    int l, r, id, lab;

    bool operator <(const data&other) const
    {
        if(l / K == other.l / K)
            return r < other.r;
        return l / K < other.l / K;
    }
} query[maxn];

void ReadInput()
{
    cin >> n;
    for(int i = 1; i <= n; ++i)
        cin >> a[i];
    v.resize(n);
    for(int i = 1; i <= n; ++i)
    {
        cin >> f[i];
        v[i - 1] = f[i];
    }
    for(int i = 1; i < n; ++i)
    {
        int x, y;
        cin >> x >> y;
        g[x].push_back(y);
        g[y].push_back(x);
    }
}

void dfs(int u, int par)
{
    in[u] = ++Time;
    arr[Time] = u;
    dep[u] = dep[par] + 1;
    p[u][0] = par;
    for(int k = 1; k < logn; ++k)
        p[u][k] = p[p[u][k - 1]][k - 1];
    for(int v: g[u])
        if(v != par)
            dfs(v, u);
    out[u] = ++Time;
    arr[Time] = u;
}

void Init()
{
    sort(v.begin(), v.end());
    v.resize(unique(v.begin(), v.end()) - v.begin());
    for(int i = 1; i <= n; ++i)
        f[i] = lower_bound(v.begin(), v.end(), f[i]) - v.begin();

    Time = 0;
    dep[0] = 0;
    dfs(1, 0);

    cin >> q;
    for(int i = 1; i <= q; ++i)
    {
        int x, y;
        cin >> x >> y;
        if(in[x] > in[y]) swap(x, y);
        if(out[x] < in[y]) query[i] = {out[x], in[y], i, 1};
        else query[i] = {in[x], in[y], i, 0};
    }
    sort(query + 1, query + 1 + q);
}

inline void add(int l, int r, int k)
{
    for(int i = l; i <= r; ++i)
    {
        int u = arr[i];
        vis[u] += k;
        if(vis[u] == 1 || vis[u] == k + 1)
        {
            cur -= 1LL * cnt[f[u]][0] * cnt[f[u]][1];
            cnt[f[u]][a[u]] += vis[u] == 1 ? 1 : -1;
            cur += 1LL * cnt[f[u]][0] * cnt[f[u]][1];
        }
    }
}

int LCA(int u, int v)
{
    if(dep[u] < dep[v]) swap(u, v);

    for(int k = logn - 1; k >= 0; --k)
        if(dep[p[u][k]] >= dep[v])
            u = p[u][k];
    if(u == v) return u;
    for(int k = logn - 1; k >= 0; --k)
        if(p[u][k] != p[v][k])
        {
            u = p[u][k];
            v = p[v][k];
        }
    return p[u][0];
}

void Solve()
{
    fill(begin(vis), end(vis), 0);
    fill_n(&cnt[0][0], sizeof(cnt) / sizeof(cnt[0][0]), 0);
    add(query[1].l, query[1].r, 1);
    cerr << query[1].l << ' ' << query[1].r << '\n';
    int par = LCA(arr[query[1].l], arr[query[1].r]);
    ans[query[1].id] = cur + (query[1].lab ? (a[par] ? cnt[f[par]][0] : cnt[f[par]][1]) : 0);

    for(int i = 2; i <= q; ++i)
    {
        if(query[i].r > query[i - 1].r)
            add(query[i - 1].r + 1, query[i].r, 1);
        else add(query[i].r + 1, query[i - 1].r, -1);

        if(query[i].l < query[i - 1].l)
            add(query[i].l, query[i - 1].l - 1, 1);
        else add(query[i - 1].l, query[i].l - 1, -1);

        int par = LCA(arr[query[i].l], arr[query[i].r]);
        ans[query[i].id] = cur + (query[i].lab ? (a[par] ? cnt[f[par]][0] : cnt[f[par]][1]) : 0);
    }

    for(int i = 1; i <= q; ++i)
        cout << ans[i] << '\n';
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    ReadInput();
    Init();
    Solve();
}


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

const int MAXN = 200005;
const int MAXM = 200005;
const int LN = 20;

int N, M, K, cur, A[MAXN], LVL[MAXN], DP[LN][MAXN];
int BL[MAXN << 1], ID[MAXN << 1], VAL[2][MAXN];
long long ANS[MAXM];
int d[MAXN], l[MAXN], r[MAXN];
bool VIS[MAXN];
int type[MAXN];
vector < int > adjList[MAXN];

struct query{
    int id, l, r, lc;
    inline friend bool operator < (query lhs, query rhs){
        return (BL[lhs.l] == BL[rhs.l]) ? (lhs.r < rhs.r) : (BL[lhs.l] < BL[rhs.l]);
    }
}Q[MAXM];

void dfs(int u, int par){
    l[u] = ++cur;
    ID[cur] = u;
    for (int i = 1; i < LN; i++) DP[i][u] = DP[i - 1][DP[i - 1][u]];
    for (int i = 0; i < adjList[u].size(); i++){
        int v = adjList[u][i];
        if (v == par) continue;
        LVL[v] = LVL[u] + 1;
        DP[0][v] = u;
        dfs(v, u);
    }
    r[u] = ++cur; ID[cur] = u;
}

inline int lca(int u, int v){
    if (LVL[u] > LVL[v]) swap(u, v);
    for (int i = LN - 1; i >= 0; i--)
        if (LVL[v] - (1 << i) >= LVL[u]) v = DP[i][v];
    if (u == v) return u;
    for (int i = LN - 1; i >= 0; i--){
        if (DP[i][u] != DP[i][v]){
            u = DP[i][u];
            v = DP[i][v];
        }
    }
    return DP[0][u];
}

inline void check(int x, long long& res){
    // If (x) occurs twice, then don't consider it's value
    if (VIS[x]) {
        res -= VAL[type[x] ^ 1][A[x]];
        VAL[type[x]][A[x]]--;
    } else {
        res += VAL[type[x] ^ 1][A[x]];
        VAL[type[x]][A[x]]++;
    }
    VIS[x] ^= 1;
}

void compute(){

    int curL = Q[0].l, curR = Q[0].l - 1;
    long long res = 0;

    for (int i = 0; i < M; i++){

        while (curL < Q[i].l) check(ID[curL++], res);
        while (curL > Q[i].l) check(ID[--curL], res);
        while (curR < Q[i].r) check(ID[++curR], res);
        while (curR > Q[i].r) check(ID[curR--], res);

        int u = ID[curL], v = ID[curR];

        if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);

        ANS[Q[i].id] = res;

        if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);
    }

    for (int i = 0; i < M; i++) printf("%lld\n", ANS[i]);
}

int main(){
    int u, v, x;
    int t = 1;
    while (t--){
        scanf("%d", &N);
        for (int i = 1; i <= N; i++) {
            scanf("%d", &type[i]);
        }
        cur = 0;
        memset(VIS, 0, sizeof(VIS));
        memset(VAL, 0, sizeof(VAL));
        for (int i = 1; i <= N; i++) adjList[i].clear();
        for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
        memcpy(d + 1, A + 1, sizeof(int) * N);

        sort(d + 1, d + N + 1);
        K = unique(d + 1, d + N + 1) - d - 1;
        for (int i = 1; i <= N; i++) A[i] = lower_bound(d + 1, d + K + 1, A[i]) - d;

        for (int i = 1; i < N; i++){
            scanf("%d %d", &u, &v);
            adjList[u].push_back(v);
            adjList[v].push_back(u);
        }

        DP[0][1] = 1;
        dfs(1, -1);
        int size = max(1, (int) sqrt(cur));

        for (int i = 1; i <= cur; i++) BL[i] = (i - 1) / size + 1;

        scanf("%d", &M);
        for (int i = 0; i < M; i++){
            scanf("%d %d", &u, &v);
            Q[i].lc = lca(u, v);
            if (l[u] > l[v]) swap(u, v);
            if (Q[i].lc == u) Q[i].l = l[u], Q[i].r = l[v];
            else Q[i].l = r[u], Q[i].r = l[v];
            Q[i].id = i;
        }

        sort(Q, Q + M);
        compute();
    }
}


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

const int MAXN = 200005;
const int MAXM = 200005;
const int LN = 20;

int N, M, K, cur, A[MAXN], LVL[MAXN], DP[LN][MAXN];
int BL[MAXN << 1], ID[MAXN << 1], VAL[2][MAXN], ANS[MAXM];
int d[MAXN], l[MAXN], r[MAXN];
bool VIS[MAXN];
int type[MAXN];
vector < int > adjList[MAXN];

struct query{
    int id, l, r, lc;
    inline friend bool operator < (query lhs, query rhs){
        return (BL[lhs.l] == BL[rhs.l]) ? (lhs.r < rhs.r) : (BL[lhs.l] < BL[rhs.l]);
    }
}Q[MAXM];

void dfs(int u, int par){
    l[u] = ++cur;
    ID[cur] = u;
    for (int i = 1; i < LN; i++) DP[i][u] = DP[i - 1][DP[i - 1][u]];
    for (int i = 0; i < adjList[u].size(); i++){
        int v = adjList[u][i];
        if (v == par) continue;
        LVL[v] = LVL[u] + 1;
        DP[0][v] = u;
        dfs(v, u);
    }
    r[u] = ++cur; ID[cur] = u;
}

inline int lca(int u, int v){
    if (LVL[u] > LVL[v]) swap(u, v);
    for (int i = LN - 1; i >= 0; i--)
        if (LVL[v] - (1 << i) >= LVL[u]) v = DP[i][v];
    if (u == v) return u;
    for (int i = LN - 1; i >= 0; i--){
        if (DP[i][u] != DP[i][v]){
            u = DP[i][u];
            v = DP[i][v];
        }
    }
    return DP[0][u];
}

inline void check(int x, int& res){
    // If (x) occurs twice, then don't consider it's value
    if (VIS[x]) {
        res -= VAL[type[x] ^ 1][A[x]];
        VAL[type[x]][A[x]]--;
    } else {
        res += VAL[type[x] ^ 1][A[x]];
        VAL[type[x]][A[x]]++;
    }
    VIS[x] ^= 1;
}

void compute(){

    int curL = Q[0].l, curR = Q[0].l - 1, res = 0;

    for (int i = 0; i < M; i++){

        while (curL < Q[i].l) check(ID[curL++], res);
        while (curL > Q[i].l) check(ID[--curL], res);
        while (curR < Q[i].r) check(ID[++curR], res);
        while (curR > Q[i].r) check(ID[curR--], res);

        int u = ID[curL], v = ID[curR];

        if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);

        ANS[Q[i].id] = res;

        if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);
    }

    for (int i = 0; i < M; i++) printf("%lld\n", ANS[i]);
}

#undef int
int main(){
    #define int long long
    int u, v, x;
    int t = 1;
    while (t--){
        scanf("%lld", &N);
        for (int i = 1; i <= N; i++) {
            scanf("%lld", &type[i]);
        }
        cur = 0;
        memset(VIS, 0, sizeof(VIS));
        memset(VAL, 0, sizeof(VAL));
        for (int i = 1; i <= N; i++) adjList[i].clear();
        for (int i = 1; i <= N; i++) scanf("%lld", &A[i]);
        memcpy(d + 1, A + 1, sizeof(int) * N);

        sort(d + 1, d + N + 1);
        K = unique(d + 1, d + N + 1) - d - 1;
        for (int i = 1; i <= N; i++) A[i] = lower_bound(d + 1, d + K + 1, A[i]) - d;

        for (int i = 1; i < N; i++){
            scanf("%lld %lld", &u, &v);
            adjList[u].push_back(v);
            adjList[v].push_back(u);
        }

        DP[0][1] = 1;
        dfs(1, -1);
        int size = max(1LL, (long long) sqrt(cur));

        for (int i = 1; i <= cur; i++) BL[i] = (i - 1) / size + 1;

        scanf("%lld", &M);
        for (int i = 0; i < M; i++){
            scanf("%lld %lld", &u, &v);
            Q[i].lc = lca(u, v);
            if (l[u] > l[v]) swap(u, v);
            if (Q[i].lc == u) Q[i].l = l[u], Q[i].r = l[v];
            else Q[i].l = r[u], Q[i].r = l[v];
            Q[i].id = i;
        }

        sort(Q, Q + M);
        compute();
    }
}


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

const int MAXN = 200005;
const int MAXM = 200005;
const int LN = 20;

int N, M, K, cur, A[MAXN], LVL[MAXN], DP[LN][MAXN];
int BL[MAXN << 1], ID[MAXN << 1], VAL[2][MAXN], ANS[MAXM];
int d[MAXN], l[MAXN], r[MAXN];
bool VIS[MAXN];
int type[MAXN];
vector < int > adjList[MAXN];

struct query{
    int id, l, r, lc;
    inline friend bool operator < (query lhs, query rhs){
        return (BL[lhs.l] == BL[rhs.l]) ? (lhs.r < rhs.r) : (BL[lhs.l] < BL[rhs.l]);
    }
}Q[MAXM];

void dfs(int u, int par){
    l[u] = ++cur;
    ID[cur] = u;
    for (int i = 1; i < LN; i++) DP[i][u] = DP[i - 1][DP[i - 1][u]];
    for (int i = 0; i < adjList[u].size(); i++){
        int v = adjList[u][i];
        if (v == par) continue;
        LVL[v] = LVL[u] + 1;
        DP[0][v] = u;
        dfs(v, u);
    }
    r[u] = ++cur; ID[cur] = u;
}

inline int lca(int u, int v){
    if (LVL[u] > LVL[v]) swap(u, v);
    for (int i = LN - 1; i >= 0; i--)
        if (LVL[v] - (1 << i) >= LVL[u]) v = DP[i][v];
    if (u == v) return u;
    for (int i = LN - 1; i >= 0; i--){
        if (DP[i][u] != DP[i][v]){
            u = DP[i][u];
            v = DP[i][v];
        }
    }
    return DP[0][u];
}

inline void check(int x, int& res){
    // If (x) occurs twice, then don't consider it's value
    if (VIS[x]) {
        res -= VAL[type[x] ^ 1][A[x]];
        VAL[type[x]][A[x]]--;
    } else {
        res += VAL[type[x] ^ 1][A[x]];
        VAL[type[x]][A[x]]++;
    }
    VIS[x] ^= 1;
}

void compute(){

    int curL = Q[0].l, curR = Q[0].l - 1, res = 0;

    for (int i = 0; i < M; i++){

        while (curL < Q[i].l) check(ID[curL++], res);
        while (curL > Q[i].l) check(ID[--curL], res);
        while (curR < Q[i].r) check(ID[++curR], res);
        while (curR > Q[i].r) check(ID[curR--], res);

        int u = ID[curL], v = ID[curR];

        if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);

        ANS[Q[i].id] = res;

        if (Q[i].lc != u and Q[i].lc != v) check(Q[i].lc, res);
    }

    for (int i = 0; i < M; i++) printf("%d\n", ANS[i]);
}

int main(){
    int u, v, x;
    int t = 1;
    while (t--){
        scanf("%d", &N);
        for (int i = 1; i <= N; i++) {
            scanf("%d", &type[i]);
        }

        cur = 0;
        memset(VIS, 0, sizeof(VIS));
        memset(VAL, 0, sizeof(VAL));
        for (int i = 1; i <= N; i++) adjList[i].clear();

        for (int i = 1; i <= N; i++) scanf("%d", &A[i]);
        memcpy(d + 1, A + 1, sizeof(int) * N);

        sort(d + 1, d + N + 1);
        K = unique(d + 1, d + N + 1) - d - 1;
        for (int i = 1; i <= N; i++) A[i] = lower_bound(d + 1, d + K + 1, A[i]) - d;

        for (int i = 1; i < N; i++){
            scanf("%d %d", &u, &v);
            adjList[u].push_back(v);
            adjList[v].push_back(u);
        }

        DP[0][1] = 1;
        dfs(1, -1);
        int size = sqrt(cur);

        for (int i = 1; i <= cur; i++) BL[i] = (i - 1) / size + 1;

        scanf("%d", &M);
        for (int i = 0; i < M; i++){
            scanf("%d %d", &u, &v);
            Q[i].lc = lca(u, v);
            if (l[u] > l[v]) swap(u, v);
            if (Q[i].lc == u) Q[i].l = l[u], Q[i].r = l[v];
            else Q[i].l = r[u], Q[i].r = l[v];
            Q[i].id = i;
        }

        sort(Q, Q + M);
        compute();
    }
}


#include <bits/stdc++.h>
using namespace std;
#define f(i, x, n) for (int i = x; i < (int)(n); ++i)
#define ll long long

int n, id[100001], pa[100001][17], dp[100001], in[100001], out[100001], fr[100001];
pair<int, int> crp[100001];
vector<int> mp, D, tr[100001];
bool boy[100001];
ll an[100000], A;

void pl(int v = 1, int p = 0){
	in[v] = D.size();
	D.push_back(v);
	dp[v] = dp[p] + 1;
	pa[v][0] = p;
	int k = 1, z;
	while (k < 17 && (z = pa[v][k - 1]))pa[v][k] = pa[z][k - 1], ++k;
	f(i, 0, tr[v].size()){
		int u = tr[v][i];
		if (u == p)continue;
		pl(u, v);
	}
	out[v] = D.size();
	D.push_back(v);
}

int lca(int a, int b){
	if (dp[a] < dp[b])swap(a, b);
	int d = dp[a] - dp[b];
	int j = 0;
	while (d){
		if (d & 1)a = pa[a][j];
		d >>= 1;
		++j;
	}
	if (a == b)return a;
	for (int i = 16; i >= 0; --i)if (pa[a][i] != pa[b][i])a = pa[a][i], b = pa[b][i];
	return pa[a][0];
}

int W = 316;

struct Q{
	int a, b, id;
	Q(){}
	Q(int x, int y, int ii):a(x), b(y), id(ii){
		if (in[b] < in[a])swap(a, b);
	}
	bool operator <(Q const o)const {
		int x = in[a] / W, y = in[o.a] / W;
		if (x == y)return out[a] < out[o.a];
		return x < y;
	}
}qu[100000];

inline void ad(int v){
	int i = id[v];
	if (boy[v]){
		A += crp[i].second;
		++crp[i].first;
	}else {
		A += crp[i].first;
		++crp[i].second;
	}
}

inline void sb(int v){
	int i = id[v];
	if (boy[v]){
		A -= crp[i].second;
		--crp[i].first;
	}else {
		A -= crp[i].first;
		--crp[i].second;
	}
}

int main(){
	scanf("%d", &n);
	f(i, 1, n + 1){
		int t;
		scanf("%d", &t);
		boy[i] = t;
	}
	f(i, 1, n + 1){
		scanf("%d", id + i);
		mp.push_back(id[i]);
	}
	sort(mp.begin(), mp.end());
	mp.resize(unique(mp.begin(), mp.end()) - mp.begin());
	f(i, 1, n + 1)id[i] = lower_bound(mp.begin(), mp.end(), id[i]) - mp.begin();

	f(i, 1, n){
		int a, b;
		scanf("%d%d", &a, &b);
		tr[a].push_back(b);
		tr[b].push_back(a);
	}

	pl();

	int q;
	scanf("%d", &q);
	f(i, 0, q){
		int a, b;
		scanf("%d%d", &a, &b);
		qu[i] = Q(a, b, i);
	}

	sort(qu, qu + q);

	int l = 0, r = -1;
	f(i, 0, q){
		if (qu[i].a == qu[i].b)continue;
		int wl = in[qu[i].a] + 1, wr = in[qu[i].b];
		while (r < wr){
			++r;
			int v = D[r];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}
		while (l > wl){
			--l;
			int v = D[l];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}
		while (r > wr){
			int v = D[r];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			--r;
		}
		while (l < wl){
			int v = D[l];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			++l;
		}

		int lc = lca(qu[i].a, qu[i].b);
		ad(lc);
		an[qu[i].id] = A;
		sb(lc);
	}

	f(i, 0, q)printf("%lld\n", an[i]);
}


#include <bits/stdc++.h>
using namespace std;
#define f(i, x, n) for (int i = x; i < (int)(n); ++i)
#define ll long long

int n, id[100001], pa[100001][17], dp[100001], in[100001], out[100001], fr[100001];
pair<int, int> crp[100001];
vector<int> mp, D, tr[100001];
bool boy[100001];
ll an[100000], A;

void pl(int v = 1, int p = 0){
	in[v] = D.size();
	D.push_back(v);
	dp[v] = dp[p] + 1;
	pa[v][0] = p;
	int k = 1, z;
	while (k < 17 && (z = pa[v][k - 1]))pa[v][k] = pa[z][k - 1], ++k;
	f(i, 0, tr[v].size()){
		int u = tr[v][i];
		if (u == p)continue;
		pl(u, v);
	}
	out[v] = D.size();
	D.push_back(v);
}

int lca(int a, int b){
	if (dp[a] < dp[b])swap(a, b);
	int d = dp[a] - dp[b];
	int j = 0;
	while (d){
		if (d & 1)a = pa[a][j];
		d >>= 1;
		++j;
	}
	if (a == b)return a;
	for (int i = 16; i >= 0; --i)if (pa[a][i] != pa[b][i])a = pa[a][i], b = pa[b][i];
	return pa[a][0];
}

int W;

struct Q{
	int a, b, id;
	Q(){}
	Q(int x, int y, int ii):a(x), b(y), id(ii){
		if (in[b] < in[a])swap(a, b);
	}
	bool operator <(Q const o)const {
		int x = in[a] / W, y = in[o.a] / W;
		if (x == y){
			if (x & 1)return in[b] < in[o.b];
			else return in[b] > in[o.b];
		}
		return x < y;
	}
}qu[100000];

inline void ad(int v){
	int i = id[v];
	if (boy[v]){
		A += crp[i].second;
		++crp[i].first;
	}else {
		A += crp[i].first;
		++crp[i].second;
	}
}

inline void sb(int v){
	int i = id[v];
	if (boy[v]){
		A -= crp[i].second;
		--crp[i].first;
	}else {
		A -= crp[i].first;
		--crp[i].second;
	}
}

int main(){
	scanf("%d", &n);
	f(i, 1, n + 1){
		int t;
		scanf("%d", &t);
		boy[i] = t;
	}
	f(i, 1, n + 1){
		scanf("%d", id + i);
		mp.push_back(id[i]);
	}
	sort(mp.begin(), mp.end());
	mp.resize(unique(mp.begin(), mp.end()) - mp.begin());
	f(i, 1, n + 1)id[i] = lower_bound(mp.begin(), mp.end(), id[i]) - mp.begin();

	f(i, 1, n){
		int a, b;
		scanf("%d%d", &a, &b);
		tr[a].push_back(b);
		tr[b].push_back(a);
	}

	pl();
	W = sqrt(D.size()) + 1;

	int q;
	scanf("%d", &q);
	f(i, 0, q){
		int a, b;
		scanf("%d%d", &a, &b);
		qu[i] = Q(a, b, i);
	}

	sort(qu, qu + q);

	int l = 0, r = -1;
	f(i, 0, q){
		if (qu[i].a == qu[i].b)continue;
		int wl = in[qu[i].a] + 1, wr = in[qu[i].b];
		while (r < wr){
			++r;
			int v = D[r];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}
		while (l > wl){
			--l;
			int v = D[l];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}
		while (r > wr){
			int v = D[r];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			--r;
		}
		while (l < wl){
			int v = D[l];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			++l;
		}

		int lc = lca(qu[i].a, qu[i].b);
		ad(lc);
		an[qu[i].id] = A;
		sb(lc);
	}

	f(i, 0, q)printf("%lld\n", an[i]);
}


#include <bits/stdc++.h>
using namespace std;
#define f(i, x, n) for (int i = x; i < (int)(n); ++i)
#define ll long long

int n, id[100001], pa[100001][17], dp[100001], in[100001], out[100001], fr[100001];
pair<int, int> crp[100001];
vector<int> mp, D, tr[100001];
bool boy[100001];
ll an[100000], A;

void pl(int v = 1, int p = 0){
	in[v] = D.size();
	D.push_back(v);
	dp[v] = dp[p] + 1;
	pa[v][0] = p;
	int k = 1, z;
	while (k < 17 && (z = pa[v][k - 1]))pa[v][k] = pa[z][k - 1], ++k;
	f(i, 0, tr[v].size()){
		int u = tr[v][i];
		if (u == p)continue;
		pl(u, v);
	}
	out[v] = D.size();
	D.push_back(v);
}

int lca(int a, int b){
	if (dp[a] < dp[b])swap(a, b);
	int d = dp[a] - dp[b];
	int j = 0;
	while (d){
		if (d & 1)a = pa[a][j];
		d >>= 1;
		++j;
	}
	if (a == b)return a;
	for (int i = 16; i >= 0; --i)if (pa[a][i] != pa[b][i])a = pa[a][i], b = pa[b][i];
	return pa[a][0];
}

int W = 316;

struct Q{
	int a, b, id;
	Q(){}
	Q(int x, int y, int ii):a(x), b(y), id(ii){
		if (in[b] < in[a])swap(a, b);
	}
	bool operator <(Q const o)const {
		int x = in[a] / W, y = in[o.a] / W;
		if (x == y)return out[a] < out[o.a];
		return x < y;
	}
}qu[100000];

inline void ad(int v){
	int i = id[v];
	if (boy[v]){
		A += crp[i].second;
		++crp[i].first;
	}else {
		A += crp[i].first;
		++crp[i].second;
	}
}

inline void sb(int v){
	int i = id[v];
	if (boy[v]){
		A -= crp[i].second;
		--crp[i].first;
	}else {
		A -= crp[i].first;
		--crp[i].second;
	}
}

int main(){
	scanf("%d", &n);
	f(i, 1, n + 1){
		int t;
		scanf("%d", &t);
		boy[i] = t;
	}
	f(i, 1, n + 1){
		scanf("%d", id + i);
		mp.push_back(id[i]);
	}
	sort(mp.begin(), mp.end());
	mp.resize(unique(mp.begin(), mp.end()) - mp.begin());
	f(i, 1, n + 1)id[i] = lower_bound(mp.begin(), mp.end(), id[i]) - mp.begin();

	f(i, 1, n){
		int a, b;
		scanf("%d%d", &a, &b);
		tr[a].push_back(b);
		tr[b].push_back(a);
	}

	pl();

	int q;
	scanf("%d", &q);
	f(i, 0, q){
		int a, b;
		scanf("%d%d", &a, &b);
		qu[i] = Q(a, b, i);
	}

	sort(qu, qu + q);

	int l = 0, r = -1;
	f(i, 0, q){
		if (qu[i].a == qu[i].b)continue;
		int wl = in[qu[i].a] + 1, wr = in[qu[i].b];
		while (r < wr){
			++r;
			int v = D[r];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}
		while (r > wr){
			int v = D[r];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			--r;
		}
		while (l < wl){
			int v = D[l];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			++l;
		}
		while (l > wl){
			--l;
			int v = D[l];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}

		int lc = lca(qu[i].a, qu[i].b);
		ad(lc);
		an[qu[i].id] = A;
		sb(lc);
	}

	f(i, 0, q)printf("%lld\n", an[i]);
}


#include <bits/stdc++.h>
using namespace std;
#define f(i, x, n) for (int i = x; i < (int)(n); ++i)
#define ll long long

int n, id[100001], pa[100001][17], dp[100001], in[100001], out[100001], fr[100001];
pair<int, int> crp[100001];
vector<int> mp, D, tr[100001];
bool boy[100001];
ll an[100000], A;

void pl(int v = 1, int p = 0){
	in[v] = D.size();
	D.push_back(v);
	dp[v] = dp[p] + 1;
	pa[v][0] = p;
	int k = 1, z;
	while (k < 17 && (z = pa[v][k - 1]))pa[v][k] = pa[z][k - 1], ++k;
	f(i, 0, tr[v].size()){
		int u = tr[v][i];
		if (u == p)continue;
		pl(u, v);
	}
	out[v] = D.size();
	D.push_back(v);
}

int lca(int a, int b){
	if (dp[a] < dp[b])swap(a, b);
	int d = dp[a] - dp[b];
	int j = 0;
	while (d){
		if (d & 1)a = pa[a][j];
		d >>= 1;
		++j;
	}
	if (a == b)return a;
	for (int i = 16; i >= 0; --i)if (pa[a][i] != pa[b][i])a = pa[a][i], b = pa[b][i];
	return pa[a][0];
}

int W = 316;

struct Q{
	int a, b, id;
	Q(){}
	Q(int x, int y, int ii):a(x), b(y), id(ii){
		if (in[b] < in[a])swap(a, b);
	}
	bool operator <(Q const o)const {
		int x = in[a] / W, y = in[o.a] / W;
		if (x == y)return out[a] < out[o.a];
		return x < y;
	}
}qu[100000];

inline void ad(int v){
	int i = id[v];
	if (boy[v]){
		A += crp[i].second;
		++crp[i].first;
	}else {
		A += crp[i].first;
		++crp[i].second;
	}
}

inline void sb(int v){
	int i = id[v];
	if (boy[v]){
		A -= crp[i].second;
		--crp[i].first;
	}else {
		A -= crp[i].first;
		--crp[i].second;
	}
}

int main(){
	scanf("%d", &n);
	f(i, 1, n + 1){
		int t;
		scanf("%d", &t);
		boy[i] = t;
	}
	f(i, 1, n + 1){
		scanf("%d", id + i);
		mp.push_back(id[i]);
	}
	sort(mp.begin(), mp.end());
	mp.resize(unique(mp.begin(), mp.end()) - mp.begin());
	f(i, 1, n + 1)id[i] = lower_bound(mp.begin(), mp.end(), id[i]) - mp.begin();

	f(i, 1, n){
		int a, b;
		scanf("%d%d", &a, &b);
		tr[a].push_back(b);
		tr[b].push_back(a);
	}

	pl();

	int q;
	scanf("%d", &q);
	f(i, 0, q){
		int a, b;
		scanf("%d%d", &a, &b);
		qu[i] = Q(a, b, i);
	}

	sort(qu, qu + q);

	int l = 0, r = -1;
	f(i, 0, q){
		int wl = in[qu[i].a] + 1, wr = in[qu[i].b];
		while (r < wr){
			++r;
			int v = D[r];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}
		while (r > wr){
			int v = D[r];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			--r;
		}
		while (l < wl){
			int v = D[l];
			if (--fr[v] == 1)ad(v);
			else sb(v);
			++l;
		}
		while (l > wl){
			--l;
			int v = D[l];
			if (++fr[v] == 1)ad(v);
			else sb(v);
		}

		int lc = lca(qu[i].a, qu[i].b);
		ad(lc);
		an[qu[i].id] = A;
		sb(lc);
	}

	f(i, 0, q)printf("%lld\n", an[i]);
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N*10], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  dfs(1);
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[b.l];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  if (n == 213) puts("1: gg");
  dfs(1);
  if (n == 213) puts("2: gg");
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  if (n == 213) puts("3: gg");
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N*10], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  dfs(1);
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  // printf("%d\n", u);
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
  }
  dfs(1);
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2];
long long ans[N], cur;
int st[N*10], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= 1ll * cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += 1ll * cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  dfs(1);
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[b.l];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%lld\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N];
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  // printf("%d\n", u);
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  // printf("%d %d %d %d\n", u, in[u], cnt[f[u]][b[u]], cnt[f[u]][b[u]^1]);
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
  // printf("%d %d %d %d\n", u, in[u], cnt[f[u]][b[u]], cnt[f[u]][b[u]^1]);
}

void move(int u, int v) {
  // printf("%d %d:\n", u, v);
  if (dep[u] < dep[v]) swap(u, v);
  while (dep[u] > dep[v]) {
    // printf("before: %d %d\n", u, cur);
    inv(u); u = par[u];
    // printf("after: %d %d\n", u, cur);
  }
  while (u != v) {
    inv(u); inv(v);
    u = par[u]; v = par[v];
  }
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
  }
  dfs(1);
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N*10], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  vis[u] = 1;
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  dfs(1);
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[b.l];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  // printf("%d\n", u);
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  dfs(1);
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur, vis[N];
int st[N*10], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  vis[u] = 1;
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    assert(!vis[v]);
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  dfs(1);
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#include <bits/stdc++.h>

using namespace std;

const int N = 1e5 + 5;
int n, q, f[N], b[N], cnt[N][2], ans[N], cur;
int st[N], dfn[N], cn, top, par[N], dep[N], sz, tot, bl[N], in[N], cross;
vector<int> es[N];
map<int, int> hs;

struct Query {
  int l, r, id;
}qs[N];

int dfs(int u) {
  int ret = 0;
  st[++top] = u, dfn[u] = ++cn;
  for (auto v : es[u]) if (v != par[u]) {
    par[v] = u;
    dep[v] = dep[u] + 1;
    ret += dfs(v);
    if (ret >= sz) {
      ++tot; ret = 0;
      while (st[top] != u) {
        bl[st[top--]] = tot;
      }
    }
  }
  return ret + 1;
}

void inv(int u) {
  if (in[u]) {
    in[u] = 0;
    cur -= cnt[f[u]][b[u]^1];
    cnt[f[u]][b[u]]--;
  } else {
    in[u] = 1;
    cnt[f[u]][b[u]]++;
    cur += cnt[f[u]][b[u]^1];
  }
}

void move_up(int &x) {
  if (!cross) {
    if (in[x] && !in[par[x]]) cross = x;
    else if (in[par[x]] && !in[x]) cross = par[x];
  }
  inv(x); x = par[x];
}

void move(int a, int b) {
  if (a == b) return;
  cross = 0;
  if (in[b]) cross = b;
  while (dep[a] > dep[b]) move_up(a);
  while (dep[b] > dep[a]) move_up(b);
  while (a != b) move_up(a), move_up(b);
  inv(a); inv(cross);
}

void solve() {
  if (n == 213) puts("0: gg");
  scanf("%d", &n);
  sz = sqrt(n);
  for (int i = 1; i <= n; i++) scanf("%d", &b[i]);
  for (int i = 1; i <= n; i++) {
    scanf("%d", &f[i]); hs[f[i]] = 0;
  }
  for (int i = 1; i < n; i++) {
    int u, v; scanf("%d%d", &u, &v);
    es[u].push_back(v); es[v].push_back(u);
  }
  int k = 0;
  for (auto &it : hs) it.second = k++;
  for (int i = 1; i <= n; i++) f[i] = hs[f[i]];
  if (n == 213) puts("1: gg");
  dfs(1);
  if (n == 213) puts("2: gg");
  while (top) bl[st[top--]] = tot;
  scanf("%d", &q);
  for (int i = 0; i < q; i++) {
    scanf("%d%d", &qs[i].l, &qs[i].r); qs[i].id = i;
    if (bl[qs[i].l] > bl[qs[i].r]) swap(qs[i].l, qs[i].r);
  }
  sort(qs, qs + q, [&](Query &a, Query &b) {
    return bl[a.l] == bl[b.l] ? dfn[a.r] < dfn[b.r] : bl[a.l] < bl[a.r];
  });
  int lo = 1, hi = 1;
  cnt[f[1]][b[1]]++; cur = 0; in[1] = 1;
  if (n == 213) puts("3: gg");
  for (int i = 0; i < q; i++) {
    // printf("%d %d:\n", qs[i].l, qs[i].r);
    move(lo, qs[i].l); lo = qs[i].l;
    move(hi, qs[i].r); hi = qs[i].r;
    // for (int i = 1; i <= n; i++) printf("%d ", in[i]); puts("\n");
    ans[qs[i].id] = cur;
  }
  for (int i = 0; i < q; i++) printf("%d\n", ans[i]);
}

int main() {
#ifdef SHCH
  freopen("input.txt", "r", stdin);
  freopen("output.txt", "w", stdout);
#endif
  solve();
  return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 3000, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 400, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 1500, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 350, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k, kol[N];

int s, ans[N];

unordered_map < int, int > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    int now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    int now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    k = 350;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


//#pragma GCC optimize("Ofast")
//#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 350, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 2000, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}


#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4")

#include <bits/stdc++.h>

#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/detail/standard_policies.hpp>

#define pb push_back
#define F first
#define S second
#define lll long long
#define lld long double

using namespace std;
using namespace __gnu_pbds;

template <typename T>
using ordered_set = tree <T,null_type,less<T>,rb_tree_tag,tree_order_statistics_node_update>;

const int N = 1e5 + 229;
const lll M = 1e9 + 7;
const lll M2 = 1e9 + 9;
const int mod = 998244353;
const int rx[8] = {1, 1, -1, -1, -2, -2, 2, 2};
const int ry[8] = {-2, 2, -2, 2, 1, -1, 1, -1};
const lld eps = 1e-7;
const double pi = acos(-1.0);

bool who[N];

int f[N];

vector < int > g[N], way;

int tin[N], tout[N], up[N][20], timer = -1;

int k = 1000, kol[N];

lll s, ans[N];

unordered_map < int, lll > boy, girl;

struct node {
    int l, r, nom, lca;
    bool need;
    bool operator < (const node a) {
        if (l / k == a.l / k) {
            return r < a.r;
        }
        return l / k < a.l / k;
    }
};

vector < node > q;

void dfs(int v, int p = 0) {
    ++timer;
    tin[v] = timer;
    up[v][0] = p;
    way.pb(v);
    for (int i = 1; i < 20; ++i) {
        up[v][i] = up[up[v][i - 1]][i - 1];
    }
    for (auto to : g[v]) {
        if (to == p) {
            continue;
        }
        dfs(to, v);
    }
    way.pb(v);
    ++timer;
    tout[v] = timer;
}

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

int lca(int a, int b) {
    if (upper(a, b)) {
        return a;
    }
    if (upper(b, a)) {
        return b;
    }
    for (int i = 19; i >= 0; --i) {
        if (!upper(up[a][i], b)) {
            a = up[a][i];
        }
    }
    return up[a][0];
}

void add(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    ++kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

void del(int i) {
    lll now = 0;
    int v = way[i];
    if (!who[v]) {
        now = girl[f[v]];
    } else {
        now = boy[f[v]];
    }
    --kol[v];
    if (kol[v] == 1) {
        s += now;
        if (!who[v]) {
            ++boy[f[v]];
        } else {
            ++girl[f[v]];
        }
    } else {
        s -= now;
        if (!who[v]) {
            --boy[f[v]];
        } else {
            --girl[f[v]];
        }
    }
}

int main() {
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    srand(time(0));
#ifdef LOCAL
    freopen("input.txt", "r", stdin);
    freopen("output.txt", "w", stdout);
#else
//    freopen("input.txt", "r", stdin);
//    freopen("output.txt", "w", stdout);
#endif
    int n;
    cin >> n;
    for (int i = 0; i < n; ++i) {
        cin >> who[i];
    }
    for (int i = 0; i < n; ++i) {
        cin >> f[i];
    }
    int x, y;
    for (int i = 1; i < n; ++i) {
        cin >> x >> y;
        --x;
        --y;
        g[x].pb(y);
        g[y].pb(x);
    }
    dfs(0);
    int m;
    node now;
    cin >> m;
    for (int i = 0; i < m; ++i) {
        cin >> x >> y;
        --x;
        --y;
        now.nom = i;
        now.need = 0;
        now.lca = lca(x, y);
        if (tin[x] > tin[y]) {
            swap(x, y);
        }
        if (upper(x, y)) {
            now.l = tin[x];
            now.r = tin[y];
            now.need = 0;
        } else {
            now.l = tout[x];
            now.r = tin[y];
            now.need = 1;
        }
        q.pb(now);
    }
//    for (auto i : way) {
//        cout << i + 1 << ' ';
//    }
//    cout << endl;
    sort(q.begin(), q.end());
    int l = 0, r = -1;
    for (auto i : q) {
//        cout << i.l << ' ' << i.r << endl;
        while (r < i.r) {
            ++r;
            add(r);
        }
        while (l > i.l) {
            --l;
            add(l);
        }
        while (r > i.r) {
            del(r);
            --r;
        }
        while (l < i.l) {
            del(l);
            ++l;
        }
//        cout << girl[9] << endl;
        if (i.need) {
            int v = i.lca;
            if (!who[v]) {
                ans[i.nom] += girl[f[v]];
            } else {
                ans[i.nom] += boy[f[v]];
            }
        }
        ans[i.nom] += s;
    }
    for (int i = 0; i < m; ++i) {
        cout << ans[i] << '\n';
    }
    return 0;
}