#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;
}
};
#define max_d 41
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), dep(n + 1, int(1e9));
int timer = 0;
queue<int> q;
q.push(1);
dep[1] = 0;
while (!q.empty()) {
int u = q.front();
q.pop();
tim[u] = timer++;
for (int &i : adj[u]) {
if (dep[u] + 1 < dep[i]) {
par[i] = u;
dep[i] = dep[u] + 1;
q.push(i);
}
}
}
vector st(n + 1, vector<int>(max_d, int(1e9))), en(n + 1, vector<int>(max_d, -int(1e9)));
for (int i = 1; i <= n; ++i) {
int u = i;
for (int d = 0; d < max_d && u != 0; ++d) {
st[u][d] = min(st[u][d], tim[i]);
en[u][d] = max(en[u][d], tim[i]);
u = par[u];
}
}
segment_tree tree(n);
for (int i = 1; i <= n; ++i) {
tree.apply(tim[i], tim[i], a[i]);
}
int qq;
cin >> qq;
while (qq--) {
int t;
cin >> t;
if (t == 1) {
int x, d, w;
cin >> x >> d >> w;
while (d >= 0 && x != 0) {
// apply d and d-1 rn
for (int i = max(0, d - 1); i <= d; ++i) {
tree.apply(st[x][i], en[x][i], w);
}
if (x == 1) { // no parent exists, apply rest now
for (int i = 0; i < d - 1; ++i) {
tree.apply(st[x][i], en[x][i], w);
}
}
d--;
x = par[x];
}
} else {
int x;
cin >> x;
cout << tree.query(tim[x]) << '\n';
}
}
}