#include <bits/stdc++.h>
using namespace std;
int L;
class segment_tree {
int n;
vector<int64_t> seg;
public:
segment_tree(int n) : n(n), seg(2 * n, 1) {}
void apply(int l, int r, int mul) {
for (l += n, r += n + 1; l < r; l >>= 1, r >>= 1) {
if (l & 1) {
seg[l] = (seg[l] * mul) % L;
l++;
}
if (r & 1) {
--r;
seg[r] = (seg[r] * mul) % L;
}
}
}
int64_t query(int i) {
int64_t ans = 1;
for (i += n; i > 0; i >>= 1) {
ans = (ans * seg[i]) % L;
}
return ans;
}
};
int main() {
cin.tie(nullptr)->sync_with_stdio(false);
int n;
cin >> n >> L;
vector<vector<int>> adj(n + 1);
for (int i = 0, u, v; i < n - 1; ++i) {
cin >> u >> v;
adj[u].push_back(v), adj[v].push_back(u);
}
vector<int64_t> a(n + 1);
for (int i = 1; i <= n; ++i) {
cin >> a[i];
}
vector<int> tim(n + 1), par(n + 1), st(n + 1), en(n + 1);
int timer = 1;
auto dfs = [&](auto &&self, int u, int p) -> void {
st[u] = timer;
for (int &i : adj[u]) {
if (i == p) {
continue;
}
par[i] = u;
tim[i] = timer++;
}
en[u] = timer - 1;
for (int &i : adj[u]) {
if (i == p) {
continue;
}
self(self, i, u);
}
};
dfs(dfs, 1, 0);
segment_tree tree(n);
for (int i = 1; i <= n; ++i) {
tree.apply(tim[i], tim[i], a[i]);
}
int q;
cin >> q;
while (q--) {
int t;
cin >> t;
if (t == 1) {
int x, d, w;
cin >> x >> d >> w;
assert(d <= 1);
tree.apply(tim[x], tim[x], w);
if (d == 0) {
continue;
}
if (par[x] != 0) {
tree.apply(tim[par[x]], tim[par[x]], w);
}
tree.apply(st[x], en[x], w);
} else {
int x;
cin >> x;
cout << tree.query(tim[x]) << '\n';
}
}
}