rt WA on #2
#include<bits/stdc++.h>
using namespace std;
namespace zorr{
#ifdef getchar_unlocked
#define gc getchar_unlocked
#define pc putchar_unlocked
#else
#define gc getchar
#define pc putchar
#endif
#define FORG(h,e,i,u) for(int i=h[u];i;i=e[i].nxt)
#define rep(i,l,r,k) for(int i=l;i<=r;i+=k)
#define rrep(i,r,l,k) for(int i=r;i>=l;i-=k)
#define clr(a,val) memset(a,val,sizeof a)
#define cpy(a,b) memcpy(a,b,sizeof a)
#define pb emplace_back
#define mkp make_pair
const int inf=0x3f3f3f3f;
const long long infll=0x3f3f3f3f3f3f3f3fll;
const __int128 infi128=(__int128(1)<<126);
mt19937 __rnd(time(0));
__int128 read()
{
char ch=gc();int x=0;
bool w=0;
for(;!isdigit(ch);ch=gc())w|=(ch=='-');
for(;isdigit(ch);ch=gc())x=(x<<3)+(x<<1)+(ch^48);
return w?-x:x;
}
void write(__int128 x)
{
if(x<0)pc('-'),x=-x;
if(x>9)write(x/10);
pc(x%10+48);
}
void file(string in,string out)
{
freopen(in.c_str(),"r",stdin);
freopen(out.c_str(),"w",stdout);
}
int rnd(int l,int r)
{
int x=abs((int)(__rnd()));
return x%(r-l+1)+l;
}
int qpow(int x,int y,int mod)
{
int res=1;
while(y)
{
if(y&1)
res=res*x%mod;
x=x*x%mod;
y>>=1;
}
return res;
}
}
#define int long long
using namespace zorr;
const int N=1e5+5;
int a[N],h[N],to[N<<1],nxt[N<<1],_;
int sz[N],son[N],dep[N],dp[N][21];
int dfn[N],pos[N],top[N],id;
void add(int u,int v){to[++_]=v,nxt[_]=h[u],h[u]=_;}
//--------------- 树剖 ----------------
void dfs1(int u,int f)
{
dep[u]=dep[f]+1;
sz[u]=1;
son[u]=-1;
dp[u][0]=f;
rep(i,1,20,1)dp[u][i]=dp[dp[u][i-1]][i-1];
for(int i=h[u];i;i=nxt[i])
{
int v=to[i];
if(v==f)continue;
dfs1(v,u);
sz[u]+=sz[v];
if(son[u]==-1||sz[v]>sz[son[u]])
son[u]=v;
}
}
void dfs2(int u,int t)
{
dfn[u]=++id;
top[u]=t;
pos[id]=u;
if(~son[u])dfs2(son[u],t);
for(int i=h[u];i;i=nxt[i])
{
int v=to[i];
if(v==dp[u][0]||v==son[u])
continue;
dfs2(v,v);
}
}
int LCA(int x,int y)
{
while(top[x]^top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
x=dp[top[x]][0];
}
return dfn[x]<dfn[y]?x:y;
}
//--------------- 树剖 ----------------
//--------------- 线段树 ---------------
int mi[N<<2],tag[N<<2];
void pushup(int p){mi[p]=min(mi[p<<1],mi[p<<1|1]);}
void addtag(int p,int d){mi[p]=d,tag[p]=d;}
void pushdown(int p){if(tag[p]!=infll){addtag(p<<1,tag[p]),addtag(p<<1|1,tag[p]),tag[p]=infll;}}
void build(int p,int pl,int pr)
{
tag[p]=infll;
if(pl==pr){mi[p]=a[pos[pl]];return ;}
int mid=(pl+pr)>>1;
build(p<<1,pl,mid);build(p<<1|1,mid+1,pr);
pushup(p);
}
void update(int p,int pl,int pr,int L,int R,int v)
{
if(R<pl||pr<L)return ;
if(L<=pl&&pr<=R)return addtag(p,v);
int mid=(pl+pr)>>1;pushdown(p);
update(p<<1,pl,mid,L,R,v);update(p<<1|1,mid+1,pr,L,R,v);
pushup(p);
}
int query(int p,int pl,int pr,int L,int R)
{
if(R<pl||pr<L)return infll;
if(L<=pl&&pr<=R)return mi[p];
int mid=(pl+pr)>>1;
return min(query(p<<1,pl,mid,L,R),query(p<<1|1,mid+1,pr,L,R));
}
//--------------- 线段树 ---------------
void solve()
{
int n,m,rt;
cin>>n>>m;
rep(i,1,n-1,1)
{
int u,v;
cin>>u>>v;
add(u,v);add(v,u);
}
rep(i,1,n,1)cin>>a[i];
cin>>rt;
dfs1(1,0);dfs2(1,1);build(1,1,n);
rep(__,1,m,1)
{
int op,x,y,k;cin>>op;
if(op==1)cin>>rt;
if(op==2)
{
cin>>x>>y>>k;
while(top[x]^top[y])
{
if(dep[top[x]]<dep[top[y]])swap(x,y);
update(1,1,n,dfn[top[x]],dfn[x],k);
x=dp[top[x]][0];
}
if(dfn[x]>dfn[y])swap(x,y);
update(1,1,n,dfn[x],dfn[y],k);
}
if(op==3)
{
cin>>x;
if(x==rt)cout<<mi[1]<<'\n';
else if(LCA(x,rt)==x)
{
int p=rt;
rrep(i,20,0,1)
if(dp[p][i]&&dep[dp[p][i]]>dep[x])
p=dp[p][i];
int res=inf;
if(dfn[p]>1)res=min(res,query(1,1,n,1,dfn[p]-1));
if(dfn[p]+sz[p]<=n)res=min(res,query(1,1,n,dfn[p]+sz[p],n));
cout<<res<<'\n';
}
else cout<<query(1,1,n,dfn[x],dfn[x]+sz[x]-1)<<'\n';
}
}
}
signed main()
{
ios_base::sync_with_stdio(false);
cin.tie(0);
int T=1;
//cin>>T;
//T=read();
rep(i,1,T,1)solve();
}