#include #include using namespace std; typedef long long ll; typedef long double ld; // read template long long readInt(long long l,long long r,char endd){ long long x=0; int cnt=0; int fi=-1; bool is_neg=false; while(true){ char g=getchar(); if(g=='-'){ assert(fi==-1); is_neg=true; continue; } if('0'<=g && g<='9'){ x*=10; x+=g-'0'; if(cnt==0){ fi=g-'0'; } cnt++; assert(fi!=0 || cnt==1); assert(fi!=0 || is_neg==false); assert(!(cnt>19 || ( cnt==19 && fi>1) )); } else if(g==endd){ assert(cnt>0); if(is_neg){ x= -x; } assert(l<=x && x<=r); return x; } else { assert(false); } } } string readString(int l,int r,char endd){ string ret=""; int cnt=0; while(true){ char g=getchar(); assert(g!=-1); if(g==endd){ break; } cnt++; ret+=g; } assert(l<=cnt && cnt<=r); return ret; } long long readIntSp(long long l,long long r){ return readInt(l,r,' '); } long long readIntLn(long long l,long long r){ return readInt(l,r,'\n'); } string readStringLn(int l,int r){ return readString(l,r,'\n'); } string readStringSp(int l,int r){ return readString(l,r,' '); } // end const int X = 8 * 1e6 + 239; const int M = 2e5 + 239; const int N = 2 * M; const int L = 19; const int BIG = 1e9 + 239; //persistent segment tree int tree[X], ls[X], rs[X], cur; inline int build(int i, int l, int r) { if (r - l == 1) { tree[cur] = -BIG; ls[cur] = -1; rs[cur] = l; cur++; return (cur - 1); } int mid = (l + r) >> 1; int ix = cur++; ls[ix] = build(2 * i + 1, l, mid); rs[ix] = build(2 * i + 2, mid, r); tree[ix] = -BIG; return ix; } inline int update(int ver, int l, int r, int id, int x) { if (r - l == 1) { tree[cur] = x; ls[cur] = -1; rs[cur] = id; cur++; return (cur - 1); } int mid = (l + r) >> 1; if (id < mid) { int ix = cur++; ls[ix] = update(ls[ver], l, mid, id, x); rs[ix] = rs[ver]; tree[ix] = max(tree[ls[ix]], tree[rs[ix]]); return ix; } else { int ix = cur++; ls[ix] = ls[ver]; rs[ix] = update(rs[ver], mid, r, id, x); tree[ix] = max(tree[ls[ix]], tree[rs[ix]]); return ix; } } inline int gettL(int ver, int l, int r, int s, int mx) { if (r == s && tree[ver] < mx) return -1; if (r - l == 1) { if (tree[ver] < mx) return -1; return rs[ver]; } int mid = (l + r) >> 1; if (s <= mid) return gettL(ls[ver], l, mid, s, mx); int t = gettL(rs[ver], mid, r, s, mx); if (t != -1) return t; return gettL(ls[ver], l, mid, mid, mx); } inline int gettR(int ver, int l, int r, int s, int mx) { if (l == s && tree[ver] < mx) return -1; if (r - l == 1) { if (tree[ver] < mx) return -1; return rs[ver]; } int mid = (l + r) >> 1; if (s >= mid) return gettR(rs[ver], mid, r, s, mx); int t = gettR(ls[ver], l, mid, s, mx); if (t != -1) return t; return gettR(rs[ver], mid, r, mid, mx); } bool used[M]; int n, q, a[M], szk[M], ans, in[M], root[M], st; vector v[M]; pair val[M]; ll sum; inline void dfs_check(int p) { used[p] = true; for (int i : v[p]) if (!used[i]) dfs_check(i); } int gl[N], first[N], how[N]; pair dp[L][N]; vector et; inline void dfs_build(int p, int pr, int ver) { root[p] = update(ver, 0, n, in[p], gl[p]); // version of persistent segment tree in vertex p for (int i : v[p]) if (i != pr) dfs_build(i, p, root[p]); } inline void dfs_lca(int p, int pr, int f) { first[p] = et.size(); et.push_back(p); gl[p] = f; for (int i : v[p]) if (i != pr) { dfs_lca(i, p, f + 1); et.push_back(p); } } inline int lca(int u, int v) { if (first[u] > first[v]) swap(u, v); int l = first[u]; int r = first[v]; int e = how[r - l + 1]; return min(dp[e][l], dp[e][r + 1 - (1 << e)]).second; } inline void init_lca() { et.clear(); dfs_lca(0, -1, 0); int k = et.size(); for (int i = 0; i < k; i++) dp[0][i] = make_pair(gl[et[i]], et[i]); for (int i = 1; i < L; i++) for (int j = 0; j < k; j++) { int st = (1 << (i - 1)); if (st + j >= k) { dp[i][j] = dp[i - 1][j]; continue; } dp[i][j] = min(dp[i - 1][j], dp[i - 1][st + j]); } how[1] = 0; for (int i = 2; i <= k; i++) { how[i] = how[i - 1]; if ((1 << (how[i] + 1)) == i) how[i]++; } } inline int getans(int r, int s, int f) // get answer on way from s to f { int t = lower_bound(val, val + n, make_pair(r, 0)) - val; // prefix [0, t) and suffix [t, n) int ans = BIG; int it = -1; if (t > 0) it = gettL(root[f], 0, n, t, gl[s]); // get nearest on prefix if (it >= 0) ans = min(ans, abs(val[it].first - r)); it = -1; if (t < n) it = gettR(root[f], 0, n, t, gl[s]); // get nearest on suffix if (it >= 0) ans = min(ans, abs(val[it].first - r)); return ans; } inline int query(int r, vector id) { int x = id[0]; for (int i : id) x = lca(x, i); int ans = BIG; for (int i : id) ans = min(ans, getans(r, x, i)); return ans; } inline void solve() { n = readIntSp(2, (int)(1e5)); q = readIntLn(2, (int)(1e5)); for (int i = 0; i < n; i++) v[i].clear(); for (int i = 0; i < n; i++) { if (i < n - 1) a[i] = readIntSp(1, (int)(1e9)); else a[i] = readIntLn(1, (int)(1e9)); } for (int i = 0; i < n; i++) val[i] = make_pair(a[i], i); sort(val, val + n); // compress array a for (int i = 0; i < n; i++) in[val[i].second] = i; cur = 0; st = build(0, 0, n); for (int i = 0; i < n - 1; i++) { int x = readIntSp(1, n); int y = readIntLn(1, n); assert(x != y); x--, y--; v[x].push_back(y); v[y].push_back(x); } for (int i = 0; i < n; i++) used[i] = false; dfs_check(0); for (int i = 0; i < n; i++) assert(used[i]); init_lca(); dfs_build(0, -1, st); // build versions of persistent segment tree of all vertexes sum = 0; ans = 0; for (int i = 0; i < q; i++) { int r = readIntSp(0, (int)(2e9)); r ^= ans; assert(1 <= r && r <= (int)(1e9)); int k = readIntSp(1, n); sum += k; vector id; for (int x = 0; x < k; x++) { int p; if (x < k - 1) p = readIntSp(0, (int)(2e9)); else p = readIntLn(0, (int)(2e9)); p ^= ans; assert(1 <= p && p <= n); p--; assert(szk[p] == 0); szk[p]++; id.push_back(p); } for (int x : id) szk[x]--; ans = query(r, id); cout << ans << "\n"; } assert((sum <= (ll)(3e5))); } int main() { ios::sync_with_stdio(0); int T = readIntLn(1, 5); sum = 0; while (T--) solve(); assert(getchar() == -1); return 0; }