#include <fstream>
#include <vector>
#include <cmath>
#define Nmax 100001
#define pb push_back
using namespace std;
ofstream g("heavypath.out");
struct nod{
nod *st,*dr;
int val;
nod (nod *_st,nod *_dr,int _val) : st(_st), dr(_dr), val(_val) {};
}*AINT[Nmax];
int lg[Nmax];
vector<int> V[Nmax],L[Nmax];
int val[Nmax],x,y,nrf[Nmax],Lid[Nmax],poz[Nmax],nrL,n,m,niv[Nmax],T[Nmax],t;
void update(nod *N,int st,int dr,int poz,int val)
{
if (N->st == NULL)
N->st = new nod(NULL,NULL,0);
if (N->dr == NULL)
N->dr = new nod(NULL,NULL,0);
if (st==dr)
{
N->val = val;
return;
}
int mid = (st+dr)/2;
if (poz>mid)
update(N->dr,mid+1,dr,poz,val);
else
update(N->st,st,mid,poz,val);
N->val = max(N->st->val,N->dr->val);
}
void make_aint(vector<int> &L,int x)
{
AINT[x] = new nod(NULL,NULL,0);
lg[x] = (1<<(int)log2(L.size()))*2;
for (int i=0;i<L.size();i++)
update(AINT[x],0,lg[x],i+1,val[L[i]]);
}
int dfs(int nod,int p,int nv)
{
int nr = 0,x,mx = -1,sav = -1;
niv[nod] = nv;
for (int i=0;i<V[nod].size();i++)
{
if (V[nod][i]!=p)
{
x = dfs(V[nod][i],nod,nv+1);
if (x>mx)
{
mx = x;
sav = V[nod][i];
}
nr+=x;
}
}
if (sav==-1)
{
Lid[nod] = ++nrL;
poz[nod] = L[Lid[nod]].size()+1;
L[Lid[nod]].pb(nod);
}
else
{
Lid[nod] = Lid[sav];
poz[nod] = L[Lid[nod]].size()+1;
L[Lid[nod]].pb(nod);
}
for (int i=0;i<V[nod].size();i++)
if (V[nod][i]!=p)
T[V[nod][i]] = nod;
return nr+1;
}
int query(nod *N,int st,int dr,int L,int R)
{
if (N->st == NULL)
N->st = new nod(NULL,NULL,0);
if (N->dr == NULL)
N->dr = new nod(NULL,NULL,0);
if (L<=st && dr<=R)
return N->val;
int mid = (st+dr)/2,a=0,b=0;
if (L<=mid)
a = query(N->st,st,mid,L,R);
if (R>mid)
b = query(N->dr,mid+1,dr,L,R);
return max(a,b);
}
int path(int x,int y)
{
if (poz[x]>poz[y])
swap(x,y);
if (Lid[x]==Lid[y])
return query(AINT[Lid[x]],0,lg[Lid[x]],poz[x],poz[y]);
if (niv[T[x]]<niv[T[y]])
swap(x,y);
return max(query(AINT[Lid[x]],0,lg[Lid[x]],poz[x],lg[Lid[x]]),path(T[x],y));
}
int main()
{
freopen("heavypath.in","r",stdin);
scanf("%d%d",&n,&m);
for (int i=1;i<=n;i++)
scanf("%d",&val[i]);
for (int i=1;i<n;i++)
{
scanf("%d%d",&x,&y);
V[x].pb(y);
V[y].pb(x);
}
dfs(1,-1,1);
for (int i=1;i<=nrL;i++)
make_aint(L[i],i);
for (int i=1;i<=m;i++)
{
scanf("%d%d%d",&t,&x,&y);
if (t==0)
update(AINT[Lid[x]],0,lg[Lid[x]],poz[x],y);
if (t==1)
{
g<<path(x,y)<<'\n';
}
}
return 0;
}