#include <stdio.h>
#include <algorithm>
#include <cstring>
#include <cctype>
#define lson k << 1
#define rson k << 1 | 1
using namespace std;
typedef long long ll;
const int maxn=1e5+5;
int head[maxn],nex[maxn<<1],ver[maxn<<1],tot;
int dep[maxn],sz[maxn],son[maxn],fa[maxn],rev[maxn],id[maxn],top[maxn],idx;
int maxx[maxn<<2];
int a[maxn];
ll s[maxn<<2];
int n,m;
inline int read()
{
int x=0;
char ch=getchar();
while(ch<48||ch>57) ch=getchar();
while(ch>=48&&ch<=57) x=x*10+ch-48,ch=getchar();
return x;
}
inline void add(int x,int y)
{
ver[++tot]=y;
nex[tot]=head[x];
head[x]=tot;
}
inline void dfs(int x,int f)
{
dep[x]=dep[f]+1;fa[x]=f;sz[x]=1;
for(int i=head[x];i;i=nex[i])
{
int y=ver[i];
if(y==f) continue ;
dfs(y,x);
sz[x]+=sz[y];
if(sz[y]>sz[son[x]]) son[x]=y;
}
}
inline void dfs2(int x,int t)
{
id[x]=++idx;top[x]=t;rev[id[x]]=a[x];
if(!son[x]) return ;
dfs2(son[x],t);
for(int i=head[x];i;i=nex[i])
{
int y=ver[i];
if(y!=fa[x]&&y!=son[x])
dfs2(y,y);
}
}
inline void pushup(int k)
{
//printf("##%d %d %d \n",k,lson,rson);
s[k]=s[lson]+s[rson];
maxx[k]=maxx[lson]>maxx[rson]?maxx[lson]:maxx[rson];
}
inline void build(int k,int l,int r)
{
if(l==r)
{
s[k]=maxx[k]=rev[l];
return;
}
int mid=l+r>>1;
build(lson,l,mid);
build(rson,mid+1,r);
pushup(k);
}
inline void change(int k,int l,int r,int x,int v)
{
if(l==r)
{
s[k]=maxx[k]=v;
return;
}
int mid=l+r>>1;//
if(x<=mid) change(lson,l,mid,x,v);
else change(rson,mid+1,r,x,v);
pushup(k);
}
inline void change_mod(int k,int l,int r,int x,int y,int q)
{
if(maxx[k]<q) return;
if(l==r)//
{
s[k]%=q;
maxx[k]=s[k];
return;
}
int mid=l+r>>1;
if(x<=mid) change_mod(lson,l,mid,x,y,q);
if(mid<y) change_mod(rson,mid+1,r,x,y,q);//
pushup(k);
}
inline ll query(int k,int l,int r,int x,int y)
{
if(l>y||r<x||l>r) return 0;//
if(l>=x&&r<=y) return s[k];
int mid=l+r>>1;
ll ans=0;//
if(mid>=x) ans+=query(lson,l,mid,x,y);
if(mid<y) ans+=query(rson,mid+1,r,x,y);
return ans;
}
inline ll ask(int x,int y)
{
ll res=0;
while(top[x]!=top[y])
{
if(dep[top[x]]<dep[top[y]]) swap(x,y);
res+=query(1,1,n,id[top[x]],id[x]);
x=fa[top[x]];
}
if(dep[x]>dep[y])swap(x,y);
res+=query(1,1,n,id[x],id[y]);
return res;
}
int main()
{
freopen("flower.in","r",stdin);
freopen("flower.out","w",stdout);
// scanf("%d%d",&n,&m);
n=read();m=read();
//printf("%d",n);
for(int i=1;i<=n-1;i++)
{
int x,y;
// scanf("%d%d",&x,&y);
x=read();y=read();
add(x,y);
add(y,x);
}
for(int i=1;i<=n;i++) a[i]=read();//scanf("%d",&a[i]);
dfs(1,0);
dfs2(1,1);
build(1,1,n);
for(int i=1,op,a1,a2;i<=m;i++)
{
op=read();
//printf("!%d\n",op);
a1=read();
a2=read();
//scanf("%d%d%d",&op,&x,&y);
if(op==1) change_mod(1,1,n,id[a1],id[a1]+sz[a1]-1,a2);
if(op==2) change(1,1,n,id[a1],a2);
if(op==3) printf("%lld\n",ask(a1,a2));
}
return 0;
}