#include <iostream>
#include <fstream>
#include <vector>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector<int> v[100001], x[100001];
int n, k, k1, kk=1, y[100001], niv[100001], g[100001], lung[100001];
int dp[17][100001], log2[100001], d[500001], apar1[100001], apar2[100001];
bool p[100001];
void DFS(int nod)
{d[++k1]=nod;
p[nod]=1;
apar1[nod]=apar2[nod]=k1;
vector<int>:: iterator I;
for(I=v[nod].begin();I<v[nod].end();I++)
if(p[*I]==0)
{niv[*I]=niv[nod]+1;
DFS(*I);
g[nod]+=g[*I];
d[++k1]=nod;
apar2[nod]=k1;
}
g[nod]++;
}
void QS(int ind, int st, int dr)
{if(st<dr)
{int i=st, j=dr, d=0;
swap(v[ind][st], v[ind][(st+dr)/2]);
while(i<j)
{if(g[v[ind][i]]<g[v[ind][j]])swap(v[ind][i], v[ind][j]);
i+=d;
j-=1-d;
}
QS(ind, st, i-1);
QS(ind, i+1, dr);
}
}
struct nod{
int l, nr, t;
}nod[100001];
void DFS1(int no)
{int k=0;
p[no]=0;
vector<int>:: iterator I;
for(I=v[no].begin();I<v[no].end();I++)
if(p[*I]==1)
{k++;
if(k==1)nod[*I]={nod[no].l+1, nod[no].nr, nod[no].t}, lung[nod[no].nr]++;
else nod[*I]={1, ++kk, no}, lung[kk]=1;
DFS1(*I);
}
}
void Update(int no, int st, int dr, int ind, int p, int v)
{if(st==dr)
x[ind][no]=v;
else
{int mij=(st+dr)/2;
if(mij>=p)Update(no*2, st, mij, ind, p, v);
else Update(no*2+1, mij+1, dr, ind, p, v);
x[ind][no]=max(x[ind][no*2], x[ind][no*2+1]);
}
}
int Query(int no, int st, int dr, int ind, int qs, int qd)
{if(qs<=st && qd>=dr)
return x[ind][no];
else
{int mij=(st+dr)/2;
if(mij>=qd)return Query(no*2, st, mij, ind, qs, qd);
if(mij<qs)return Query(no*2+1, mij+1, dr, ind, qs, qd);
int a=Query(no*2, st, mij, ind, qs, qd), b=Query(no*2+1, mij+1, dr, ind, qs, qd);
return max(a, b);
}
}
void F(int r, int a, int b)
{int a1=0, b1=0;
if(nod[r].nr==nod[a].nr)
a1=Query(1, 1, lung[nod[a].nr], nod[a].nr, nod[r].l, nod[a].l);
else
{a1=Query(1, 1, lung[nod[a].nr], nod[a].nr, 1, nod[a].l);
a=nod[a].t;
while(nod[a].nr!=nod[r].nr)
a=nod[a].t, a1=max(a1, Query(1, 1, lung[nod[a].nr], nod[a].nr, 1, nod[a].l));
a1=max(a1, Query(1, 1, lung[nod[a].nr], nod[a].nr, nod[r].l, nod[a].l));
}
if(nod[r].nr==nod[b].nr)
b1=Query(1, 1, lung[nod[b].nr], nod[b].nr, nod[r].l, nod[b].l);
else
{b1=Query(1, 1, lung[nod[b].nr], nod[b].nr, 1, nod[b].l);
b=nod[b].t;
while(nod[b].nr!=nod[r].nr)
b=nod[b].t, b1=max(b1, Query(1, 1, lung[nod[b].nr], nod[b].nr, 1, nod[b].l));
b1=max(b1, Query(1, 1, lung[nod[b].nr], nod[b].nr, nod[r].l, nod[b].l));
}
fout<<max(a1, b1)<<"\n";
}
int main()
{ int q, a, b, c;
fin>>n>>q;
for(int i=1;i<=n;i++)
fin>>y[i];
for(int i=1;i<n;i++)
{fin>>a>>b;
v[a].push_back(b);
v[b].push_back(a);
}
niv[1]=1;
DFS(1);
for(int i=1;i<=n;i++)
if(v[i].size()!=0)QS(i, 0, v[i].size()-1);
nod[1]={1, 1}, lung[1]=1;
nod[1].t=1;
DFS1(1);
for(int i=1;i<=k1;i++)
{if(i!=1)log2[i]=log2[i/2]+1;
dp[0][i]=d[i];
}
for(int i=1;i<=log2[k1];i++)
for(int j=1<<i;j<=k1;j++)
if(niv[dp[i-1][j-(1<<(i-1))]]<=niv[dp[i-1][j]])dp[i][j]=dp[i-1][j-(1<<(i-1))];
else dp[i][j]=dp[i-1][j];
for(int i=1;i<=kk;i++)
for(int j=0;j<=4*lung[i];j++)
x[i].push_back(0);
for(int i=1;i<=n;i++)
Update(1, 1, lung[nod[i].nr], nod[i].nr, nod[i].l, y[i]);
for(int i=1;i<=q;i++)
{fin>>a>>b>>c;
if(a==0)
{Update(1, 1, lung[nod[b].nr], nod[b].nr, nod[b].l, c);
y[b]=c;
}
else
{int r, v1=min(apar1[b], apar1[c]), v2=max(apar2[b], apar2[c]), dist;
dist=log2[v2-v1+1];
if(niv[dp[dist][v1+(1<<dist)]]<=niv[dp[dist][v2]])r=dp[dist][v1+(1<<dist)];
else r=dp[dist][v2];
F(r, b, c);
}
}
return 0;
}