// ROOT : DRAGON3012009 : Wa In Real Life
#include <bits/stdc++.h>
#define ll long long
#define el "\n"
#define _ROOT_ int main()
#define FOR(i,l,r) for(int i = l ; i <= r ; i ++)
#define FORD(i,r,l) for(int i = r ; i >= l ; i --)
#define REP(i, a ) for(int i = 0 ; i < a ; i ++ )
#define fi first
#define se second
#define M 1000000007
#define MAXN 200001
#define INF (1ll<<60)
#define NAME "file"
#define debug(a) cerr << #a << " = " << a << endl ;
#define compare(v) sort((v).begin(), (v).end()); (v).erase(unique((v).begin(), (v).end()), (v).end());
using namespace std;
const ll MOD[] = {(ll)1e9 + 2277, (ll)1e9 + 5277, (ll)1e9 + 8277, (ll)1e9 + 9277, (ll) 1e9 + 7 };
const ll NMOD = 1;

ll n, q ;
ll a[MAXN];
ll st[MAXN ], fin[MAXN ], timeDFS ;
ll chainID[MAXN ], chainHead[MAXN ], curChain  ;
ll sz[MAXN ], bigchild[MAXN ], par[MAXN ] , high[MAXN ] ;
vector<ll> adj[MAXN ] ;

struct Node
{
    ll res, pre, suf, sum, trash ;
};



Node MergeNode(Node a, Node b )
{
    if(a.trash ) return b ;
    if(b.trash ) return a ;
    Node res ;
    res.sum = a.sum + b.sum ;
    res.pre = max(a.pre, a.sum + b.pre ) ;
    res.suf = max(b.suf, a.suf + b.sum ) ;
    res.trash = 0 ;
    res.res = max({a.res, b.res, a.suf + b.pre, a.sum + b.pre, a.suf + b.sum }) ;
    return res ;
}

struct Seg
{
    Node val[MAXN << 2 ] ;
    void update(ll id, ll l, ll r, ll pos, ll value )
    {
        if(l == r)
        {
            ll nv = max(0LL, value ) ;
            val[id] = {nv, nv, nv, value, 0 } ;
        }
        else
        {
            ll m = l + r >> 1 ;
            if(m >= pos ) update(id << 1, l, m, pos, value ) ;
            else update(id << 1 | 1, m + 1, r,  pos, value ) ;
            val[id] = MergeNode(val[id << 1], val[id << 1 | 1 ]) ;
        }
    }
    Node get(ll id, ll l, ll r, ll u, ll v )
    {
        if(u > r || v < l ) return {1, 1, 1, 1, 1 } ;
        if(u <= l && v >= r ) return val[id] ;
        ll m = l + r >> 1 ;
        return MergeNode(get(id << 1, l, m, u, v ), get(id << 1 | 1, m + 1, r, u, v )) ;
    }
} seg ;

void hld(ll u, ll p )
{
    if(!chainHead[curChain ]) chainHead[curChain ] = u ;
    chainID[u] = curChain ;
    st[u] = ++timeDFS ;
    if(bigchild[u] != 0 ) hld(bigchild[u] , u ) ;

    for(ll v : adj[u] ) if(v != p && v != bigchild[u]) {
        curChain ++ ;
        hld(v , u   ) ;
    }

    fin[u] = timeDFS ;
}

ll LCA(ll u , ll v ) {
//    debug(u) ;
while(chainID[u] != chainID[v]) {
    if(chainID[u] > chainID[v]) u = par[chainHead[chainID[u]]] ;
    else v = par[chainHead[chainID[v]]] ;
//    debug(u ) ;
//    debug(v ) ;
}
if(high[u] > high[v]) swap(u , v ) ;
return u ;
}

Node get_path(ll u , ll v ) {
    ll lca = LCA(u , v ) ;
    Node res ;
    res.trash = true ;
    vector<Node> L , R ;

    while(chainID[u] != chainID[lca ]) {
        L.push_back(seg.get(1 , 1 , n , st[chainHead[chainID[u]]] , st[u] )) ;
        u = par[chainHead[chainID[u]]] ;
//        debug(u) ;
    }

    while(chainID[v] != chainID[lca ]) {
        R.push_back(seg.get(1 , 1 , n , st[chainHead[chainID[v]]] , st[v] )) ;
        v = par[chainHead[chainID[v]]] ;
    }

    if(high[u] <= high[v] ) R.push_back(seg.get(1 , 1 , n , st[u] , st[v]) ) ;
    if(high[u] > high[v] ) L.push_back(seg.get(1 , 1 , n , st[v] , st[u]) ) ;
    for(Node & it : L ) {
        swap(it.pre , it.suf ) ;
    }
    for(Node & it : L ) res = MergeNode(res , it ) ;
    reverse(R.begin() , R.end() ) ;
    for(Node & it : R ) res = MergeNode(res , it ) ;
    return res ;
}

void dfs(ll u, ll p )
{
    sz[u] = 1 ;
    ll ma = 0 ;
    for(ll v : adj[u]) if(v != p )
        {
            high[v] = high[u  ] + 1  ;
            par[v] = u ;
            dfs(v, u ) ;
            sz[u] += sz[v] ;
            if(ma == 0 || sz[ma] < sz[v]) ma = v ;
        }
    bigchild[u] = ma ;
}

void init()
{
    cin >> n >> q ;
    FOR(i, 1, n ) cin >> a[i] ;
    FOR(i, 2, n )
    {
        ll x, y ;
        cin >> x >> y ;
        adj[x].push_back(y) ;
        adj[y].push_back(x) ;
    }
    dfs(1, 1 ) ;
    hld(1, 1  ) ;
    FOR(i, 1, n ) seg.update(1, 1, n, st[i], a[i]) ;
}

void solve()
{
    FOR(cnt , 1 , q ) {
    ll t , l , r ; cin >> t >> l >> r ;
    if(t == 1 ) seg.update(1 , 1 , n , st[l] , r ) ;
    else {
        Node res = get_path(l , r ) ;
        cout << res.res << el ;
    }
    }
}

_ROOT_
{
    // freopen(NAME".inp" , "r" , stdin);
    // freopen(NAME".out" , "w", stdout) ;
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
    int t = 1; // cin >> t ;
    while(t--)
    {
        init();
        solve();
    }
    return (0&0);
}
