#include <bits/stdc++.h>
#define pii pair<int,int>
#define fs first
#define sc second
#define pb push_back
#define zeros(x) x&(-x)
#define all(v) v.begin(), v.end()
#define MOD 1000000007
#define oo 2000000010
#define pii pair<int,int>
#define ll long long
#define ld long double
#define ull unsigned long long
#define mem(a) memset(a,0,sizeof(a))
#define pi 3.14159265359
using namespace std;
ifstream fin("heavypath.in");
ofstream fout("heavypath.out");
vector <int> v[100010], lant[100010], arb[100010];
int a[100010],d[100010], id[100010], poz[100010], subarb[100010],t[100010];
bool viz[100010];
int i,nrl,m,x,y,n,op;
void dfs(int nod, int depth)
{
viz[nod] = 1;
d[nod] = depth;
subarb[nod] = 1;
int maxi = 0, f = -1;
for(int i=0; i<v[nod].size(); ++i)
if(!viz[v[nod][i]])
{
t[v[nod][i]] = nod;
dfs(v[nod][i], depth+1);
int nod2 = v[nod][i];
subarb[nod] += subarb[ nod2 ];
if(subarb[v[nod][i]] > maxi)
{
maxi = subarb[v[nod][i]];
f = v[nod][i];
}
}
if(f == -1)
{
++nrl;
lant[nrl].pb(nod);
poz[nod] = 1;
id[nod] = nrl;
}
else
{
lant[id[f]].pb(nod);
poz[nod] = lant[id[f]].size();
id[nod] = id[f];
}
}
void init(int idx,int nod, int l, int r)
{
if(l == r)
arb[idx][nod] = a[lant[idx][l-1]];
else
{
init(idx,2*nod,l,(l+r)/2);
init(idx,2*nod+1,(l+r)/2+1,r);
arb[idx][nod] = max(arb[idx][2*nod], arb[idx][2*nod+1]);
}
}
void update(int idx, int nod, int l, int r)
{
if(l == r) arb[idx][nod] = a[x];
else
{
if(poz[x] > (l+r)/2) update(idx,2*nod+1, (l+r)/2+1, r);
else update(idx,2*nod,l,(l+r)/2);
arb[idx][nod] = max(arb[idx][2*nod], arb[idx][2*nod+1]);
}
}
int query_aint(int idx, int nod, int l, int r, int pozx, int pozy)
{
if(pozy < l || pozx > r) return 0;
if(pozx <= l && pozy >= r) return arb[idx][nod];
else
{
int auxr = query_aint(idx,2*nod+1,(l+r)/2+1, r, pozx,pozy);
int auxl = query_aint(idx,2*nod, l,(l+r)/2, pozx, pozy);
return max(auxr,auxl);
}
}
int query(int x, int y)
{
if(id[x] == id[y])
{
return query_aint(id[x],1,1,lant[id[x]].size(),min(poz[x],poz[y]), max(poz[x],poz[y]));
}
else
{
if( d[lant[id[x]][lant[id[x]].size()-1]] < d[lant[id[y]][lant[id[y]].size()-1]] )
swap(x,y);
int aux = query_aint(id[x],1,1,lant[id[x]].size(), poz[x], lant[id[x]].size() );
return max(aux,query(t[lant[id[x]][lant[id[x]].size()-1]],y));
}
}
int main()
{
fin>>n>>m;
for(i=1; i<=n; ++i)
fin>>a[i];
for(i=1; i<n; ++i)
{
fin>>x>>y;
v[x].pb(y);
v[y].pb(x);
}
dfs(1,0);
for(i=1; i<=nrl; ++i)
{
arb[i].resize(4*lant[i].size()+2);
init(i,1,1,lant[i].size());
}
for(i=1;i<=m;++i)
{
fin>>op>>x>>y;
if(op==0)
{
a[x] = y;
update(id[x],1,1,lant[id[x]].size());
}
else
{
fout<<query(x,y)<<'\n';
}
}
return 0;
}