#include <bits/stdc++.h>
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
const int NMAX=1e5;
int n,i,v[NMAX+5],q,s[NMAX+5],parent[NMAX+5],depth[NMAX+5],heavy[NMAX+5],head[NMAX+5],poz[NMAX+5],g[NMAX+5],node1,node2,t;
bool viz[NMAX+5];
vector <int> adj[NMAX+5];
struct SegTree{
int A[4*NMAX+5],sol;
void build(int nod, int st, int dr, int v[])
{
if (st==dr)
A[nod]=v[st];
else
{
int mij=(st+dr)>>1;
build(2*nod,st,mij,v);
build(2*nod+1,mij+1,dr,v);
A[nod]=max(A[2*nod],A[2*nod+1]);
}
}
void update(int nod ,int st ,int dr ,int p, int x)
{
if (st==dr)
A[nod]=x;
else
{
int mij=(st+dr)>>1;
if (p<=mij)
update(2*nod,st,mij,p,x);
else
update(2*nod+1,mij+1,dr,p,x);
A[nod]=max(A[2*nod],A[2*nod+1]);
}
}
void query(int nod, int st ,int dr ,int a ,int b)
{
if (a<=st && dr<=b)
sol=max(A[nod],sol);
else
{
int mij=(st+dr)>>1;
if (a<=mij)
query(2*nod,st,mij,a,b);
if (b>mij)
query(2*nod+1,mij+1,dr,a,b);
}
}
int ans(int st, int dr)
{
sol=0;
query(1,1,n,st,dr);
return sol;
}
}AINT;
void dfs(int node)
{
viz[node]=1;
s[node]=1;
heavy[node]=-1;
int sz=0;
for (auto node2: adj[node])
{
if (!viz[node2])
{
depth[node2]=depth[node]+1;
parent[node2]=node;
dfs(node2);
s[node]+=s[node2];
if (sz<s[node2])
{
sz=s[node2];
heavy[node]=node2;
}
}
}
}
void dfs_HLD(int node, int h)
{
head[node]=h;
poz[node]= ++t;
g[poz[node]]=v[node];
viz[node]=1;
if (heavy[node]!=-1)
dfs_HLD(heavy[node],h);
for (auto node2: adj[node])
if (!viz[node2])
dfs_HLD(node2,node2);
}
int query(int a, int b)
{
int ans=0;
while (head[a]!=head[b])
{
if (depth[head[a]]<depth[head[b]])
swap(a,b);
ans=max(ans,AINT.ans(poz[head[a]],poz[a]));
a=parent[head[a]];
}
if (depth[a]>depth[b])
swap(a,b);
ans=max(ans,AINT.ans(poz[a],poz[b]));
return ans;
}
int main()
{
ios_base::sync_with_stdio(false);
fin.tie(nullptr); fout.tie(nullptr);
fin>>n>>q;
for (i=1; i<=n; i++)
fin>>v[i];
for (i=1; i<n; i++)
{
fin>>node1>>node2;
adj[node1].push_back(node2);
adj[node2].push_back(node1);
}
dfs(1);
for (i=1; i<=n; i++)
viz[i]=0;
dfs_HLD(1,1);
AINT.build(1,1,n,g);
while(q--)
{
int x,y;
fin>>t>>x>>y;
if (t==0)
AINT.update(1,1,n,poz[x],y);
else
fout<<query(x,y)<<'\n';
}
return 0;
}