#include<bits/stdc++.h>
#define int long long
#define R1 register
#define F(i,a,b) for(int i = (a);i<=(b);i++)
using namespace std;
inline int read(){R1 int x=0,t=1;R1 char ch=getchar();while(ch<'0'||ch>'9'){if(ch=='-') t=-1;ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+(ch^48);ch=getchar();}return x*t;}
const int N=2e6+10;
int n,m,rt;
vector<int>g[N];
void add(int ui,int vi)
{
g[ui].push_back(vi);
return;
}
int siz[N],dep[N],fa[N],son[N];
void dfs1(int u,int Fa)
{
siz[u]=1;
dep[u]=dep[Fa]+1;
fa[u]=Fa;
for(int v:g[u]){
if(v==Fa) continue;
dfs1(v,u);
siz[u]+=siz[v];
if(siz[v]>siz[son[u]]) son[u]=v;
}
return;
}
int id[N],top[N],b[N],val[N],tot;
void dfs2(int u,int topf)
{
id[u]=++tot;
top[u]=topf;
b[tot]=val[u];
if(son[u]) dfs2(son[u],topf);
for(int v:g[u]){
if(id[v]) continue;
dfs2(v,v);
}
}
#define ls(x) x*2
#define rs(x) x*2+1
struct node
{
int l,r,minn,lazy;
}tr[N*4];
void pushup(int x)
{
tr[x].minn=min(tr[ls(x)].minn,tr[rs(x)].minn);
return;
}
void build(int x,int l,int r)
{
tr[x].l=l,tr[x].r=r;
tr[x].lazy=-1;
if(l==r){
tr[x].minn=b[l];
return;
}
int mid=l+r>>1;
build(ls(x),l,mid);
build(rs(x),mid+1,r);
pushup(x);
return;
}
void pushdown(int x)
{
if(tr[x].lazy!=-1){
tr[ls(x)].minn=tr[ls(x)].lazy=tr[x].lazy;
tr[rs(x)].minn=tr[rs(x)].lazy=tr[x].lazy;
tr[x].lazy=-1;
}
return;
}
void update(int x,int l,int r,int k)
{
if(tr[x].l>=l && tr[x].r<=r){
tr[x].minn=k;
tr[x].lazy=k;
return;
}
pushdown(x);
int mid=tr[x].l+tr[x].r>>1;
if(mid>=l) update(ls(x),l,r,k);
if(mid<r) update(rs(x),l,r,k);
pushup(x);
}
void upRange(int x,int y,int k)
{
while(top[x]!=top[y]){
if(dep[top[x]]<dep[top[y]]) swap(x,y);
update(1,id[top[x]],id[x],k);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
update(1,id[x],id[y],k);
return;
}
int query(int x,int l,int r)
{
if(r<l) return 1e16;
if(tr[x].l>=l && tr[x].r<=r){
return tr[x].minn;
}
pushdown(x);
int mid=tr[x].l+tr[x].r>>1,minn=1e16;
if(mid>=l) minn=min(minn,query(ls(x),l,r));
if(mid<r) minn=min(minn,query(rs(x),l,r));
pushup(x);
return minn;
}
int qson(int x)
{
if(rt==x){
return query(1,1,n);
}
if(id[rt]>=id[x] && id[rt]<=id[x]+siz[x]-1){
return min(query(1,1,id[rt]-1),query(1,id[rt]+siz[rt],n));
}
else{
return query(1,id[x],id[x]+siz[x]-1);
}
}
signed main()
{
n=read(),m=read();
for(int i = 2;i<=n;i++){
int ui=read(),vi=read();
add(ui,vi);
add(vi,ui);
}
for(int i = 1;i<=n;i++){
val[i]=read();
}
rt=read();
dfs1(rt,0);
dfs2(rt,rt);
build(1,1,n);
for(int i = 1;i<=m;i++){
int op=read();
if(op==1){
rt=read();
}
else if(op==2){
int x=read(),y=read(),v=read();
upRange(x,y,v);
}
else{
int x=read();
cout << qson(x) << '\n';
}
}
return 0;
}