/*
I QUIT
😭
NEVEER!!!!
*/
#define NDEBUG
#ifdef NDEBUG
#define dbg(TXTMSG) if constexpr (false) cerr << "lol"
#define dbgv(VARN) ((void)0)
#define dbgfor(COND) if constexpr (false) for (COND)
#else
#define _GLIBCXX_DEBUG 1
#define _GLIBCXX_DEBUG_PEDANTIC 1
#pragma GCC optimize("trapv")
#define dbg(TXTMSG) cerr << "\n" << TXTMSG
#define dbgv(VARN) cerr << "\n" << #VARN << " = "<< VARN << ", line " << __LINE__ << "\n"
#define dbgfor(COND) for (COND)
#endif
#include <bits/stdc++.h>
using namespace std;
using ll = long long; 
using pll = pair<ll,ll>;
#define e0 first
#define e1 second
constexpr ll INFTY = 2e18;
ll N,L;
struct segtree
{
	vector<ll> tomul;
	segtree(ll n)
	{
		tomul.assign(4*n,1);
	}
	ll get(ll x, ll l, ll r, ll node)
	{
		if (x<l||x>r) return 1;
		if (l==r && l==x) return tomul[node];
		ll mid = (l+r)/2;
		return (tomul[node] * get(x,l,mid,node*2) * get(x,mid+1,r,node*2+1))%L;
	}
	void mul(ll val, ll lseg, ll rseg, ll l, ll r, ll node)
	{
	//	dbgv(lseg);dbgv(rseg);dbgv(l);dbgv(r);dbgv(node);
		if (lseg>r||rseg<l) return;
		if (lseg<=l && r<=rseg)
		{
			tomul[node]*=val;
			tomul[node]%=L;
			return;
		}
		ll mid = (l+r)/2;
		mul(val, lseg, rseg, l,mid, node*2);
		mul(val, lseg, rseg, mid+1,r , node*2+1);
	}
};
vector<vector<ll>> tree;
vector<vector<ll>> children;
vector<ll> parent;
array<vector<ll>, 42> binright;
array<vector<ll>, 42> binleft;
vector<ll> dfsstack;
void dfs(ll node)
{
	dfsstack.push_back(node);
	for (ll child : tree[node])
	{
		if (child==parent[node]) continue;
		children[node].push_back(child);
		parent[child]=node;
		dfs(child);
	}
	/*if (ll(dfsstack.size())>3 && dfsstack[ll(dfsstack.size()) - 3]==536)
	{
		dbgv("huh");
		dbgv(node);
	}*/
	for (ll p = 0; p<42 && (ll(dfsstack.size()) - 1 - p)>=0; ++p)
	{
		ll ancnode = dfsstack[ll(dfsstack.size()) - 1 - p];
		if (binleft[p][ancnode]==-1)
		{
			binleft[p][ancnode]=node;
		}
		binright[p][ancnode]=node;
	}
	dfsstack.pop_back();
}
vector<ll> posn;
pll getdescendent(ll node, ll d)
{
	/*ll l = node;
	ll r = node;
	for (ll p = 0; (1ll<<p)<=d; ++p)
	{
		//dbgv(l);dbgv(r);dbgv(p);
		if (((d>>p)&1ll) == 1)
		{
			l = binleft[p][l];
			r = binright[p][r];
		}
		if (l==-1 || r==-1)
		{
			dbgv(node);
			dbgv(d);
			dbgv(r);
			return {-1,-1};
		}
	}
	for (ll i = 0; i < d; ++i)
	{
		l = binleft[0][l];
		r = binright[0][r];
		if (l==-1 || r==-1)
		{
			dbgv(node);
			dbgv(d);
			dbgv(r);
			return {-1,-1};
		}
	}
	if (posn[l]<=posn[r]) return {l,r};
	else return {-1,-1};*/
	assert(!((binleft[d][node]==-1)^(binright[d][node]==-1)));
	return {binleft[d][node],binright[d][node]};
}
int main()
{
	cin.tie(nullptr);
	ios_base::sync_with_stdio(false);
	dbgv("Started");
	cin >> N >> L;
	tree.assign(N,{});
	for (ll i = 0; i < N-1; ++i)
	{
		ll a,b;
		cin >> a >> b;
		a--; b--; //c
		tree[a].push_back(b);
		tree[b].push_back(a);	
	}
	children.assign(N,{});
	parent.assign(N,-1);
	binleft.fill(vector<ll>(N,-1));
	binright.fill(vector<ll>(N,-1));
	dfs(0);
	ll currposn = 0;
	posn.assign(N,-1);
	queue<ll> bfsq;
	bfsq.push(0);
	while (!bfsq.empty())
	{
		ll curr=bfsq.front();
		bfsq.pop();
		posn[curr] = currposn++;
		for (ll child:children[curr])
		{
			bfsq.push(child);
		}
	}
	/*for (ll p = 0; p<25; p++)
	{
		for (ll i = 1; i < N; ++i)
		{
			if (binright[p][posn[i]]==-1)
			{
				binright[p][posn[i]] = binright[p][posn[i-1]];
			}
		}
		for (ll i = N-2; i >=0; --i)
		{
			if (binleft[p][posn[i]]==-1)
			{
				binleft[p][posn[i]] = binleft[p][posn[i+1]];
			}
		}
	}*/
		
dbgv("p0 done");
	segtree H(N);
	for (ll i = 0; i < N; ++i)
	{
		ll Hi;
		cin >> Hi;
		H.mul(Hi,posn[i],posn[i], 0,N-1,1);
	}
	dbgv("p1 done");
	ll Q;
	cin >> Q;
	for (ll qno = 0; qno < Q; ++qno)
	{
		/*dbgv(qno);
		dbgfor (ll i = 0; i < N; ++i)
		{
			cerr << (H[posn[i]]) << " ";
		}*/
		ll t;
		cin >> t;
		if (t==1)
		{
			ll Xi,Di,Wi;
			cin >> Xi >> Di >> Wi;
			Xi--;//c
			ll currn = Xi;
			for (ll h = 0; h < Di; ++h)
			{
				//dbgv(currn+1);
				if (currn==0)
				{
					for (ll d = 1; d <= Di-h; ++d)
					{
						pll r1 = getdescendent(currn,d);
						if (r1!=pll{-1,-1})
						{
							H.mul(Wi,posn[r1.e0],posn[r1.e1], 0,N-1,1);
						}
						/*for (ll i = posn[r1.e0]; i <= posn[r1.e1]; ++i)
						{
							H[i] *= Wi;
							H[i] %= L;
						}*/
					}
					break;
				}
				pll r = getdescendent(currn,Di-h);
				if (r!=pll{-1,-1})
					{
							H.mul(Wi,posn[r.e0],posn[r.e1], 0,N-1,1);
						}
				/*for (ll i = posn[r.e0]; i <= posn[r.e1]; ++i)
				{
					H[i] *= Wi;
					H[i] %= L;
				}*/
				r = getdescendent(currn,Di-h-1);
				if (r!=pll{-1,-1})
					{
							H.mul(Wi,posn[r.e0],posn[r.e1], 0,N-1,1);
						}
				/*for (ll i = posn[r.e0]; i <= posn[r.e1]; ++i)
				{
					H[i] *= Wi;
					H[i] %= L;
				}*/
				currn=parent[currn];
				assert(currn>=0);
			}
			//dbgv(currn+1);
			/*H[posn[currn]] *= Wi;
			H[posn[currn]] %= L;*/
			{
				H.mul(Wi,posn[currn],posn[currn], 0,N-1,1);
			}
		}
		else if (t==2)
		{
			ll Xi;
			cin >> Xi;
			Xi--;//c
			cout << H.get(posn[Xi], 0,N-1,1) << "\n";
		}
		else throw exception();
	}
}
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... | 
| # | Verdict | Execution time | Memory | Grader output | 
|---|
| Fetching results... |