#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cctype>
#include <cmath>
#include <string>
#include <algorithm>
#include <vector>
#include <queue>
#include <deque>
#include <set>
#include <stack>
#include <ctime>
#include <cassert>
using namespace std;
#define PRO "heavypath"
void OpenFiles(int EVAL)
{
if(EVAL)
{
char input[100] = PRO, output[100] = PRO;
freopen(strcat(input, ".in"),"r",stdin);
freopen(strcat(output,".out"),"w",stdout);
} else
{
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
}
}
#define MAX 100001
#define MOD 666013
#define INF 0xffffff
#define EPS 1E-8
vector<int>graf[MAX], path[MAX], inter[MAX];
int val_nod[MAX], nr_sub[MAX], nr_niv[MAX], parent[MAX], whatpath[MAX], whatpos[MAX];
bool nod_vizitat[MAX];
int n, nr_path, retq;
void dfs_sub(int x,int cur_niv)
{
nr_niv[x] = cur_niv;
nod_vizitat[x] = 1;
for(int i=0;i<graf[x].size();i++)
if(!nod_vizitat[ graf[x][i] ])
{
dfs_sub( graf[x][i], cur_niv + 1 );
nr_sub[x] += nr_sub[ graf[x][i] ];
}
nr_sub[x] += 1;
}
void dfs_lant(int x,int nr_path,int pos)
{
//printf("(%d %d %d) ,",x,nr_path,pos);
nod_vizitat[x] = 1;
whatpath[x] = nr_path;
whatpos[x] = pos;
path[ nr_path ].push_back( x );
int next = 0;
for(int i=0;i<graf[x].size();i++)
if(!nod_vizitat[ graf[x][i] ] && (next == 0 || nr_sub[ graf[x][i] ] > nr_sub[ next ])) next = graf[x][i];
if(next && !nod_vizitat[ next ])
{
parent[ next ] = x;
dfs_lant( next, nr_path, pos+1);
return;
}
}
int lca(int x,int y)
{
if(x == y)return x;
else
{
if( nr_niv[x] > nr_niv[y] )
lca(parent[x],y); else
lca(x,parent[y]);
}
}
void update(vector<int>&path,int pos,int val,int nod,int lf,int rt)
{
//printf("%d %d %d %d %d\n",pos,val,nod,lf,rt);
if(lf == rt)
{
path[nod] = val;
return;
}
int md = (lf+rt)/2;
if(pos <= md) update(path,pos,val,2*nod,lf,md); else
update(path,pos,val,2*nod+1,md+1,rt);
path[nod] = max( path[2*nod], path[2*nod+1] );
}
void query(vector<int>path, int st, int dr, int nod, int lf, int rt)
{
if(st <= lf && rt <= dr)
{
retq = max( retq, path[nod] );
return;
}
int md = (lf+rt)/2;
if(st <= md) query(path, st, dr, 2*nod, lf, md);
if( dr > md ) query(path, st, dr, 2*nod+1, md+1, rt);
}
int heavy_query(int x,int y)
{
int ret = val_nod[ x ];
while( x != y )
{
if( whatpath[ x ] == whatpath[ y ] )
{
retq = 0;
query(inter[ whatpath[x] ], whatpos[x], whatpos[y], 1, 1, path[ whatpath[x] ].size()-1);
ret = max( ret, retq );
y = x;
} else
{
retq = 0;
query(inter[ whatpath[y] ], 1, whatpos[y], 1, 1, path[ whatpath[y] ].size()-1);
ret = max( ret, retq );
y = parent[y];
}
}
return ret;
}
int main(int argv,char *args[])
{
OpenFiles(argv==0);
/* start code */
int m,t,x,y;
scanf("%d %d",&n,&m);
for(int i=1;i<=n;i++) scanf("%d",&val_nod[i]);
for(int i=1;i<n;i++)
{
scanf("%d %d",&x,&y);
graf[x].push_back(y);
graf[y].push_back(x);
}
dfs_sub(1,1);
//for(int i=1;i<=n;i++)printf("%d ",nr_sub[i]); printf("\n");
//for(int i=1;i<=n;i++)printf("%d ",nr_niv[i]); printf("\n");
memset(nod_vizitat,0,sizeof(nod_vizitat));
for(int i=1;i<=n;i++)
if(!nod_vizitat[i])
{
for(int j=0;j<graf[i].size();j++)
if(nod_vizitat[ graf[i][j] ])
{
parent[i] = graf[i][j];
break;
}
nr_path += 1;
path[ nr_path ].push_back(0);
dfs_lant(i, nr_path, 1);
//printf("\n");
}
//for(int i=0;i<path[1].size();i++)printf("%d ",path[1][i]); return 0;
//inter[1].resize(1<<int(log( double(path[1].size()) )/log( double(2) ) + 1));
for(int nr_i = 1; nr_i <= nr_path; nr_i++)
{
inter[ nr_i ].resize(1<<int(log( double(path[ nr_i ].size()) )/log( double(2) ) + 2));
for(int i=1;i<path[ nr_i ].size();i++)
{//printf("------------\n");
update( inter[nr_i], i, val_nod[ path[ nr_i ][i] ], 1, 1, path[ nr_i ].size()-1);}
//for(int i=1;i<inter[ nr_i ].size();i++ )printf("%d ",inter[ nr_i ][i]);
//printf("\n");
}
/*int str; x = 1; y = 6;
str = lca( x, y );
printf("%d\n",max( heavy_query(str, x), heavy_query(str, y) ));
*/
int str;
while(m--)
{
scanf("%d %d %d",&t ,&x, &y);
if(t)
{
if(x == 1 && y == 6)
str=0;
if(x>y)swap( x, y );
str = lca( x, y );
printf("%d\n",max( heavy_query(str, x), heavy_query(str, y) ));
} else
{
val_nod [x] = y;
//printf("(%d) ",whatpath[x]);s
update( inter[ whatpath[x] ], whatpos[x], y, 1, 1, path[ whatpath[x] ].size() - 1);
//for(int i=1;i<inter[ whatpath[x] ].size();i++)printf("%d ",inter [ whatpath[x] ][i]); printf("\n");
}
}
//for(int i=1;i<=n;i++)
// for(int j=1;j<=n;j++)
// if(whatpath[i] != whatpath[j]) printf("lca(%d,%d)=%d\n",i,j,lca(i,j));
/* end */
return 0;
}