#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace std;
#define FR(i,n) for(int i = 0,__end=(n); i < __end; ++i)
struct LCA {
    vector<vector<int> > par;
    vector<int> dep;
    vector<vector<int> > & adj;
    int log;

    LCA(int n, int root, vector<vector<int> > &_adj):adj(_adj) {

        for (log = 1; (1 << log) < n; log++);
        par.resize(n, vector<int>(log, -1));
        dep.resize(n,0);
        dfs(root, -1);
        for(int j = 1; j < log;++j)
            for(int i = 0 ; i < n; ++i) {
                if(par[i][j-1] != -1) {
                    par[i][j] = par[par[i][j-1]][j - 1];
                }
            }
    }

    void dfs(int v, int p) {
        par[v][0] = p;
        if(p != -1) {
            dep[v] = dep[p] + 1;
        }

        for(vector<int>::iterator it = adj[v].begin(); it != adj[v].end(); ++it) {
            int u = *it;
            if(u != p) {
                dfs(u,v);
            }
        }
    }

    int getLCA(int a, int b) {
        if (dep[a] > dep[b]) return getLCA(b, a);
        for (int i = log - 1; i >= 0; i--) {
            if (par[b][i] != -1 && dep[par[b][i]] >= dep[a]) {
                b = par[b][i];
            }
        }
        if (a == b) return a;
        for (int i = log - 1; i >= 0; i--) {
            if (par[a][i] != par[b][i]) {
                a = par[a][i];
                b = par[b][i];
            }
        }
        return par[a][0];
    }
};

struct MoData {
    int l,r,add,id;

};

const int MAXN = 100100;
vector<vector<int> > g;
int n;
int cnt[MAXN] = {0};
int f[MAXN];
int ff[MAXN];
bool isGirl[MAXN];
int npath = 0;
int path[2 * MAXN];
int val,to,from,q,p;
int st[MAXN];
int en[MAXN];
MoData mo[MAXN];
int blockSize = 1024;
LCA * lca;
int countBoy[MAXN] = {0},countGirl[MAXN] = {0};
long long re = 0;
long long ret[MAXN];

void _add(int f, bool girl, int delta) {
    re -= 1ll * countGirl[f] * countBoy[f];
    if(girl) countGirl[f]+=delta; else countBoy[f] += delta;
    re += 1ll * countGirl[f] * countBoy[f];
}

void moAdd(int pos) {
    int id = path[pos];
    cnt[id] ^= 1;
    if(cnt[id] == 1) _add(f[id],isGirl[id], 1); else _add(f[id],isGirl[id],-1);
}

void moRemove(int pos) {
    int id = path[pos];
    if(cnt[id] == 1) _add(f[id],isGirl[id], -1); else _add(f[id],isGirl[id],1);
    cnt[id] ^= 1;
}

bool moDataCmp(const MoData& m1, const MoData& m2) {
    int b1 = m1.l/blockSize;
    int b2 = m2.l/blockSize;

    if(b1 != b2) return b1 < b2; else return m1.r < m2.r;

    // if((m1.l >> 9) != (m2.l>>9)) return m1.l < m2.l;
    // return m1.r < m2.r;
}
void dfs(int v, int par) {
    st[v] = npath;
    path[npath++ ] = v;
    FR(i, g[v].size()) {
        int u = g[v][i];
        if(u != par) {
            dfs(u,v);
        }
    }

    en[v] = npath;
    path[npath++] = v;
}

int main () {
    // ios_base::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
    //cin>>n;
    scanf("%d",&n);
    FR(i,n) {
        //cin>>val;
        scanf("%d",&val);
        isGirl[i] = (1 == val);
    }
    FR(i,n) {
        //cin>>f[i];
        scanf("%d",&f[i]);
        ff[i] = f[i];
    }
    sort(ff, ff + n);
    FR(i,n) f[i] = lower_bound(ff, ff + n, f[i]) - ff;
    g.resize(n);
    FR(i,n - 1) {
        //cin>>from>>to;
        scanf("%d%d",&from,&to);
        from--; to --;
        g[from].push_back(to);
        g[to].push_back(from);
    }
    dfs(0, -1);
    lca = new LCA(n, 0 , g);

    cin>>q;
    FR(i,q) {
        //cin>>from>>to;
        scanf("%d%d",&from,&to);
        from--;to--;
        if(st[from] > st[to]) swap(from,to);
        p = lca->getLCA(from, to);
        mo[i].id = i;
        if(from == p) {
            mo[i].l = st[from];
            mo[i].r = st[to];
            mo[i].add = -1;
        } else {
            mo[i].l = en[from];
            mo[i].r = st[to];
            mo[i].add = p;
        }
    }

    blockSize = (int)sqrt(npath) + 1;

    sort(mo, mo + q, moDataCmp);
    int moStart = mo[0].l;
    int moEnd = moStart - 1;
    // FR(i,npath) cerr<<path[i]<<" ";
    // cerr<<endl;

    FR(i,q) {
        int l = mo[i].l;
        int r = mo[i].r;
        while(moStart < l) moRemove(moStart ++);
        while(moStart > l) moAdd(--moStart);
        while(moEnd < r) moAdd(++moEnd);
        while(moEnd > r) moRemove(moEnd--);
        if(mo[i].add == -1) {
            ret[mo[i].id] = re;
        } else {
            int p = mo[i].add;
            _add(f[p], isGirl[p], 1);
            ret[mo[i].id] = re;
            _add(f[p], isGirl[p], -1);
        }
    }

    FR(i,q) printf("%lld\n",ret[i]);

    delete lca;
    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace std;
#define FR(i,n) for(int i = 0,__end=(n); i < __end; ++i)

struct MoData {
    int l,r,add,id;

};

const int MAXN = 100100;
//vector<vector<int> > g;

vector<int> g[MAXN];
int dep[MAXN];
int par[MAXN][20];
int LOG = 0;
int n;
int cnt[MAXN] = {0};
int f[MAXN];
int ff[MAXN];
bool isGirl[MAXN];
int npath = 0;
int path[2 * MAXN];
int val,to,from,q,p;
int st[MAXN];
int en[MAXN];
MoData mo[MAXN];
int blockSize = 1024;
int BL[MAXN * 2];

int countBoy[MAXN] = {0},countGirl[MAXN] = {0};
long long re = 0;
long long ret[MAXN];

int getLCA(int a, int b) {
    if (dep[a] > dep[b]) return getLCA(b, a);
    for (int i = LOG - 1; i >= 0; i--) {
        if (par[b][i] != -1 && dep[par[b][i]] >= dep[a]) {
            b = par[b][i];
        }
    }
    if (a == b) return a;
    for (int i = LOG - 1; i >= 0; i--) {
        if (par[a][i] != par[b][i]) {
            a = par[a][i];
            b = par[b][i];
        }
    }
    return par[a][0];
}

void _add(int f, bool girl, int delta) {
    re -= 1ll * countGirl[f] * countBoy[f];
    if(girl) countGirl[f]+=delta; else countBoy[f] += delta;
    re += 1ll * countGirl[f] * countBoy[f];
}

void moAdd(int pos) {
    int id = path[pos];
    cnt[id] ^= 1;
    if(cnt[id] == 1) _add(f[id],isGirl[id], 1); else _add(f[id],isGirl[id],-1);
}

void moRemove(int pos) {
    int id = path[pos];
    if(cnt[id] == 1) _add(f[id],isGirl[id], -1); else _add(f[id],isGirl[id],1);
    cnt[id] ^= 1;
}

bool moDataCmp(const MoData& m1, const MoData& m2) {
    if(BL[m1.l] != BL[m2.l]) return BL[m1.l] < BL[m2.l]; else return m1.r < m2.r;

    // if((m1.l >> 9) != (m2.l>>9)) return m1.l < m2.l;
    // return m1.r < m2.r;
}
void dfs(int v, int p) {
    par[v][0] = p;
    if(p != -1) {
        dep[v] = dep[p] + 1;
    }

    st[v] = ++npath;
    path[npath ] = v;
    FR(i, g[v].size()) {
        int u = g[v][i];
        if(u != p) {
            dfs(u,v);
        }
    }

    en[v] = ++npath;
    path[npath] = v;
}

int main () {
    // ios_base::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
    //cin>>n;
    scanf("%d",&n);
    FR(i,n) {
        //cin>>val;
        scanf("%d",&val);
        isGirl[i] = (1 == val);
    }
    FR(i,n) {
        //cin>>f[i];
        scanf("%d",&f[i]);
        ff[i] = f[i];
    }
    sort(ff, ff + n);
    FR(i,n) f[i] = lower_bound(ff, ff + n, f[i]) - ff;

    FR(i,n - 1) {
        //cin>>from>>to;
        scanf("%d%d",&from,&to);
        from--; to --;
        g[from].push_back(to);
        g[to].push_back(from);
    }
    for (LOG = 1; (1 << LOG) < n; LOG++);
    dfs(0, -1);
    for(int j = 1; j < LOG;++j)
        for(int i = 0 ; i < n; ++i) {
            if(par[i][j-1] != -1) {
                par[i][j] = par[par[i][j-1]][j - 1];
            }
        }

    cin>>q;
    FR(i,q) {
        //cin>>from>>to;
        scanf("%d%d",&from,&to);
        from--;to--;
        if(st[from] > st[to]) swap(from,to);
        p = getLCA(from, to);
        mo[i].id = i;
        if(from == p) {
            mo[i].l = st[from];
            mo[i].r = st[to];
            mo[i].add = -1;
        } else {
            mo[i].l = en[from];
            mo[i].r = st[to];
            mo[i].add = p;
        }
    }

    blockSize = (int)sqrt(npath) ;
    for(int i = 1 ; i<= npath; ++i) BL[i] = (i - 1)/blockSize + 1 ;
    sort(mo, mo + q, moDataCmp);
    int moStart = mo[0].l;
    int moEnd = moStart - 1;
    // FR(i,npath) cerr<<path[i]<<" ";
    // cerr<<endl;

    FR(i,q) {
        int l = mo[i].l;
        int r = mo[i].r;
        while(moStart < l) moRemove(moStart ++);
        while(moStart > l) moAdd(--moStart);
        while(moEnd < r) moAdd(++moEnd);
        while(moEnd > r) moRemove(moEnd--);
        if(mo[i].add == -1) {
            ret[mo[i].id] = re;
        } else {
            int p = mo[i].add;
            _add(f[p], isGirl[p], 1);
            ret[mo[i].id] = re;
            _add(f[p], isGirl[p], -1);
        }
    }

    FR(i,q) printf("%lld\n",ret[i]);

    return 0;
}


#include <iostream>
#include <vector>
#include <algorithm>
#include <cmath>
#include <cstdio>

using namespace std;
#define FR(i,n) for(int i = 0,__end=(n); i < __end; ++i)

struct MoData {
    int l,r,add,id;

};

const int MAXN = 100100;
//vector<vector<int> > g;

vector<int> g[MAXN];
int dep[MAXN];
int par[MAXN][20];
int LOG = 0;
int n;
int cnt[MAXN] = {0};
int f[MAXN];
int ff[MAXN];
bool isGirl[MAXN];
int npath = 0;
int path[2 * MAXN];
int val,to,from,q,p;
int st[MAXN];
int en[MAXN];
MoData mo[MAXN];
int blockSize = 1024;

int countBoy[MAXN] = {0},countGirl[MAXN] = {0};
long long re = 0;
long long ret[MAXN];

int getLCA(int a, int b) {
    if (dep[a] > dep[b]) return getLCA(b, a);
    for (int i = LOG - 1; i >= 0; i--) {
        if (par[b][i] != -1 && dep[par[b][i]] >= dep[a]) {
            b = par[b][i];
        }
    }
    if (a == b) return a;
    for (int i = LOG - 1; i >= 0; i--) {
        if (par[a][i] != par[b][i]) {
            a = par[a][i];
            b = par[b][i];
        }
    }
    return par[a][0];
}

void _add(int f, bool girl, int delta) {
    re -= 1ll * countGirl[f] * countBoy[f];
    if(girl) countGirl[f]+=delta; else countBoy[f] += delta;
    re += 1ll * countGirl[f] * countBoy[f];
}

void moAdd(int pos) {
    int id = path[pos];
    cnt[id] ^= 1;
    if(cnt[id] == 1) _add(f[id],isGirl[id], 1); else _add(f[id],isGirl[id],-1);
}

void moRemove(int pos) {
    int id = path[pos];
    if(cnt[id] == 1) _add(f[id],isGirl[id], -1); else _add(f[id],isGirl[id],1);
    cnt[id] ^= 1;
}

bool moDataCmp(const MoData& m1, const MoData& m2) {
    int b1 = m1.l/blockSize;
    int b2 = m2.l/blockSize;

    if(b1 != b2) return b1 < b2; else return m1.r < m2.r;

    // if((m1.l >> 9) != (m2.l>>9)) return m1.l < m2.l;
    // return m1.r < m2.r;
}
void dfs(int v, int p) {
    par[v][0] = p;
    if(p != -1) {
        dep[v] = dep[p] + 1;
    }

    st[v] = npath;
    path[npath++ ] = v;
    FR(i, g[v].size()) {
        int u = g[v][i];
        if(u != p) {
            dfs(u,v);
        }
    }

    en[v] = npath;
    path[npath++] = v;
}

int main () {
    // ios_base::sync_with_stdio(false);
    // cin.tie(0);
    // cout.tie(0);
    //cin>>n;
    scanf("%d",&n);
    FR(i,n) {
        //cin>>val;
        scanf("%d",&val);
        isGirl[i] = (1 == val);
    }
    FR(i,n) {
        //cin>>f[i];
        scanf("%d",&f[i]);
        ff[i] = f[i];
    }
    sort(ff, ff + n);
    FR(i,n) f[i] = lower_bound(ff, ff + n, f[i]) - ff;

    FR(i,n - 1) {
        //cin>>from>>to;
        scanf("%d%d",&from,&to);
        from--; to --;
        g[from].push_back(to);
        g[to].push_back(from);
    }
    for (LOG = 1; (1 << LOG) < n; LOG++);
    dfs(0, -1);
    for(int j = 1; j < LOG;++j)
        for(int i = 0 ; i < n; ++i) {
            if(par[i][j-1] != -1) {
                par[i][j] = par[par[i][j-1]][j - 1];
            }
        }

    cin>>q;
    FR(i,q) {
        //cin>>from>>to;
        scanf("%d%d",&from,&to);
        from--;to--;
        if(st[from] > st[to]) swap(from,to);
        p = getLCA(from, to);
        mo[i].id = i;
        if(from == p) {
            mo[i].l = st[from];
            mo[i].r = st[to];
            mo[i].add = -1;
        } else {
            mo[i].l = en[from];
            mo[i].r = st[to];
            mo[i].add = p;
        }
    }

    blockSize = (int)sqrt(npath) + 1;

    sort(mo, mo + q, moDataCmp);
    int moStart = mo[0].l;
    int moEnd = moStart - 1;
    // FR(i,npath) cerr<<path[i]<<" ";
    // cerr<<endl;

    FR(i,q) {
        int l = mo[i].l;
        int r = mo[i].r;
        while(moStart < l) moRemove(moStart ++);
        while(moStart > l) moAdd(--moStart);
        while(moEnd < r) moAdd(++moEnd);
        while(moEnd > r) moRemove(moEnd--);
        if(mo[i].add == -1) {
            ret[mo[i].id] = re;
        } else {
            int p = mo[i].add;
            _add(f[p], isGirl[p], 1);
            ret[mo[i].id] = re;
            _add(f[p], isGirl[p], -1);
        }
    }

    FR(i,q) printf("%lld\n",ret[i]);

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

#define int long long
// #define double long double
#define FOR(i, a, b) for(ll i = (a); i < (b); ++i)
#define FORR(i, a, b) for(ll i = (a); i > (b); --i)
#define REP(i, n) for(ll i = 0; i < (n); ++i)
#define REPR(i, n) for(ll i = n; i >= 0; i--)
#define FOREACH(x, a) for(auto &(x) : (a))
#define VECCIN(x)                                                              \
    for(auto &youso_ : (x)) cin >> youso_
#define bitcnt __builtin_popcount
#define SZ(x) ((ll)(x).size())
#define fi first
#define se second
#define All(a) (a).begin(), (a).end()
#define rAll(a) (a).rbegin(), (a).rend()
template <typename T = long long> inline T IN() {
    T x;
    cin >> x;
    return (x);
}
inline void CIN() {}
template <class Head, class... Tail>
inline void CIN(Head &&head, Tail &&... tail) {
    cin >> head;
    CIN(move(tail)...);
}
#define CCIN(...)                                                              \
    char __VA_ARGS__;                                                          \
    CIN(__VA_ARGS__)
#define DCIN(...)                                                              \
    double __VA_ARGS__;                                                        \
    CIN(__VA_ARGS__)
#define LCIN(...)                                                              \
    ll __VA_ARGS__;                                                            \
    CIN(__VA_ARGS__)
#define SCIN(...)                                                              \
    string __VA_ARGS__;                                                        \
    CIN(__VA_ARGS__)
#define Printv(v)                                                              \
    {                                                                          \
        REP(x, v.size()) { cout << v[x] << (x == v.size() - 1 ? "\n" : " "); } \
    }
template <typename T = string> inline void eputs(T s) {
    cout << s << "\n";
    exit(0);
}
template <typename A, size_t N, typename T>
void Fill(A (&array)[N], const T &val) {
    std::fill((T *)array, (T *)(array + N), val);
}
template <typename T> using PQG = priority_queue<T, vector<T>, greater<T>>;
template <typename T> using PQ = priority_queue<T>;

typedef long long ll;
typedef pair<ll, ll> PL;
typedef vector<PL> VPL;
typedef vector<ll> VL;
typedef vector<VL> VVL;
typedef vector<double> VD;

#define uni int;

const int INF = 1e9;
const int MOD = 1e9 + 7;
const ll LINF = 1e18;
const ll dx[] = {1, 0, -1, 0};
const ll dy[] = {0, 1, 0, -1};
#define PI 3.141592653589793238

struct Mo_Tree_Vertex {
    vector<vector<int>> g, parent;
    vector<int> vs, in;

    vector<int> left, right, order, lca, dep;
    vector<bool> v;
    int width;
    int nl, nr, ptr;

    Mo_Tree_Vertex(int n)
        : width((int)sqrt(2 * n - 1)), nl(0), nr(0), ptr(0), g(n), in(n),
          dep(n), v(n) {
        const auto lg = (int)(log2(n) + 1);
        parent.resize(lg, vector<int>(n));
        vs.reserve(2 * n - 1);
    }

    void add_edge(int x, int y) {
        g[x].push_back(y);
        g[y].push_back(x);
    }

    void dfs(int idx, int depth, int par) {
        in[idx] = (int)vs.size();
        dep[idx] = depth;
        parent[0][idx] = par;
        vs.push_back(idx);
        for(auto &to : g[idx]) {
            if(to == par) continue;
            dfs(to, depth + 1, idx);
            vs.push_back(to); // 本来のEuler-tourはidxだが,
                              // 今回は深い方の頂点をとりたいのでto
        }
    }

    int getlca(int u, int v) {
        if(dep[u] > dep[v]) swap(u, v);
        for(int k = 0; k < parent.size(); k++) {
            if(((dep[v] - dep[u]) >> k) & 1) {
                v = parent[k][v];
            }
        }
        if(u == v) return (u);
        for(int k = (int)parent.size() - 1; k >= 0; k--) {
            if(parent[k][u] != parent[k][v]) {
                u = parent[k][u];
                v = parent[k][v];
            }
        }
        return (parent[0][u]);
    }

    void insert(int x, int y) {
        if(in[x] > in[y]) swap(x, y);
        left.push_back(in[x] + 1);
        right.push_back(in[y] + 1);
        lca.push_back(getlca(x, y));
    }

    void prepare() {
        dfs(0, 0, -1);
        for(int k = 0; k + 1 < parent.size(); k++) {
            for(int i = 0; i < parent[k].size(); i++) {
                if(parent[k][i] == -1)
                    parent[k + 1][i] = -1;
                else
                    parent[k + 1][i] = parent[k][parent[k][i]];
            }
        }
    }

    void build() {
        order.resize(left.size());
        iota(begin(order), end(order), 0);
        sort(begin(order), end(order), [&](int a, int b) {
            if(left[a] / width != left[b] / width) return left[a] < left[b];
            return right[a] < right[b];
        });
    }

    int process() {
        if(ptr == order.size()) return (-1);
        if(ptr > 0)
            distribute(lca[order[ptr - 1]]); // 前のクエリで追加したLCAを削除
        const auto id = order[ptr];
        while(nl > left[id]) distribute(vs[--nl]);
        while(nr < right[id]) distribute(vs[nr++]);
        while(nl < left[id]) distribute(vs[nl++]);
        while(nr > right[id]) distribute(vs[--nr]);
        distribute(lca[id]); // LCA の頂点を例外として追加する
        return (order[ptr++]);
    }

    /* 偶数回目の訪問時は削除, 奇数回目の訪問時は追加を呼び出す */
    inline void distribute(int vertex) {
        v[vertex].flip();
        if(v[vertex])
            add(vertex);
        else
            del(vertex);
    }

    void add(int idx);

    void del(int idx);
};

ll N, Q, val[100000];
bool bg[100000];
ll cnt1[100000], cnt2[100000], sum, ans[100000];

void Mo_Tree_Vertex::add(int idx) {
    if(bg[idx]) {
        cnt1[val[idx]]++;
        sum += cnt2[val[idx]];
    } else {
        cnt2[val[idx]]++;
        sum += cnt1[val[idx]];
    }
}

void Mo_Tree_Vertex::del(int idx) {
    if(bg[idx]) {
        sum -= cnt2[val[idx]];
        cnt1[val[idx]]--;
    } else {
        sum -= cnt1[val[idx]];
        cnt2[val[idx]]--;
    }
}

signed main() {
    cin >> N;
    VL com;
    REP(i, N) cin >> bg[i];
    REP(i, N) cin >> val[i], com.emplace_back(val[i]);
    sort(All(com));
    com.erase(unique(All(com)), com.end());
    REP(i, N) val[i] = lower_bound(All(com), val[i]) - com.begin();
    Mo_Tree_Vertex mo(N);
    REP(i, N - 1) {
        LCIN(a, b);
        mo.add_edge(--a, --b);
    }
    mo.prepare();
    cin >> Q;
    REP(i, Q) {
        LCIN(a, b);
        mo.insert(--a, --b);
    }
    mo.build();
    REP(i, Q) { ans[mo.process()] = sum; }
    REP(i, Q) { cout << ans[i] << "\n"; }
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return bel[a.v]<bel[b.v];
	return a.u<b.u;
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return bel[a.u]&1?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return a.u<b.u;
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <math.h>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return (bel[a.u]&1)?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>=Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	Bsz=sqrt(n*2)+1e-6;
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v,cnt;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30],dfn[maxn];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return bel[a.u]&1?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	dfn[rt]=++cnt;
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn];
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return bel[a.v]<bel[b.v];
	return a.u<b.u;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <stack>
#include <cstring>
#include <algorithm>
using namespace std;
const int maxn=2e5+5;
struct node{
	int num,type;
};
char s[maxn];
stack<node>S1;
int q[maxn],idx;
int len,sum,temp;
bool judge(int w){
	int s=0;
	temp=w;
	while (w>0){
		s+=w%10;
		w/=10;
	}
	if (s<=9) return true;
	return false;
}
bool dfs(int r,int cost){
	if (r==0)
		if (judge(cost)) return true;
		else return false;
	if (r>9){
		q[++idx]=2;
		if (dfs(r/100,cost+r%100))
			return true;
		idx--;
	}
	q[++idx]=1;
	if (dfs(r/10,cost+r%10)) return true;
	idx--;
	return false;
}
void dfs1(int w){
	int k=w%10;
	if (w/10==0)
		printf("%d",k);
	else{
		dfs1(w/10);
		printf("+%d",k);
	}
}
int main(){
	scanf("%d",&len);
	scanf("%s",s);
	//len=strlen(s);
	for (int i=0;i<len;i++)
		sum+=s[i]-'0';
	bool flag=false;
	if (len==197523) printf("%d\n",sum);
	if (dfs(sum,0)){
		for (int i=0;i<len;i++)
			printf("%c%c",s[i],"+\n"[i==len-1]);
	}else
	for (int i=0;i<len-1;i++){
		if (flag) break;
		sum=sum+(s[i]-'0')*10-(s[i]-'0');
		if (dfs(sum,0)){
			for (int j=0;j<len;j++){
				printf("%c",s[j]);
				if (j!=i&&j!=len-1) printf("+");
			}
			printf("\n");
			break;
		}
		sum=sum-(s[i]-'0')*10+(s[i]-'0');
	}
	int i=1;
	while (sum>0){
		int u=q[i++];
		if (u==2){
			S1.push({sum%100,2});
			sum/=100;
		}else{
			S1.push({sum%10,1});
			sum/=10;
		}
	}
	while (!S1.empty()){
		node u=S1.top();
		S1.pop();
		if (u.num<=9&&u.type==2)
			printf("0%d",u.num);
		else printf("%d",u.num);
		if (S1.empty())
			printf("\n");
		else printf("+");
	}
	dfs1(temp);
}/*999999999999999999999999999999991*/


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <math.h>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return (bel[a.u]&1)?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>=Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	Bsz=sqrt(n*2)+1e-6;
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
	//	if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <math.h>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v,top;
int bel[maxn],depth[maxn],f[maxn],col[maxn],sta[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return (bel[a.u]&1)?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=top;
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (top-st>=Bsz){
			index++;
			while (top>st) bel[sta[top--]]=index;
		}
	}
	sta[++top]=rt;
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	for (int i=0;i<=20;i++)
		if ((1<<i)&t) u=rmq[u][i];/*
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}*/
	for (int i=20;i>=0;i--)
		if (rmq[u][i]!=rmq[v][i])
			u=rmq[u][i],v=rmq[v][i];
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	Bsz=sqrt(n*2)+1e-6;
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (top>0) bel[sta[top--]]=index;
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);//¿´Çé¿ö
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <math.h>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v,top;
int bel[maxn],depth[maxn],f[maxn],col[maxn],sta[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return (bel[a.u]&1)?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=top;
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (top-st>=Bsz){
			index++;
			while (top>st) bel[sta[top--]]=index;
		}
	}
	sta[++top]=rt;
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	Bsz=sqrt(n*2)+1e-6;
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (top>0) bel[sta[top--]]=index;
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);//¿´Çé¿ö
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn];
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][21];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return bel[a.v]<bel[b.v];
	return a.u<b.u;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v,cnt;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30],dfn[maxn];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return dfn[a.v]<dfn[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	dfn[rt]=++cnt;
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>=Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	Bsz=sqrt(n*2)+1e-6;
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v,cnt;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30],dfn[maxn];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return dfn[a.v]<dfn[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	dfn[rt]=++cnt;
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return bel[a.u]&1?bel[a.v]<bel[b.v]:bel[a.v]>bel[b.v];
	return a.u<b.u;
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
	//	if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


#include <iostream>
#include <cstring>
#include <algorithm>
#include <stack>
#include <vector>
#include <math.h>
using namespace std;
const int maxn=1e5+5;
struct node{
	int u,v,id;
}Q[maxn];
vector<int>G[maxn],b;
int t[2]={1,-1};
long long Ans[maxn];
int Bsz,index,q,n,u,v,cnt;
int bel[maxn],depth[maxn],f[maxn],col[maxn];
bool sex[maxn];
int num[maxn][2],rmq[maxn][30],dfn[maxn];//col  sex
bool flag[maxn];
stack<int>Sta;
long long ans=0;
bool operator<(node a,node b){
	if (bel[a.u]==bel[b.u]) return dfn[a.v]<dfn[b.v];
	return bel[a.u]<bel[b.u];
}
int getid(int w){
	return lower_bound(b.begin(),b.end(),w)-b.begin()+1;
}
void dfs(int rt,int fa){
	dfn[rt]=++cnt;
	depth[rt]=depth[fa]+1;f[rt]=fa;
	int st=Sta.size();
	for (int i=0;i<G[rt].size();i++){
		if (G[rt][i]==fa) continue;
		dfs(G[rt][i],rt);
		if (Sta.size()-st>=Bsz){
			index++;
			while (Sta.size()>st){
				bel[Sta.top()]=index;
				Sta.pop();
			}
		}
	}
	Sta.push(rt);
}
void done(int w){
	num[col[w]][sex[w]]+=t[flag[w]];
	ans=ans+t[flag[w]]*num[col[w]][sex[w]^1];
	flag[w]^=1;
}
void update(int a,int b){
	while (a!=b){
		if (depth[b]>=depth[a])	done(b),b=f[b];
		else done(a),a=f[a];
	}
}
void getrmq(){
	for (int i=1;i<=n;i++)
		rmq[i][0]=f[i];
	for (int i=1;i<=20;i++)
		for (int j=1;j<=n;j++)
			rmq[j][i]=rmq[rmq[j][i-1]][i-1];
}
int lca(int u,int v){
	if (depth[u]<depth[v]) swap(u,v);
	int t=depth[u]-depth[v],cnt=0;
	while (t>0){
		if (t&1) u=rmq[u][cnt];
		t>>=1; cnt++;
	}
	cnt=20;
	while (cnt>=0){
		if (rmq[u][cnt]!=rmq[v][cnt]){
			u=rmq[u][cnt];v=rmq[v][cnt];
		}
		cnt--;
	}
	if (u!=v)
		u=rmq[u][0],v=rmq[v][0];
	return u;
}
int main(){
	scanf("%d",&n);
	Bsz=sqrt(n*2)+1e-6;
	for (int i=1;i<=n;i++)
		scanf("%d",&sex[i]);
	for (int i=1;i<=n;i++)
		scanf("%d",&col[i]),b.push_back(col[i]);
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	for (int i=1;i<=n;i++)
		col[i]=getid(col[i]);
	for (int i=1;i<n;i++){
		scanf("%d%d",&u,&v);
		G[u].push_back(v);
		G[v].push_back(u);
	}
	dfs(1,0);
	index++;
	while (Sta.size()>0){
		bel[Sta.top()]=index;
		Sta.pop();
	}
	getrmq();
	scanf("%d",&q);
	for (int i=1;i<=q;i++){
		scanf("%d%d",&Q[i].u,&Q[i].v);
		if (bel[Q[i].u]<bel[Q[i].v]) swap(Q[i].u,Q[i].v);
		Q[i].id=i;
	}
	sort(Q+1,Q+1+q);
	int u=1,v=1;
	for (int i=1;i<=q;i++){
		update(u,Q[i].u);
		update(v,Q[i].v);
		u=Q[i].u;v=Q[i].v;
		int LCA=lca(u,v);
		done(LCA);
		Ans[Q[i].id]=ans;
		done(LCA);
	}
	for (int i=1;i<=q;i++)
		printf("%lld\n",Ans[i]);
}


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

#define endl '\n'

void io(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    cout.tie(0);
    cout.precision(15);
}
const int MAXN = 1e5 + 5 ;
const int LN = 21 ;
const int SQRT = 420 ;
int boy[MAXN] ;
int F[MAXN] ;
map<int,int> zip ;
vector<int> g[MAXN] ;
int pa[LN][MAXN] ;
int tin[MAXN], tout[MAXN] ;
int pool ;
int n ;
struct Query{
    int u,v,lca;
    int ql,qr ;
    int id ;
    bool operator < (const Query& rr){
        int bl = ql/SQRT ;
        int br = rr.ql/SQRT ;
        if(bl != br){
            return bl < br ;
        }
        return qr < rr.qr ;
    }
};
Query query[MAXN] ;
long long qans[MAXN] ;
int nodeAt[MAXN*2] ;
int depth[MAXN] ;
void dfs(int u,int p){
    pa[0][u] = p ;
    depth[u] = depth[p] + 1 ;
    tin[u] = ++pool ;
    nodeAt[pool] = u ;
    for(auto v:g[u]){
        if(v != p){
            dfs(v,u) ;
        }
    }
    tout[u] = ++pool ;
    nodeAt[pool] = u ;
}
void preprocess(){
    for(int j = 1; j < LN; j++){
        for(int i = 1; i <= n ;i++){
            if(pa[j-1][i] != 0){
                pa[j][i] = pa[j-1][pa[j-1][i]] ;
            }
        }
    }
}
int LCA(int u,int v){
    if(depth[u] < depth[v]) swap(u,v) ;
    int d = depth[u] - depth[v] ;
    for(int j = 0 ; j < LN; j++) {
            if((d >> j)&1) u = pa[j][u] ;
    }
    if(u == v) return u ;
    for(int j = LN - 1; j >= 0; j--){
        if(pa[j][u] != pa[j][v]){
            u = pa[j][u] ;
            v = pa[j][v] ;
        }
    }
    return pa[0][u] ;
}
int cnt[MAXN][2] ;
int vis[MAXN] ;
long long fans ;
void update(int i){
    int u = nodeAt[i] ;
    if(vis[u]){
        fans -= cnt[F[u]][boy[u]^1] ;
        cnt[F[u]][boy[u]]-- ;
    }
    else{
        fans += cnt[F[u]][boy[u]^1] ;
        cnt[F[u]][boy[u]]++ ;
    }
    vis[u] ^= 1;
}
int main(int argc,char* argv[]) {
    io() ;
    cin >> n ;
    for(int i = 1; i <= n; i++){
        cin >> boy[i] ;
    }
    for(int i = 1; i <= n; i++){
        cin >> F[i] ;
        zip[F[i]] ;
    }
    int cntr = 0 ;
    for(auto it:zip){
        zip[it.first] = ++cntr ;
    }
    for(int i = 1; i <= n; i++){
        F[i] = zip[F[i]] ;
    }
    for(int i = 1; i < n; i++){
        int u,v ;
        cin >> u >> v ;
        g[u].push_back(v) ;
        g[v].push_back(u) ;
    }
    dfs(1,0) ;
    preprocess();
    int q ;
    cin >> q ;
    for(int i = 0; i < q; i++){
        int u,v ;
        cin >> u >> v ;
        if(tin[u] > tin[v]) swap(u,v) ;
        int lca = LCA(u,v);
        query[i].id = i ;
        query[i].u = u ;
        query[i].v = v ;
        if(u == lca){
            query[i].ql = tin[u] ;
            query[i].qr = tin[v] ;
        }
        else{
            query[i].lca = lca ;
            query[i].ql = tout[u] ;
            query[i].qr = tin[v] ;
        }
    }
    sort(query, query + q) ;
    int mo_l = 1 ;
    int mo_r = 1 ;
    cnt[F[1]][boy[1]]++ ;
    vis[1] = 1 ;

    for(int i = 0; i < q; i++){
        int id = query[i].id ;
        int l = query[i].ql ;
        int r = query[i].qr ;
        while(mo_l < l){
            update(mo_l) ;
            mo_l++ ;
        }
        while(mo_r > r){
            update(mo_r) ;
            mo_r-- ;
        }
        while(mo_l > l){
            mo_l-- ;
            update(mo_l) ;
        }
        while(mo_r < r){
            mo_r++ ;
            update(mo_r) ;
        }
        if(query[i].lca != 0){
            update(tin[query[i].lca]) ;
        }
        qans[id] = fans ;
        if(query[i].lca != 0){
            update(tin[query[i].lca]) ;
        }
    }
    for(int i = 0; i < q; i++){
        cout << qans[i] << endl ;
    }
    return 0 ;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

string rev(string s) {
       string res = "";
       for(int i = s.length() - 1; i >= 0; --i)
               res += s[i];
       return res;
}

vector<int> p_func(string s) {
            int n = s.length(), k = 0;
            vector<int> p(n, 0);
            for(int i = 1; i < n; ++i) {
                    while(s[i] != s[k] && k > 0)
                               k = p[k - 1];
                    if(s[i] == s[k])
                            ++k;
                    p[i] = k;
            }
            return p;
}

int main() {
    string s;

    cin >> s;

    int n, res = 0;

    cin >> n;

    for(int j = 0; j < n; ++j) {
            bool found = false;
            string patt;
            cin >> patt;
            vector<int> p1, p;
            int m = patt.length();
            if(m == 1)
                 continue;
            vector<int> suff(m + 1, -1);
            vector<int> pref(m + 1, 1000 * 1000);
            string q = patt + '#' + s;
            p = p_func(q);
            q = rev(patt) + '#' + rev(s);
            p1 = p_func(q);
            for(int i = m + 1; i < q.length(); ++i)
                    for(int k = p[i]; k <= p[i]; ++k)
                            pref[k] = min(pref[k], i - m - 1);
            for(int i = m + 1; i < q.length(); ++i)
                    for(int k = p[i]; k <= p1[i]; ++k)
                            suff[k] = max(suff[k], (int)((int)s.length() - (i - m)));
            for(int i = 0; i <= m; ++i)
                    for(int k = patt.length() - i; k <= m; ++k)
                            if(i + k >= patt.length() && suff[i] > pref[k])
                                 found = true;

            res += found;
    }

    cout << res;

    return 0;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

string rev(string s) {
       string res = "";
       for(int i = s.length() - 1; i >= 0; --i)
               res += s[i];
       return res;
}

vector<int> p_func(string s) {
            int n = s.length(), k = 0;
            vector<int> p(n, 0);
            for(int i = 1; i < n; ++i) {
                    while(s[i] != s[k] && k > 0)
                               k = p[k - 1];
                    if(s[i] == s[k])
                            ++k;
                    p[i] = k;
            }
            return p;
}

int main() {
    string s;

    cin >> s;

    int n, res = 0, len = s.length();

    cin >> n;

    for(int j = 0; j < n; ++j) {
            bool found = false;
            string patt;
            cin >> patt;
            vector<int> p1, p;
            int m = patt.length();
            if(m == 1)
                 continue;
            vector<int> suff(m + 1, -1);
            vector<int> pref(m + 1, 1000 * 1000);
            string q = patt + '#' + s;
            p = p_func(q);
            q = rev(patt) + '#' + rev(s);
            p1 = p_func(q);
            for(int i = m + 1; i < q.length(); ++i)
                    for(int k = 0; k <= p[i]; ++k)
                            pref[k] = min(pref[k], i - m - 1);
            for(int i = m + 1; i < q.length(); ++i)
                    for(int k = 0; k <= p1[i]; ++k)
                            suff[k] = max(suff[k], (int)((int)len - (i - m)));
            for(int i = 0; i <= m; ++i)
                  if(suff[i] > pref[m - i]) {
                             found = true;
                             break;
                  }

            res += found;
    }

    cout << res;

    return 0;
}


#include <iostream>
#include <string>
#include <vector>
using namespace std;

string rev(string s) {
       string res = "";
       for(int i = s.length() - 1; i >= 0; --i)
               res += s[i];
       return res;
}

vector<int> p_func(string s) {
            int n = s.length(), k = 0;
            vector<int> p(n, 0);
            for(int i = 1; i < n; ++i) {
                    while(s[i] != s[k] && k > 0)
                               k = p[k - 1];
                    if(s[i] == s[k])
                            ++k;
                    p[i] = k;
            }
            return p;
}

vector<int> z_func(string s) {
            int n = s.length();
            vector<int> z(n, 0);
            for(int i = 0, r = 0, l = 0; i < n; ++i) {
                    if(i <= r)
                         z[i] = min(z[i - l], r - i + 1);
                    while(i + z[i] < n && s[z[i]] == s[i + z[i]])
                            ++z[i];
                    if(i + z[i] - 1 > r)
                         r = i + z[i] - 1, l = i;
            }
            return z;
}

int main() {
    string s;

    cin >> s;

    int n, res = 0;

    cin >> n;

    for(int j = 0; j < n; ++j) {
            bool found = false;
            string patt;
            cin >> patt;
            vector<int> p1, p;
            int m = patt.length();
            if(m == 1)
                 continue;
            vector<int> suff(m + 1, -1);
            vector<int> pref(m + 1, 1000 * 1000);
            string q = patt + '#' + s;
            p = p_func(q);
            q = rev(patt) + '#' + rev(s);
            p1 = p_func(q);
            for(int i = m + 1; i < q.length(); ++i)
                    for(int k = 0; k <= p[i]; ++k)
                            pref[k] = min(pref[k], i - m - 1);
            for(int i = m + 1; i < q.length(); ++i)
                    for(int k = 0; k <= p1[i]; ++k)
                            suff[k] = max(suff[k], (int)((int)s.length() - (i - m)));
            for(int i = 0; i <= m; ++i)
                    for(int k = 0; k <= m; ++k)
                            if(i + k >= patt.length() && suff[i] > pref[k])
                                 found = true;

            res += found;
    }

    cout << res;

    cin >> n;

    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 100100

char g[N];
int next[1010];
int next1[1010];
char t[1010],t1[1010];
int sum[N];

int main()
{
    //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
    //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
    scanf("%s",g);
    int n;
    int len=strlen(g);
    scanf("%d",&n);
    int ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%s",t);
        int len1=strlen(t);
        next[0]=len1;
        next[1]=0;
        int j=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0 && t[j]!=t[k]) j=next[j];
            if(t[j]==t[k])
                j++;
            next[k+1]=j;
        }
        memset(sum,0,sizeof(sum));
        j=0;
        int tmp=0,flag=0;
        for(int k=0;k<len;k++)
        {
            while(j!=0&&g[k]!=t[j]) j=next[j];
            if(g[k]==t[j]) j++;
            if(j!=len1)
                tmp=max(j,tmp);
            sum[k]=tmp;
            if(j==len1)
            {
                j=next[j];
            }
        }
        for(int j=0;j<len1;j++)
            t1[len1-1-j]=t[j];
        j=0;
        next1[0]=len1;
        next1[1]=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0&&t1[k]!=t1[j]) j=next1[j];
            if(t1[k]==t1[j]) j++;
            next1[k+1]=j;
        }
        j=0;
        for(int k=len-1;k>=0;k--)
        {
            while(j!=0&&t1[j] != g[k]) j=next1[j];
            if(t1[j]==g[k]) j++;
            if(k>1&&j+sum[k-2]>=len1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1) ans++;
    }
    printf("%d\n",ans);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 100100

char g[N];
int next[1010];
int next1[1010];
char t[1010],t1[1010];
int sum[N];

int main()
{
    //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
    //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
    scanf("%s",g);
    int n;
    int len=strlen(g);
    scanf("%d",&n);
    int ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%s",t);
        int len1=strlen(t);
        if(len1==1)
        {
            continue;
        }
        next[0]=len1;
        next[1]=0;
        int j=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0 && t[j]!=t[k]) j=next[j];
            if(t[j]==t[k])
                j++;
            next[k+1]=j;
        }
        memset(sum,0,sizeof(sum));
        j=0;
        int tmp=0,flag=0;
        for(int k=0;k<len;k++)
        {
            while(j!=0&&g[k]!=t[j]) j=next[j];
            if(g[k]==t[j]) j++;
            if(j!=len1)
                tmp=max(j,tmp);
            else
            {
                flag=1;
                break;
            }
            sum[k]=tmp;
            if(j==len1)
            {
                j=next[j];
            }
        }
        if(flag==1)
        {
            ans++;
            continue;
        }
        for(int j=0;j<len1;j++) //我知道了
            t1[len1-1-j]=t[j];
        j=0;
        next1[0]=len1;
        next1[1]=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0&&t1[k]!=t1[j]) j=next1[j];
            if(t1[k]==t1[j]) j++;
            next1[k+1]=j;
        }
        j=0;
        flag=0;
        for(int k=len-1;k>=0;k--)
        {
            while(j!=0&&t1[j] != g[k]) j=next1[j];
            if(t1[j]==g[k]) j++;
            if(k>0&&j+sum[k-1]>=len1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1) ans++;
    }
    printf("%d\n",ans);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 100100

char g[N];
int next[1010];
int next1[1010];
char t[1010],t1[1010];
int sum[N];

int main()
{
    //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
    //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
    scanf("%s",g);
    int n;
    int len=strlen(g);
    scanf("%d",&n);
    int ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%s",t);
        int len1=strlen(t);
        if(len1==1)
        {
            continue;
        }
        next[0]=len1;
        next[1]=0;
        int j=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0 && t[j]!=t[k]) j=next[j];
            if(t[j]==t[k])
                j++;
            next[k+1]=j;
        }
        memset(sum,0,sizeof(sum));
        j=0;
        int tmp=0,flag=0;
        for(int k=0;k<len;k++)
        {
            while(j!=0&&g[k]!=t[j]) j=next[j];
            if(g[k]==t[j]) j++;
            if(j!=len1)
                tmp=max(j,tmp);
            sum[k]=tmp;
            if(j==len1)
            {
                j=next[j];
            }
        }
        for(int j=0;j<len1;j++)
            t1[len1-1-j]=t[j];
        j=0;
        next1[0]=len1;
        next1[1]=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0&&t1[k]!=t1[j]) j=next1[j];
            if(t1[k]==t1[j]) j++;
            next1[k+1]=j;
        }
        j=0;
        for(int k=len-1;k>=0;k--)
        {
            while(j!=0&&t1[j] != g[k]) j=next1[j];
            if(t1[j]==g[k]) j++;
            if(k>1&&j+sum[k-2]>=len1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1) ans++;
    }
    printf("%d\n",ans);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 100100

char g[N];
int next[1010];
int next1[1010];
char t[1010],t1[1010];
int sum[N];

int main()
{
    //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
    //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
    scanf("%s",g);
    int n;
    int len=strlen(g);
    scanf("%d",&n);
    int ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%s",t);
        int len1=strlen(t);
        next[0]=len1;
        next[1]=0;
        int j=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0 && t[j]!=t[k]) j=next[j];
            if(t[j]==t[k])
                j++;
            next[k+1]=j;
        }
        memset(sum,0,sizeof(sum));
        j=0;
        int tmp=0,flag=0;
        for(int k=0;k<len;k++)
        {
            while(j!=0&&g[k]!=t[j]) j=next[j];
            if(g[k]==t[j]) j++;
            tmp=max(j,tmp);
            sum[k]=tmp;
            if(j==len1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1)
        {
            ans++;
            continue;
        }
        for(int j=0;j<len1;j++)
            t1[len1-1-j]=t[j];
        j=0;
        next1[0]=len1;
        next1[1]=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0&&t1[k]!=t1[j]) j=next1[j];
            if(t1[k]==t1[j]) j++;
            next1[k+1]=j;
        }
        j=0;
        for(int k=len-1;k>=0;k--)
        {
            while(j!=0&&t1[j] != g[k]) j=next1[j];
            if(t1[j]==g[k]) j++;
            if(k!=0&&j+sum[k-1]>=len1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1) ans++;
    }
    printf("%d\n",ans);
    return 0;
}


#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <algorithm>
#include <math.h>
#include <map>
#include <queue>
#include <sstream>
#include <iostream>
using namespace std;
#define INF 0x3fffffff
#define N 100100

char g[N];
int next[1010];
int next1[1010];
char t[1010],t1[1010];
int sum[N];

int main()
{
    //freopen("//home//chen//Desktop//ACM//in.text","r",stdin);
    //freopen("//home//chen//Desktop//ACM//out.text","w",stdout);
    scanf("%s",g);
    int n;
    int len=strlen(g);
    scanf("%d",&n);
    int ans=0;
    for(int i=0;i<n;i++)
    {
        scanf("%s",t);
        int len1=strlen(t);
        if(len1==1)
        {
            continue;
        }
        next[0]=len1;
        next[1]=0;
        int j=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0 && t[j]!=t[k]) j=next[j];
            if(t[j]==t[k])
                j++;
            next[k+1]=j;
        }
        memset(sum,0,sizeof(sum));
        j=0;
        int tmp=0,flag=0;
        for(int k=0;k<len;k++)
        {
            while(j!=0&&g[k]!=t[j]) j=next[j];
            if(g[k]==t[j]) j++;
            if(j!=len1)
                tmp=max(j,tmp);
            sum[k]=tmp;
            if(j==len1)
            {
                j=next[j];
            }
        }
        for(int j=0;j<len1;j++) //我知道了
            t1[len1-1-j]=t[j];
        j=0;
        next1[0]=len1;
        next1[1]=0;
        for(int k=1;k<len1;k++)
        {
            while(j!=0&&t1[k]!=t1[j]) j=next1[j];
            if(t1[k]==t1[j]) j++;
            next1[k+1]=j;
        }
        j=0;
        for(int k=len-1;k>=0;k--)
        {
            while(j!=0&&t1[j] != g[k]) j=next1[j];
            if(t1[j]==g[k]) j++;
            if(j==len1) break;
            if(k>1&&j+sum[k-2]>=len1)
            {
                flag=1;
                break;
            }
        }
        if(flag==1) ans++;
    }
    printf("%d\n",ans);
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <map>

using namespace std;

typedef pair<int, int> PII;

map<string, PII> h;

int main()
{
    string s;
    cin >> s;
    int m, MAX = 0;
    scanf("%d", &m);
    string word[m];
    for (int i = 0; i < m; i++) {
        cin >> word[i];
        if (word[i].size() > MAX) MAX = word[i].size();
    }
    for (int j = 1; j < MAX; j++)
        for (int i = 0; i < s.size() - j + 1; i++) {
            string ss = s.substr(i, j);
            if (h.find(ss) != h.end()) h[ss].second = i;
            else h[ss] = make_pair(i, i);
        }
    int ans = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < word[i].size() - 1; j++) {
            string s1 = word[i].substr(0, j + 1);
            string s2 = word[i].substr(j + 1, word[i].size() - (j + 1));
            int left = -1, right = -1;
            if (h.find(s1) != h.end()) left = h[s1].first;
            if (h.find(s2) != h.end()) right = h[s2].second;
            if (left + j < right && left > -1 && right > -1) {
                ans++;
                break;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <map>

using namespace std;

typedef pair<int, int> PII;

map<string, PII> h;

int main()
{
    string s;
    cin >> s;
    int m, MAX = 0;
    scanf("%d", &m);
    string word[m];
    for (int i = 0; i < m; i++) {
        cin >> word[i];
        if (word[i].size() > MAX) MAX = word[i].size();
    }
    for (int j = 1; j < MAX; j++)
        for (int i = 0; i < s.size() - j + 1; i++) {
            string ss = s.substr(i, j);
            if (h.find(ss) != h.end()) h[ss].second = i;
            else h[ss] = make_pair(i, i);
        }
    int ans = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < word[i].size() - 1; j++) {
            int left, right;
            string s1 = word[i].substr(0, j + 1);
            if (h.find(s1) != h.end()) left = h[s1].first;
            else break;
            string s2 = word[i].substr(j + 1, word[i].size() - (j + 1));
            if (h.find(s2) != h.end()) right = h[s2].second;
            else continue;
            if (left + j < right) {
                ans++;
                break;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>

using namespace std;

int P[1000], pref[1000], suff[1000];

void pre_kmp(string B)
{
    int i, j;
    P[0] = j = -1;
    for (i = 1; i < B.size(); i++) {
        while (j > -1 && B[j + 1] != B[i]) j = P[j];
        if (B[j + 1] == B[i]) j++;
        P[i] = j;
    }
}

void kmp(string A, string B, int f[])
{
    int i, j = -1;
    for (i = 0; i < A.size(); i++) {
        while (j > -1 && B[j + 1] != A[i]) j = P[j];
        if (B[j + 1] == A[i]) j++;
        if (j > -1 && f[j] == -1) f[j] = i - j;
        if (j == B.size() - 1) break;
    }
}

int main()
{
    string s, rs;
    cin >> s;
    rs = s;
    reverse(rs.begin(), rs.end());
    int m, ans = 0;
    scanf("%d", &m);
    string word[m];
    for (int i = 0; i < m; i++) {
        cin >> word[i];
        int len = word[i].size();
        for (int j = 0; j < len; j++) pref[j] = suff[j] = -1;
        pre_kmp(word[i]);
        kmp(s, word[i], pref);
        reverse(word[i].begin(), word[i].end());
        pre_kmp(word[i]);
        kmp(rs, word[i], suff);
        for (int j = 0; j < len; j++)
            if (suff[j] > -1) suff[j] = s.size() - (suff[j] + j + 1);
            else break;
        for (int j = 0; j < len - 1; j++) {
            if (pref[j] < 0) break;
            if (pref[j] + j < suff[len - 2 - j]) {
                ans++;
                break;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <map>

using namespace std;

typedef pair<int, int> PII;

map<string, PII> h;

int main()
{
    string s;
    cin >> s;
    int m, MAX = 0, len = s.size();
    scanf("%d", &m);
    string word[m];
    for (int i = 0; i < m; i++) {
        cin >> word[i];
        if (word[i].size() > MAX) MAX = word[i].size();
    }
    for (int j = 1; j < MAX; j++)
        for (int i = 0; i < len - j + 1; i++) {
            string ss = s.substr(i, j);
            if (h.find(ss) != h.end()) h[ss].second = i;
            else h[ss] = make_pair(i, i);
        }
    int ans = 0;
    for (int i = 0; i < m; i++) {
        for (int j = 0; j < word[i].size() - 1; j++) {
            int left, right;
            string s1 = word[i].substr(0, j + 1);
            if (h.find(s1) != h.end()) left = h[s1].first;
            else break;
            string s2 = word[i].substr(j + 1, word[i].size() - (j + 1));
            if (h.find(s2) != h.end()) right = h[s2].second;
            else continue;
            if (left + j < right) {
                ans++;
                break;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}


#include <iostream>
#include <stdio.h>
#include <algorithm>

using namespace std;

int P[1000], pref[1000], suff[1000];

inline void pre_kmp(string B)
{
    int i, j;
    P[0] = j = -1;
    for (i = 1; i < B.size(); i++) {
        while (j > -1 && B[j + 1] != B[i]) j = P[j];
        if (B[j + 1] == B[i]) j++;
        P[i] = j;
    }
}

inline void kmp(string A, string B, int f[])
{
    int i, j = -1;
    for (i = 0; i < A.size(); i++) {
        while (j > -1 && B[j + 1] != A[i]) j = P[j];
        if (B[j + 1] == A[i]) j++;
        if (j > -1 && f[j] == -1) f[j] = i - j;
        if (j == B.size() - 1) break;
    }
}

int main()
{
    string s, rs;
    cin >> s;
    rs = s;
    reverse(rs.begin(), rs.end());
    int m, ans = 0;
    scanf("%d", &m);
    string word[m];
    for (int i = 0; i < m; i++) {
        cin >> word[i];
        int len = word[i].size();
        for (int j = 0; j < len; j++) pref[j] = suff[j] = -1;
        pre_kmp(word[i]);
        kmp(s, word[i], pref);
        reverse(word[i].begin(), word[i].end());
        pre_kmp(word[i]);
        kmp(rs, word[i], suff);
        for (int j = 0; j < len; j++)
            if (suff[j] > -1) suff[j] = s.size() - (suff[j] + j + 1);
            else break;
        for (int j = 0; j < len - 1; j++) {
            if (pref[j] < 0) break;
            if (pref[j] + j < suff[len - 2 - j]) {
                ans++;
                break;
            }
        }
    }
    printf("%d\n", ans);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
#define MAX 100000
using namespace std;

char s[MAX + 5] , p[1005], aux[MAX + 1005];
int len , lp, ls, z[MAX + 1009], suf[1009], pre[1009];

void z_function(){

	for( int i = 1, l = 0, r = 0; i < len; i++){

		z[i] = 0;

		if( i <= r)

			z[i] = min (z[i - l], r - i + 1);

		while( i + z[i] < len && aux[z[i]] == aux [ i + z[i]])

			z[i] ++;

		if( r < z[i] + i - 1)

			r = z[i] + i - 1, l = i;
	}
}
bool solve(){

	for( int i = 0; i <= lp; i ++)

		pre[i] = oo, suf[i] = -1;

	for( int i = 0; i < lp; i++)

		aux[i] = p[i];

	aux[lp] = '*';

	for( int i = 0; i < ls; i++)

		aux[i + lp + 1] = s[i];

	len = lp + ls + 1;

	z_function();

	for( int i = 0; i < ls; i++)

		pre[z[i + 1 + lp]] = min (pre[z[i + 1 + lp]], i);

	for( int i = lp - 1; i ; i --)

		pre[i] = min ( pre[i + 1], pre[i]);

	for( int i = 0; i < lp; i++)

		aux[i] = p[lp - i - 1];

	aux[lp] = '*';

	for( int i = 0; i < ls; i++)

		aux[i + lp + 1] = s[ls - i - 1];

	z_function();

	for( int i = 0; i < ls; i++)

		suf[z[i + 1 + lp]] = max (suf[z[i + 1 + lp]], ls - i - 1);

	for( int i = lp - 1; i ; i --)

		suf[i] = max ( suf[i + 1], suf[i]);

	for( int i = 1; i <= lp ; i++)

		if( pre[i] + lp - 1<= suf[lp - i]) return true;

	return false;
}
int main(){

	int r = 0, t;

	scanf("%s", s);
	ls = strlen(s);
	scanf("%d", &t);

	for( ; t; --t){

		scanf("%s", p);
		lp = strlen(p);

		if( lp > 1 && lp <= ls && solve())
			r ++;
	}

	printf("%d\n", r);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
using namespace std;

char s[100005], p[1005], tmp[101005];
int suf[1005], pre[1005], ls, lp, len, z[1005];

void z_function(){

    for( int i = 0; i <= len; i++) z[i] = 0;

    for( int i = 1, l = 0, r = 0; i < len; i++){

        if( i <= r) z[i] = min ( z[i - l] , r - i + 1);

        while( i + z[i] < len && tmp[i + z[i]] == tmp[z[i]]) z[i] ++;

        if( r < i + z[i] - 1){

            l = i;
            r = i + z[i] - 1;
        }

     }
}
bool factible(){

	for( int i = 0; i < lp; i++)

	        tmp[i] = p[i];

    tmp[lp] = '.';

	for( int i = 0; i < ls; i++)

	    tmp[i + lp + 1] = s[i];

    len = lp + ls + 1;
    for( int i = 0; i <= lp; i++) pre[i] = oo, suf[i] = -1;

    z_function();

    for( int i = 0; i < ls; i ++){
        pre[z[i + 1 + lp]] = min (i ,pre[z[i + 1 + lp]]) ;

        for( int j = 1; j < z[i + 1 + lp]; j++)
        	pre[j] =  min (i, pre[j] );

    }

    for( int i = 0;i < lp; i++)

        tmp[i] = p[lp - i - 1];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[ls - i - 1];

    z_function();

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

        suf[z[i + 1 + lp]] = max (ls - i - 1, suf[z[i + 1 + lp]]) ;

        for( int j = 1; j < z[ 1 + i + lp ]; j++){

        	suf[j] = max (ls - i - 1, suf[j] );
        }

    }

    for( int i = 1; i <= lp; i++)

        if( pre[i] <= suf[lp - i] - lp + 1)

        	return true;

    return false;
}

int main(){

    scanf("%s", s);
    int r = 0, t ; ls = strlen(s);

    scanf("%d", &t);

    for ( ; t ; t--){

        scanf("%s", p);
        lp = strlen(p);
        if( lp > ls || lp == 1) continue;

        if( factible()) r ++;

    }

    printf("%d\n", r);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
using namespace std;

char s[100005], p[1005], tmp[101005];
int suf[1005], pre[1005], ls, lp, len, z[1005];

void z_function(){

    for( int i = 0; i <= len; i++) z[i] = 0;

    for( int i = 1, l = 0, r = 0; i < len; i++){

        if( i <= r) z[i] = min ( z[i - l] , r - i + 1);

        while( i + z[i] < len && tmp[i + z[i]] == tmp[z[i]]) z[i] ++;

        if( r < i + z[i] - 1){

            l = i;
            r = i + z[i] - 1;
        }

     }
}
bool factible(){

    for( int i = 0; i < lp; i++)

            tmp[i] = p[i];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[i];

    len = lp + ls + 1;
    for( int i = 0; i <= lp; i++) pre[i] = oo, suf[i] = -1;

    z_function();

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

        if(pre[z[i + 1 + lp]] != oo) continue;
        pre[z[i + 1 + lp]] = i;
        for( int j = 1; j < z[i + 1 + lp]; j++){

            if(pre[j] != oo) continue;
            pre[j] = i;
        }
    }

    for( int i = 0;i < lp; i++)

        tmp[i] = p[lp - i - 1];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[ls - i - 1];

    z_function();

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

        if(suf[z[i + 1 + lp]] != -1) continue;
        suf[z[i + 1 + lp]] = ls - i - 1;

        for( int j = 1; j < z[ 1 + i + lp ]; j++){

            if( suf[j] != -1) continue;
            suf[j] = ls - i - 1;
        }

    }

    for( int i = 1; i <= lp; i++)

        if( pre[i] <= suf[lp - i] - lp + 1)

            return true;

    return false;
}

int main(){

    scanf("%s", s);
    int r = 0, t ; ls = strlen(s);

    scanf("%d", &t);

    for ( ; t ; t--){

        scanf("%s", p);
        lp = strlen(p);

        if( factible()) r ++;

    }

    printf("%d\n", r);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
using namespace std;

char s[100005], p[1005], tmp[101005];
int suf[1005], pre[1005], ls, lp, len, z[1005];

void z_function(){

    for( int i = 0; i <= len; i++) z[i] = 0;

    for( int i = 1, l = 0, r = 0; i < len; i++){

        if( i <= r) z[i] = min ( z[i - l] , r - i + 1);

        while( i + z[i] < len && tmp[i + z[i]] == tmp[z[i]]) z[i] ++;

        if( r < i + z[i] - 1){

            l = i;
            r = i + z[i] - 1;
        }

     }
}
bool factible(){

    for( int i = 0; i < lp; i++)

            tmp[i] = p[i];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[i];

    len = lp + ls + 1;
    for( int i = 0; i <= lp; i++) pre[i] = oo, suf[i] = -1;

    z_function();

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

        if(pre[z[i + 1 + lp]] != oo) continue;
        pre[z[i + 1 + lp]] = i;
        for( int j = 1; j < z[i + 1 + lp]; j++){

            if(pre[j] != oo) continue;
            pre[j] = i;
        }
    }

    for( int i = 0;i < lp; i++)

        tmp[i] = p[lp - i - 1];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[ls - i - 1];

    z_function();

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

        if(suf[z[i + 1 + lp]] != -1) continue;
        suf[z[i + 1 + lp]] = ls - i - 1;

        for( int j = 1; j < z[ 1 + i + lp ]; j++){

            if( suf[j] != -1) continue;
            suf[j] = ls - i - 1;
        }

    }

    for( int i = 1; i <= lp; i++)

        if( pre[i] <= suf[lp - i] - lp + 1)

            return true;

    return false;
}

int main(){

    scanf("%s", s);
    int r = 0, t ; ls = strlen(s);

    scanf("%d", &t);

    for ( ; t ; t--){

        scanf("%s", p);
        lp = strlen(p);
        if( lp > ls || lp == 1) continue;
        if( factible()) r ++;

    }

    printf("%d\n", r);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
#define MAX 10000
using namespace std;

char s[MAX + 5] , p[1005], aux[MAX + 1005];
int len , lp, ls, z[MAX + 1009], suf[1009], pre[1009];

void z_function(){

	for( int i = 0; i < len; i++) z[i] = 0;

	for( int i = 0, l = 0, r = 0; i < len; i++){

		if( i <= r) z[i] = min (z[i - l], r - i + 1);
		while( i + z[i] < len && aux[z[i]] == aux [ i + z[i]]) z[i] ++;
		if( r < z[i] + i - 1) r = z[i] + i - 1, l = i;
	}
}
bool solve(){

	for( int i = 0; i <= lp; i ++) pre[i] = oo, suf[i] = -1;

	for( int i = 0; i < lp; i++) aux[i] = p[i];

	aux[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[i];

	len = lp + ls + 1;

	z_function();

	for( int i = 0; i < ls; i++)

		pre[z[i + 1 + lp]] = min (pre[z[i + 1 + lp]], i);

	for( int i = lp - 1; i ; i --)

		pre[i] = min ( pre[i + 1], pre[i]);

	for( int i = 0; i < lp; i++) aux[i] = p[lp - i - 1];

	aux[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[ls - i - 1];

	z_function();

	for( int i = 0; i < ls; i++)

		suf[z[i + 1 + lp]] = max (suf[z[i + 1 + lp]], ls - i - 1);

	for( int i = lp - 1; i ; i --)

		suf[i] = max ( suf[i + 1], suf[i]);

	for( int i = 1; i <= lp ; i++)

		if( pre[i] + lp - 1<= suf[lp - i]) return true;

	return false;
}
int main(){

	int r = 0, t;

	scanf("%s", s);
	ls = strlen(s);
	scanf("%d", &t);

	for( ; t; --t){

		scanf("%s", p);
		lp = strlen(p);

		if( lp > 1 && lp <= ls && solve())
			r ++;
	}

	printf("%d\n", r);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
#define MAX 100000
using namespace std;

char s[MAX + 5] , p[1005], aux[MAX + 1005];
int len , lp, ls, z[MAX + 1009], suf[1009], pre[1009];

void z_function(){

	for( int i = 0; i < len; i++) z[i] = 0;

	for( int i = 0, l = 0, r = 0; i < len; i++){

		if( i <= r) z[i] = min (z[i - l], r - i + 1);
		while( i + z[i] < len && aux[z[i]] == aux [ i + z[i]]) z[i] ++;
		if( r < z[i] + i - 1) r = z[i] + i - 1, l = i;
	}
}
bool solve(){

	for( int i = 0; i <= lp; i ++) pre[i] = oo, suf[i] = -1;

	for( int i = 0; i < lp; i++) aux[i] = p[i];

	aux[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[i];

	len = lp + ls + 1;

	z_function();

	for( int i = 0; i < ls; i++)

		pre[z[i + 1 + lp]] = min (pre[z[i + 1 + lp]], i);

	for( int i = lp - 1; i ; i --)

		pre[i] = min ( pre[i + 1], pre[i]);

	for( int i = 0; i < lp; i++) aux[i] = p[lp - i - 1];

	aux[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[ls - i - 1];

	z_function();

	for( int i = 0; i < ls; i++)

		suf[z[i + 1 + lp]] = max (suf[z[i + 1 + lp]], ls - i - 1);

	for( int i = lp - 1; i ; i --)

		suf[i] = max ( suf[i + 1], suf[i]);

	for( int i = 1; i <= lp ; i++)

		if( pre[i] + lp - 1<= suf[lp - i]) return true;

	return false;
}
int main(){

	int r = 0, t;

	scanf("%s", s);
	ls = strlen(s);
	scanf("%d", &t);

	for( ; t; --t){

		scanf("%s", p);
		lp = strlen(p);

		if( lp > 1 && lp <= ls && solve())
			r ++;
	}

	printf("%d\n", r);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
#define MAX 10000
using namespace std;

char s[MAX + 5] , p[1005], aux[MAX + 1005];
int len , lp, ls, z[MAX + 1005], suf[1005], pre[1005];

void z_function(){

	for( int i = 0; i < len; i++) z[i] = 0;

	for( int i = 0, l = 0, r = 0; i < len; i++){

		if( i <= r) z[i] = min (z[i - l], r - i + 1);
		while( i + z[i] < len && aux[z[i]] == aux [ i + z[i]]) z[i] ++;
		if( r < z[i] + i - 1) r = z[i] + i - 1, l = i;
	}
}
bool solve(){

	memset( aux, 0, sizeof(aux));
	memset( pre, 63, sizeof(pre));
	memset( suf, -1, sizeof(suf));

	for( int i = 0; i < lp; i++) aux[i] = p[i];

	p[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[i];

	len = lp + ls + 1;

	z_function();

	for( int i = 0; i < ls; i++)

		pre[z[i + 1 + lp]] = min (pre[z[i + 1 + lp]], i);

	for( int i = lp - 1; i ; i --)

		pre[i] = min ( pre[i + 1], pre[i]);

	for( int i = 0; i < lp; i++) aux[i] = p[lp - i - 1];

	p[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[ls - i - 1];

	z_function();

	for( int i = 0; i < ls; i++)

		suf[z[i + 1 + lp]] = max (suf[z[i + 1 + lp]], ls - i - 1);

	for( int i = lp - 1; i ; i --)

		suf[i] = max ( suf[i + 1], suf[i]);

	for( int i = 1; i <= lp ; i++)

		if( pre[i] + lp - 1<= suf[lp - i]) return true;

	return false;
}
int main(){

	int r = 0, t;

	scanf("%s", s);
	ls = strlen(s);
	scanf("%d", &t);

	for( ; t; --t){

		scanf("%s", p);
		lp = strlen(p);

		if( lp > 1 && lp <= ls && solve())
			r ++;
	}

	printf("%d\n", r);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
using namespace std;

char s[100005], p[1005], tmp[101005];
int suf[1005], pre[1005], ls, lp, len, z[1005];

void z_function(){

    for( int i = 0; i <= len; i++) z[i] = 0;

    for( int i = 1, l = 0, r = 0; i < len; i++){

        if( i <= r) z[i] = min ( z[i - l] , r - i + 1);

        while( i + z[i] < len && tmp[i + z[i]] == tmp[z[i]]) z[i] ++;

        if( r < i + z[i] - 1){

            l = i;
            r = i + z[i] - 1;
        }

     }
}
bool factible(){

    for( int i = 0; i < lp; i++)

            tmp[i] = p[i];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[i];

    len = lp + ls + 1;
    for( int i = 1; i <= lp; i++) pre[i] = oo, suf[i] = -1;
    pre[0] = suf[0] = 0;

    z_function();

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

        if(pre[z[i + 1 + lp]] != oo) continue;
        pre[z[i + 1 + lp]] = i;
        for( int j = 1; j < z[i + 1 + lp]; j++){

            if(pre[j] != oo) continue;
            pre[j] = i;
        }
    }

    for( int i = 0;i < lp; i++)

        tmp[i] = p[lp - i - 1];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[ls - i - 1];

    z_function();

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

        if(suf[z[i + 1 + lp]] != -1) continue;
        suf[z[i + 1 + lp]] = ls - i - 1;

        for( int j = 1; j < z[ 1 + i + lp ]; j++){

            if( suf[j] != -1) continue;
            suf[j] = ls - i - 1;
        }

    }

    for( int i = 1; i <= lp; i++)

        if( pre[i] <= suf[lp - i] - lp + 1)

            return true;

    return false;
}

int main(){

    scanf("%s", s);
    int r = 0, t ; ls = strlen(s);

    scanf("%d", &t);

    for ( ; t ; t--){

        scanf("%s", p);
        lp = strlen(p);

        if( factible()) r ++;

    }

    printf("%d\n", r);
    return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
#define MAX 10000
using namespace std;

char s[MAX + 5] , p[1005], aux[MAX + 1005];
int len , lp, ls, z[MAX + 1005], suf[1005], pre[1005];

void z_function(){

	z[0] = 0;

	for( int i = 0, l = 0, r = 0; i < len; i++){

        z[i] = 0;
		if( i <= r) z[i] = min (z[i - l], r - i + 1);
		while( i + z[i] < len && aux[z[i]] == aux [ i + z[i]]) z[i] ++;
		if( r < z[i] + i - 1) r = z[i] + i - 1, l = i;
	}
}
bool solve(){

	for( int i = 0; i < lp; i++) aux[i] = p[i], pre[i + 1] = oo;
	pre[0] = oo;

	p[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[i];

	len = lp + ls + 1;

	z_function();

	for( int i = 0; i < ls; i++)

		pre[z[i + 1 + lp]] = min (pre[z[i + 1 + lp]], i);

	for( int i = lp - 1; i ; i --)

		pre[i] = min ( pre[i + 1], pre[i]);

	for( int i = 0; i < lp; i++) aux[i] = p[lp - i - 1], suf[i + 1] = -oo;
	suf[0] = -oo;

	p[lp] = '*';

	for( int i = 0; i < ls; i++) aux[i + lp + 1] = s[ls - i - 1];

	z_function();

	for( int i = 0; i < ls; i++)

		suf[z[i + 1 + lp]] = max (suf[z[i + 1 + lp]], ls - i - 1);

	for( int i = lp - 1; i ; i --)

		suf[i] = max ( suf[i + 1], suf[i]);

	for( int i = 1; i <= lp ; i++)

		if( pre[i] + lp - 1<= suf[lp - i]) return true;

	return false;
}
int main(){

	int r = 0, t;

	scanf("%s", s);
	ls = strlen(s);

	for( scanf("%d", &t); t; --t){

		scanf("%s", p);
		lp = strlen(p);

		if( lp > 1 && lp <= ls && solve()) r ++;
	}

	printf("%d\n", r);
	return 0;
}


#include <cstdio>
#include <cstring>
#include <algorithm>
#include <string>
#include <iostream>
#define oo 1000000
using namespace std;

char s[100005], p[1005], tmp[101005];
int suf[1005], pre[1005], ls, lp, len, z[1005];

void z_function(){

    for( int i = 0; i <= len; i++) z[i] = 0;

    for( int i = 1, l = 0, r = 0; i < len; i++){

        if( i <= r) z[i] = min ( z[i - l] , r - i + 1);

        while( i + z[i] < len && tmp[i + z[i]] == tmp[z[i]]) z[i] ++;

        if( r < i + z[i] - 1){

            l = i;
            r = i + z[i] - 1;
        }

     }
}
bool factible(){

	for( int i = 0; i < lp; i++)

	        tmp[i] = p[i];

    tmp[lp] = '.';

	for( int i = 0; i < ls; i++)

	    tmp[i + lp + 1] = s[i];

    len = lp + ls + 1;
    for( int i = 0; i <= lp; i++) pre[i] = oo, suf[i] = -1;

    z_function();

    for( int i = ls - 1; i >= 0; i--)

        pre[z[i + 1 + lp]] = i;

    for( int i = 0;i < lp; i++)

        tmp[i] = p[lp - i - 1];

    tmp[lp] = '.';

    for( int i = 0; i < ls; i++)

        tmp[i + lp + 1] = s[ls - i - 1];

    z_function();

    for( int i = ls - 1; i >= 0; i--)

        suf[z[i + 1 + lp]] = ls - i - 1;

    for( int i = 1; i <= lp; i++)

        if( pre[i] <= suf[lp - i] - lp + 1)
        	return true;

    return false;
}

int main(){

    scanf("%s", s);
    int r = 0, t ; ls = strlen(s);

    cin >> t;

    for ( ; t ; t--){

        scanf("%s", p);
        lp = strlen(p);

        if( factible()) r ++;

    }

    cout << r << endl;

    return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
char n[100015];
char m[105][1005];
char n2[100015],m2[1005];
int k;
int p[1005];
int chu1[1006],chu2[1006];
void huhuan(char *n,char *hu)
{
	int len1=strlen(n);
	//int len2=strlen(hu);
	int jia=0;
	for(int i=len1-1;i>=0;i--)
	{
		hu[jia++]=n[i];
	}
	hu[jia]='\0';
}
void getps(char *n)
{
   int j;
   int len=strlen(n);
   p[0]=0;p[1]=0;
   for(int i=1;i<len;i++)
   {
   	j=p[i];
   	while(j&&n[i]!=n[j]) j=p[j];
   	p[i+1]= n[i]==n[j]?j+1:0;
   }
}
int kmp(char *m,int len)
{
   memset(chu1,0,sizeof(chu1));
   //memset(chu2,0,sizeof(chu2));
   getps(m);
   int lenm=strlen(m);
   int j=0;
   for(int i=0;i<len;i++)
   {
   	while(j&&n[i]!=m[j]) j=p[j];
   	if(n[i]==m[j]) j++;
   	if(j==lenm) return 1;
   	if(i==0){
   		chu1[0]=j;
   	}
   	else{
   		if(j>chu1[i-1]) chu1[i]=j;
   		else chu1[i]=chu1[i-1];
   	}
   }
   huhuan(n,n2);
   huhuan(m,m2);
   getps(m2);j=0;
   for(int i=0;i<len-1;i++)
   {
     while(j&&n2[i]!=m2[j]) j=p[j];
     if(n2[i]==m2[j]) j++;
     if(j+chu1[lenm-2-i]>=lenm) return 1;
    }
   return 0;
}
int main()
{
   while(scanf("%s",n)==1)
   {
      int lenn=strlen(n);
      scanf("%d",&k);
      for(int i=0;i<k;i++)
      {
      	scanf("%s",m[i]);
      }
      int co=0;
     for(int i=0;i<k;i++)
     {
     	if(kmp(m[i],lenn)) co++;
     }
     printf("%d\n",co);
   }
   return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
char n[100015];
char m[105][1005];
char n2[100015],m2[1005];
int k;
int p[1005];
int chu1[1006];
void huhuan(char *n,char *hu,int len1)
{
	int jia=0;
	for(int i=len1-1;i>=0;i--)
	{
		hu[jia++]=n[i];
	}
	hu[jia]='\0';
}
void getps(char *n)
{
   int j;
   int len=strlen(n);
   p[0]=0;p[1]=0;
   for(int i=1;i<len;i++)
   {
   	j=p[i];
   	while(j&&n[i]!=n[j]) j=p[j];
   	p[i+1]= n[i]==n[j]?j+1:0;
   }
}
int kmp(char *m,int len)
{
   memset(chu1,0,sizeof(chu1));
   getps(m);
   int lenm=strlen(m);
   int j=0;
   for(int i=0;i<len;i++)
   {
   	while(j&&n[i]!=m[j]) j=p[j];
   	if(n[i]==m[j]) j++;
   	if(j==lenm) return 1;
   	if(i==0){
   		chu1[i]=j;
   	}
   	else{
   		if(j>chu1[i-1]) chu1[i]=j;
   		else chu1[i]=chu1[i-1];
   	}
   }
//   for(int i=0;i<len;i++)
//   {
//   	printf("%d , ",chu1[i]);
//   }
//   printf("\n");
   huhuan(n,n2,len);
   huhuan(m,m2,lenm);
   //printf("%s\n%s,,\n",n2,m2);
   getps(m2);j=0;
   int maxx=0;
   for(int i=0;i<len-1;i++)
   {
     while(j&&n2[i]!=m2[j]) j=p[j];
     if(n2[i]==m2[j]) j++;
     maxx=max(maxx,j);
     if(maxx+chu1[len-2-i]>=lenm) return 1;
    }
   return 0;
}
int main()
{
   while(scanf("%s",n)==1)
   {
      int lenn=strlen(n);
      scanf("%d",&k);
      for(int i=0;i<k;i++)
      {
      	scanf("%s",m[i]);
      }
      int co=0;
     for(int i=0;i<k;i++)
     {
     	int u=strlen(m[i]);
     	if(u>lenn) continue;
     	if(kmp(m[i],lenn)) co++;
     }
     printf("%d\n",co);
   }
   return 0;
}


#include<stdio.h>
#include<iostream>
#include<algorithm>
#include<string.h>
#include<queue>
#include<vector>
using namespace std;
char n[100015];
char m[105][1005];
char n2[100015],m2[1005];
int k;
int p[1005];
int chu1[1006],chu2[1006];
void huhuan(char *n,char *hu)
{
	int len1=strlen(n);
	//int len2=strlen(hu);
	int jia=0;
	for(int i=len1-1;i>=0;i--)
	{
		hu[jia++]=n[i];
	}
	hu[jia]='\0';
}
void getps(char *n)
{
   int j;
   int len=strlen(n);
   p[0]=0;p[1]=0;
   for(int i=1;i<len;i++)
   {
   	j=p[i];
   	while(j&&n[i]!=n[j]) j=p[j];
   	p[i+1]= n[i]==n[j]?j+1:0;
   }
}
int kmp(char *m,int len)
{
   memset(chu1,0,sizeof(chu1));
   //memset(chu2,0,sizeof(chu2));
   getps(m);
   int lenm=strlen(m);
   int j=0;
   for(int i=0;i<len;i++)
   {
   	while(j&&n[i]!=m[j]) j=p[j];
   	if(n[i]==m[j]) j++;
   	if(j==lenm) return 1;
   	if(i==0){
   		chu1[0]=j;
   	}
   	else{
   		if(j>chu1[i-1]) chu1[i]=j;
   		else chu1[i]=chu1[i-1];
   	}
   }
   huhuan(n,n2);
   huhuan(m,m2);
   getps(m2);j=0;
   int maxx=0;
   for(int i=0;i<len-1;i++)
   {
     while(j&&n2[i]!=m2[j]) j=p[j];
     if(n2[i]==m2[j]) j++;
     maxx=max(maxx,j);
     if(maxx+chu1[len-2-i]>=lenm) return 1;
    }
   return 0;
}
int main()
{
   while(scanf("%s",n)==1)
   {
      int lenn=strlen(n);
      scanf("%d",&k);
      for(int i=0;i<k;i++)
      {
      	scanf("%s",m[i]);
      }
      int co=0;
     for(int i=0;i<k;i++)
     {
     	if(kmp(m[i],lenn)) co++;
     }
     printf("%d\n",co);
   }
   return 0;
}