#include <bits/stdc++.h>
#define ll long long int
#define fastIO ios_base::sync_with_stdio(0); cin.tie(0); cout.tie(0);
#define ff first
#define ss second
#define pb push_back
#define po pop_back()
#define lb lower_bound
#define ub upper_bound
#define nl "\n"
#define dbg(x) cout << (#x) << " = " << (x) << nl
#define fl(i,a,b,c) for(int i=a;i<b;i+=c)
#define rl(i,a,b,c) for(int i=a;i>b;i-=c)
#define sn(a,l) fl(i,0,l,1) cin >> a[i]
#define pr(a,l) fl(i,0,l,1) cout << a[i] << ' '
#define all(a) a.begin(),a.end()
#define test() int ts; cin>>ts; while(ts--)
const int INF = 1e9 + 1;
const ll MOD = 1e9 + 7;
const int N = 1e5 + 5;
const int K = 20;
const int B = 30;
using namespace std;
// #include <ext/pb_ds/assoc_container.hpp>
// #include <ext/pb_ds/tree_policy.hpp>
// using namespace __gnu_pbds;
// template<class T> using oset = tree<T, null_type, less<T>, rb_tree_tag, tree_order_statistics_node_update>;
// CODE BEGINS HERE --- TREES
int n;
vector<int> lst[N];
int LCA[N][K], dp[N][B];
int a[N], dis[N];
ll info[B], fc[N], ifc[N];
ll power(ll b, ll p)
{
ll r = 1;
while(p > 0)
{
if(p & 1)
r = (r * b) % MOD;
b = (b * b) % MOD;
p >>= 1;
}
return r % MOD;
}
void reset()
{
fc[0] = ifc[0] = 1;
fl(i,0,n,1)
{
fc[i+1] = ((i+1) * 1LL * fc[i]) % MOD;
ifc[i+1] = power(fc[i+1], MOD-2) % MOD;
fl(j,0,K,1)
LCA[i][j] = -1;
fl(j,0,B,1)
dp[i][j] = 0;
}
}
void dfs(int u=0, int p=-1, int d=0)
{
LCA[u][0] = p;
dis[u] = d;
fl(j,1,K,1)
if(LCA[u][j-1] != -1)
LCA[u][j] = LCA[LCA[u][j-1]][j-1];
fl(j,0,B,1)
if(a[u] & (1<<j))
dp[u][j]++;
for(auto v : lst[u])
if(v != p)
{
fl(j,0,B,1)
dp[v][j] += dp[u][j];
dfs(v,u,d+1);
}
}
int getLCA(int a, int b)
{
if(dis[b] < dis[a])
swap(a,b);
int d = dis[b] - dis[a];
while(d > 0)
{
int l = (int)log2(d);
b = LCA[b][l];
d -= (1<<l);
}
if(a == b)
return a;
rl(i,K-1,-1,1)
if(LCA[a][i] != -1 && (LCA[a][i] != LCA[b][i]))
{
a = LCA[a][i];
b = LCA[b][i];
}
return LCA[a][0];
}
void getArray(int x, int y, int lca)
{
fl(j,0,B,1)
info[j] = dp[x][j] + dp[y][j] - 2*dp[lca][j] + ((a[lca] & (1<<j)) ? 1 : 0);
}
int getDistance(int x, int y, int lca)
{
return (dis[x] + dis[y] - 2*dis[lca]);
}
ll mCr(int m, int r)
{
if(m < r)
return 0;
return (fc[m] * ((ifc[r] * ifc[m-r]) % MOD)) % MOD;
}
ll query_1(int d)
{
ll ans = 0;
fl(j,0,B,1)
ans = (ans + ((1LL<<j) * info[j])) % MOD;
return ans % MOD;
}
ll query_2(int d)
{
ll ans = 0;
fl(j,0,B,1)
{
int z = d - info[j];
// ans = (ans + ((1LL<<j)*(mCr(o,2) + mCr(o,1)*mCr(z,1))%MOD)%MOD) % MOD;
ans = (ans + ((1LL<<j)*((mCr(d,2) - mCr(z,2) + MOD) % MOD)) % MOD) % MOD;
}
return ans % MOD;
}
ll query_3(int d)
{
ll ans = 0;
fl(j,0,B,1)
{
int z = d - info[j];
ans = (ans + ((1LL<<j)*((mCr(d,3) - mCr(z,3) + MOD) % MOD)) % MOD) % MOD;
}
return ans % MOD;
}
ll query_4(int d)
{
ll ans = 0;
fl(j,0,B,1)
{
int z = d - info[j];
ans = (ans + ((1LL<<j)*((mCr(d,4) - mCr(z,4) + MOD) % MOD)) % MOD) % MOD;
}
return ans % MOD;
}
void solve()
{
cin >> n;
sn(a,n);
reset();
fl(i,1,n,1)
{
int u, v;
cin >> u >> v;
lst[--u].pb(--v);
lst[v].pb(u); // undirected graph
}
dfs();
test()
{
int t, u, v, l, d;
cin >> t >> u >> v;
--u, --v;
l = getLCA(u,v);
getArray(u,v,l);
d = (getDistance(u,v,l) + 1);
if(t == 1)
cout << query_1(d) << nl;
else if(t == 2)
cout << query_2(d) << nl;
else if(t == 3)
cout << query_3(d) << nl;
else
cout << query_4(d) << nl;
}
}
int main()
{
fastIO
solve();
return 0;
}
I2luY2x1ZGUgPGJpdHMvc3RkYysrLmg+CiNkZWZpbmUgbGwgbG9uZyBsb25nIGludAojZGVmaW5lIGZhc3RJTyBpb3NfYmFzZTo6c3luY193aXRoX3N0ZGlvKDApOyBjaW4udGllKDApOyBjb3V0LnRpZSgwKTsKI2RlZmluZSBmZiBmaXJzdAojZGVmaW5lIHNzIHNlY29uZAojZGVmaW5lIHBiIHB1c2hfYmFjawojZGVmaW5lIHBvIHBvcF9iYWNrKCkKI2RlZmluZSBsYiBsb3dlcl9ib3VuZAojZGVmaW5lIHViIHVwcGVyX2JvdW5kCiNkZWZpbmUgbmwgIlxuIgojZGVmaW5lIGRiZyh4KSBjb3V0IDw8ICgjeCkgPDwgIiA9ICIgPDwgKHgpIDw8IG5sCiNkZWZpbmUgZmwoaSxhLGIsYykgZm9yKGludCBpPWE7aTxiO2krPWMpCiNkZWZpbmUgcmwoaSxhLGIsYykgZm9yKGludCBpPWE7aT5iO2ktPWMpCiNkZWZpbmUgc24oYSxsKSBmbChpLDAsbCwxKSBjaW4gPj4gYVtpXQojZGVmaW5lIHByKGEsbCkgZmwoaSwwLGwsMSkgY291dCA8PCBhW2ldIDw8ICcgJwojZGVmaW5lIGFsbChhKSBhLmJlZ2luKCksYS5lbmQoKQojZGVmaW5lIHRlc3QoKSBpbnQgdHM7IGNpbj4+dHM7IHdoaWxlKHRzLS0pCmNvbnN0IGludCBJTkYgPSAxZTkgKyAxOwpjb25zdCBsbCBNT0QgPSAxZTkgKyA3Owpjb25zdCBpbnQgTiA9IDFlNSArIDU7CmNvbnN0IGludCBLID0gMjA7CmNvbnN0IGludCBCID0gMzA7CnVzaW5nIG5hbWVzcGFjZSBzdGQ7CiAKLy8gI2luY2x1ZGUgPGV4dC9wYl9kcy9hc3NvY19jb250YWluZXIuaHBwPiAKLy8gI2luY2x1ZGUgPGV4dC9wYl9kcy90cmVlX3BvbGljeS5ocHA+IAovLyB1c2luZyBuYW1lc3BhY2UgX19nbnVfcGJkczsgCi8vIHRlbXBsYXRlPGNsYXNzIFQ+IHVzaW5nIG9zZXQgPSB0cmVlPFQsIG51bGxfdHlwZSwgbGVzczxUPiwgcmJfdHJlZV90YWcsIHRyZWVfb3JkZXJfc3RhdGlzdGljc19ub2RlX3VwZGF0ZT47CiAKLy8gQ09ERSBCRUdJTlMgSEVSRSAtLS0gVFJFRVMKIAppbnQgbjsKdmVjdG9yPGludD4gbHN0W05dOwppbnQgTENBW05dW0tdLCBkcFtOXVtCXTsKaW50IGFbTl0sIGRpc1tOXTsKbGwgaW5mb1tCXSwgZmNbTl0sIGlmY1tOXTsKIApsbCBwb3dlcihsbCBiLCBsbCBwKQp7CglsbCByID0gMTsKCXdoaWxlKHAgPiAwKQoJewoJCWlmKHAgJiAxKQoJCQlyID0gKHIgKiBiKSAlIE1PRDsKCQliID0gKGIgKiBiKSAlIE1PRDsKCQlwID4+PSAxOwoJfQoJcmV0dXJuIHIgJSBNT0Q7Cn0KIAp2b2lkIHJlc2V0KCkKewogICAgZmNbMF0gPSBpZmNbMF0gPSAxOwogICAgZmwoaSwwLG4sMSkKICAgIHsKICAgICAgICBmY1tpKzFdID0gKChpKzEpICogMUxMICogZmNbaV0pICUgTU9EOwogICAgICAgIGlmY1tpKzFdID0gcG93ZXIoZmNbaSsxXSwgTU9ELTIpICUgTU9EOwogICAgICAgIGZsKGosMCxLLDEpCiAgICAgICAgICAgIExDQVtpXVtqXSA9IC0xOwogICAgICAgIGZsKGosMCxCLDEpCiAgICAgICAgICAgIGRwW2ldW2pdID0gMDsKICAgIH0KfQogCnZvaWQgZGZzKGludCB1PTAsIGludCBwPS0xLCBpbnQgZD0wKQp7CiAgICBMQ0FbdV1bMF0gPSBwOwogICAgZGlzW3VdID0gZDsKICAgIGZsKGosMSxLLDEpCiAgICAgICAgaWYoTENBW3VdW2otMV0gIT0gLTEpCiAgICAgICAgICAgIExDQVt1XVtqXSA9IExDQVtMQ0FbdV1bai0xXV1bai0xXTsKICAgIGZsKGosMCxCLDEpCiAgICAgICAgaWYoYVt1XSAmICgxPDxqKSkKICAgICAgICAgICAgZHBbdV1bal0rKzsKICAgIGZvcihhdXRvIHYgOiBsc3RbdV0pCiAgICAgICAgaWYodiAhPSBwKQogICAgICAgIHsKICAgICAgICAgICAgZmwoaiwwLEIsMSkKICAgICAgICAgICAgICAgIGRwW3ZdW2pdICs9IGRwW3VdW2pdOwogICAgICAgICAgICBkZnModix1LGQrMSk7CiAgICAgICAgfQp9CiAKaW50IGdldExDQShpbnQgYSwgaW50IGIpCnsKICAgIGlmKGRpc1tiXSA8IGRpc1thXSkKICAgICAgICBzd2FwKGEsYik7CiAgICBpbnQgZCA9IGRpc1tiXSAtIGRpc1thXTsKICAgIHdoaWxlKGQgPiAwKQogICAgewogICAgICAgIGludCBsID0gKGludClsb2cyKGQpOwogICAgICAgIGIgPSBMQ0FbYl1bbF07CiAgICAgICAgZCAtPSAoMTw8bCk7CiAgICB9CiAgICBpZihhID09IGIpCiAgICAgICAgcmV0dXJuIGE7CiAgICBybChpLEstMSwtMSwxKQogICAgICAgIGlmKExDQVthXVtpXSAhPSAtMSAmJiAoTENBW2FdW2ldICE9IExDQVtiXVtpXSkpCiAgICAgICAgewogICAgICAgICAgICBhID0gTENBW2FdW2ldOwogICAgICAgICAgICBiID0gTENBW2JdW2ldOwogICAgICAgIH0KICAgIHJldHVybiBMQ0FbYV1bMF07Cn0KIAp2b2lkIGdldEFycmF5KGludCB4LCBpbnQgeSwgaW50IGxjYSkKewogICAgZmwoaiwwLEIsMSkKICAgICAgICBpbmZvW2pdID0gZHBbeF1bal0gKyBkcFt5XVtqXSAtIDIqZHBbbGNhXVtqXSArICgoYVtsY2FdICYgKDE8PGopKSA/IDEgOiAwKTsKfQogCmludCBnZXREaXN0YW5jZShpbnQgeCwgaW50IHksIGludCBsY2EpCnsKICAgIHJldHVybiAoZGlzW3hdICsgZGlzW3ldIC0gMipkaXNbbGNhXSk7Cn0KIApsbCBtQ3IoaW50IG0sIGludCByKQp7CiAgICBpZihtIDwgcikKICAgICAgICByZXR1cm4gMDsKICAgIHJldHVybiAoZmNbbV0gKiAoKGlmY1tyXSAqIGlmY1ttLXJdKSAlIE1PRCkpICUgTU9EOwp9CiAKbGwgcXVlcnlfMShpbnQgZCkKewogICAgbGwgYW5zID0gMDsKICAgIGZsKGosMCxCLDEpCiAgICAJYW5zID0gKGFucyArICgoMUxMPDxqKSAqIGluZm9bal0pKSAlIE1PRDsKICAgIHJldHVybiBhbnMgJSBNT0Q7Cn0KIApsbCBxdWVyeV8yKGludCBkKQp7CiAgICBsbCBhbnMgPSAwOwogICAgZmwoaiwwLEIsMSkKICAgIHsKICAgICAgICBpbnQgeiA9IGQgLSBpbmZvW2pdOwogICAgICAgIC8vIGFucyA9IChhbnMgKyAoKDFMTDw8aikqKG1DcihvLDIpICsgbUNyKG8sMSkqbUNyKHosMSkpJU1PRCklTU9EKSAlIE1PRDsKICAgICAgICBhbnMgPSAoYW5zICsgKCgxTEw8PGopKigobUNyKGQsMikgLSBtQ3IoeiwyKSArIE1PRCkgJSBNT0QpKSAlIE1PRCkgJSBNT0Q7CiAgICB9CiAgICByZXR1cm4gYW5zICUgTU9EOwp9CiAKbGwgcXVlcnlfMyhpbnQgZCkKewogICAgbGwgYW5zID0gMDsKICAgIGZsKGosMCxCLDEpCiAgICB7CiAgICAgICAgaW50IHogPSBkIC0gaW5mb1tqXTsKICAgICAgICBhbnMgPSAoYW5zICsgKCgxTEw8PGopKigobUNyKGQsMykgLSBtQ3IoeiwzKSArIE1PRCkgJSBNT0QpKSAlIE1PRCkgJSBNT0Q7CiAgICB9CiAgICByZXR1cm4gYW5zICUgTU9EOwp9CiAKbGwgcXVlcnlfNChpbnQgZCkKewogICAgbGwgYW5zID0gMDsKICAgIGZsKGosMCxCLDEpCiAgICB7CiAgICAgICAgaW50IHogPSBkIC0gaW5mb1tqXTsKICAgICAgICBhbnMgPSAoYW5zICsgKCgxTEw8PGopKigobUNyKGQsNCkgLSBtQ3Ioeiw0KSArIE1PRCkgJSBNT0QpKSAlIE1PRCkgJSBNT0Q7CiAgICB9CiAgICByZXR1cm4gYW5zICUgTU9EOwp9CiAKdm9pZCBzb2x2ZSgpCnsKICAgIGNpbiA+PiBuOwogICAgc24oYSxuKTsKICAgIAogICAgcmVzZXQoKTsKIAogICAgZmwoaSwxLG4sMSkKICAgIHsKICAgICAgICBpbnQgdSwgdjsKICAgICAgICBjaW4gPj4gdSA+PiB2OwogICAgICAgIGxzdFstLXVdLnBiKC0tdik7CiAgICAgICAgbHN0W3ZdLnBiKHUpOyAvLyB1bmRpcmVjdGVkIGdyYXBoCiAgICB9CiAKICAgIGRmcygpOwogCiAgICB0ZXN0KCkKICAgIHsKICAgICAgICBpbnQgdCwgdSwgdiwgbCwgZDsKICAgICAgICBjaW4gPj4gdCA+PiB1ID4+IHY7CiAgICAgICAgLS11LCAtLXY7CiAgICAgICAgbCA9IGdldExDQSh1LHYpOwogICAgICAgIGdldEFycmF5KHUsdixsKTsKICAgICAgICBkID0gKGdldERpc3RhbmNlKHUsdixsKSArIDEpOwogICAgICAgIGlmKHQgPT0gMSkKICAgICAgICAgICAgY291dCA8PCBxdWVyeV8xKGQpIDw8IG5sOwogICAgICAgIGVsc2UgaWYodCA9PSAyKQogICAgICAgICAgICBjb3V0IDw8IHF1ZXJ5XzIoZCkgPDwgbmw7CiAgICAgICAgZWxzZSBpZih0ID09IDMpCiAgICAgICAgICAgIGNvdXQgPDwgcXVlcnlfMyhkKSA8PCBubDsKICAgICAgICBlbHNlCiAgICAgICAgICAgIGNvdXQgPDwgcXVlcnlfNChkKSA8PCBubDsKICAgIH0KIAp9CiAKaW50IG1haW4oKQp7CiAgICBmYXN0SU8KICAgIHNvbHZlKCk7CiAgICByZXR1cm4gMDsKfQ==