#include <bits/stdc++.h>
using namespace std;
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define int long long
#define all(x) (x).begin(), (x).end()
typedef long double ld;
typedef long long ll;
typedef pair<ll,ll> pll;
typedef pair<int,int> pii;
typedef vector<int> vi;
typedef vector<ll> vll;
typedef vector<bool> vb;
typedef vector<vector<int>> vvi;
typedef vector<vector<bool>> vvb;
typedef vector<vector<ll>> vvll;
typedef vector<string> vs;
typedef vector<vector<string>> vvs;
typedef vector<char> vc;
typedef vector<vector<char>> vvc;
typedef map<int, int> mii;
typedef unordered_map<int, int> umii;
// const int mod = 1e9 + 7;
const int inf = INTMAX_MAX;
const bool tc = false;
int n, mod;
const int mxn = 2e5 + 5;
int h[mxn], par[mxn], ti[mxn], lf[mxn][41], rg[mxn][41]; vi adj[mxn];
void dfs(int node, int prev) {
for (int i = 1; i <= 40; i++) {
lf[node][i] = 1e18;
rg[node][i] = -1e18;
}
lf[node][0] = rg[node][0] = ti[node];
for (auto &neighbour : adj[node]) {
if (neighbour == prev) continue;
dfs(neighbour, node);
}
for (int i = 1; i <= 40; i++) {
for (auto &neighbour : adj[node]) {
if (neighbour == prev) continue;
lf[node][i] = min(lf[node][i], lf[neighbour][i - 1]);
rg[node][i] = max(rg[node][i], rg[neighbour][i - 1]);
}
}
}
struct SegTree {
int n, sz;
vector<int> seg;
void init(int _n, int h[]) {
n = _n;
sz = 1;
while (sz < n) sz <<= 1;
seg.assign(2 * sz, 1);
for (int i = 0; i < n; i++) seg[sz + i] = h[i] % mod;
}
void mul(int l, int r, int x) {
x %= mod;
for (l += sz, r += sz; l <= r; l >>= 1, r >>= 1) {
if (l & 1) seg[l] = 1LL * seg[l] * x % mod, l++;
if (!(r & 1)) seg[r] = 1LL * seg[r] * x % mod, r--;
}
}
int qry(int x) {
long long ans = 1;
for (x += sz; x > 0; x >>= 1) {
ans = ans * seg[x] % mod;
}
return (int)ans;
}
};
inline void solve() {
cin >> n >> mod;
for (int i = 0; i < n - 1; i++) {
int u, v; cin >> u >> v; u--; v--;
adj[u].pb(v); adj[v].pb(u);
}
queue<pii> bfs; int t = 0;
bfs.push({0, -1});
while (bfs.size()) {
auto cur = bfs.front();
int node = cur.fi; int p = cur.se;
par[node] = p;
ti[node] = t++;
bfs.pop();
for (auto &neighbour : adj[node]) {
if (neighbour == p) continue;
bfs.push({neighbour, node});
}
}
dfs(0, -1);
// use time
for (int i = 0; i < n; i++) {
int x; cin >> x;
h[ti[i]] = x;
}
SegTree st;
st.init(n, h);
int q; cin >> q;
while (q--) {
int t; cin >> t;
if (t == 1) {
int x, d, w;
cin >> x >> d >> w;
x--; int h = d;
if (d == 0) {
st.mul(ti[x], ti[x], w);
continue;
}
for (int i = 0; i <= d-1; i++) {
if (x == 0) break;
// h below and h -1
pii x1 = {lf[x][h], rg[x][h]}, x2 = {lf[x][h - 1], rg[x][h - 1]};
if (x1.fi != -1) {
st.mul(x1.fi, x1.se, w);
}
if (x2.fi != -1) {
st.mul(x2.fi, x2.se, w);
}
h--;
x = par[x];
}
// do everythign
for (int k = 0; k <= h; k++) {
pii p = {lf[x][k], rg[x][k]};
if (p.fi != -1) st.mul(p.fi, p.se, w);
}
// cout << "done\n";
} else {
int x; cin >> x; x--;
cout << st.qry(ti[x]) << '\n';
// cout << h[ti[x]] << '\n';
}
}
}
void setIO(string s) {
freopen((s + ".in").c_str(), "r", stdin);
freopen((s + ".out").c_str(), "w", stdout);
}
signed main() {
ios::sync_with_stdio(false);
cout.tie(0);
cin.tie(0);
//setIO();
int t = 1;
if (tc) {
cin >> t;
}
while (t--) {
solve();
}
}