#include <iostream>
#include <fstream>
#include <algorithm>
#include <vector>
using namespace std;
#define MAXN 100000
typedef vector<int> vi;
int n;
int initial[MAXN];
vi e[MAXN];
int lv[MAXN];
int sz[MAXN];
int numpaths=1;
int path[MAXN];
int pp[MAXN];
int parent[MAXN+5];
int lenpath[MAXN+5];
int lvpath[MAXN+5];
struct node
{
node *l, *r;
int x,y;
int v;
node(int x, int y): l(0),r(0),x(x),y(y),v(0) {}
};
node *trees[MAXN];
void dfs(int f, int t)
{
pp[t] = f;
if (t) lv[t] = lv[f]+1;
sz[t]=1;
for (auto i:e[t])
if (i!=f)
{
dfs(t,i);
sz[t]+=sz[i];
}
for (auto i:e[t])
if (i!=f && 2*sz[i]>=sz[t])
{
path[t] = path[i];
lenpath[path[t]]++;
} else if (i!=f)
{
parent[path[i]] = i;
}
if (!path[t]) path[t] = numpaths++,lenpath[path[t]]++;
}
void itrees(node *t)
{
if (t->x==t->y) return;
int m = (t->x+t->y)/2;
t->l = new node(t->x,m);
t->r = new node(m+1,t->y);
itrees(t->l);
itrees(t->r);
}
void dfs2(int f, int t)
{
if (f+1 && path[f]!=path[t]) lvpath[path[t]] = lv[path[f]]+1;
for (auto i:e[t])
if (i!=f) dfs2(t,i);
}
void init()
{
lv[0]=0;
dfs(-1,0);
pp[0] = 0;
lv[path[0]]=0;
parent[path[0]] = 0;
dfs2(-1,0);
for (int i=1; i<numpaths; i++)
trees[i] = new node(0,lenpath[i]-1),itrees(trees[i]);
}
void upd(node *t,int pos,int k)
{
if (t->x>pos) return;
if (t->y<pos) return;
if (t->x == t->y)
t->v = k;
else
{
upd(t->l,pos,k);
upd(t->r,pos,k);
t->v= max(t->l->v,t->r->v);
}
}
void update(int x, int k)
{
node *t;
t = trees[path[x]];
int pos = lv[x] - lv[parent[path[x]]];
upd(t,pos,k);
}
int ans = 0;
void qq(node *t, int l, int r)
{
if (t->x>r) return;
if (t->y<l) return;
if (l<=t->x && r>=t->y)
ans = max(ans,t->v);
else
{
qq(t->l,l,r);
qq(t->r,l,r);
}
}
int query(int x, int y)
{
ans = 0;
while (true)
{
if (path[x]==path[y])
{
int lx = lv[x] - lv[parent[path[x]]];
int ly = lv[y] - lv[parent[path[y]]];
qq(trees[path[x]],min(lx,ly),max(lx,ly));
break;
} else
{
if (lvpath[path[x]]<lvpath[path[y]]) swap(x,y);
int lx;
lx = lv[x] - lv[parent[path[x]]];
qq(trees[path[x]],0,lx);
x = parent[path[x]];
x = pp[x];
}
}
return ans;
}
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
int main()
{
int m;
fin>>n>>m;
for (int i=0; i<n; i++)
fin>>initial[i];
for (int i=0; i<n-1; i++)
{
int x,y;
fin>>x>>y;
x--,y--;
e[x].push_back(y);
e[y].push_back(x);
}
init();
for (int i=0; i<n; i++)
update(i,initial[i]);
for (int i=0; i<m; i++)
{
int cod,x,y;
fin>>cod>>x>>y;
if (!cod) update(x-1,y);
else
{
int d =query(x-1,y-1);
fout<<d<<'\n';
}
}
return 0;
}