#include <bits/stdc++.h>
#define inf (int)(2e9 + 1)
using namespace std;

// 0-indexed
template <class T, class E>
struct SegmentTreeLaze {
  // a,b:T c,d:E e:E(unit)
  // g(f(a,b),c) = f(g(a,c),g(b,c))
  // g(g(a,c),d) = g(a,h(c,d))
  // g(a,e) = a
  typedef function<T(T, T)> F;
  typedef function<T(T, E)> G;
  typedef function<E(E, E)> H;
  int n, height;
  F f;
  G g;
  H h;
  T tunit;
  E eunit;
  vector<T> dat;
  vector<E> laz;
  SegmentTreeLaze(){};
  SegmentTreeLaze(int newn, F f, G g, H h, T nt, E ne)
      : f(f), g(g), h(h), tunit(nt), eunit(ne) {
    init(newn);
  }
  SegmentTreeLaze(const vector<T> &v, F f, G g, H h, T nt, E ne)
      : f(f), g(g), h(h), tunit(nt), eunit(ne) {
    int _n = v.size();
    init(v.size());
    for (int i = 0; i < _n; ++i) dat[n + i] = v[i];
    for (int i = n - 1; i; --i) dat[i] = f(dat[i << 1], dat[(i << 1) | 1]);
  }
  void init(int newn) {
    n = 1, height = 0;
    while (n < newn) n <<= 1, ++height;
    dat.assign(n << 1, tunit);
    laz.assign(n << 1, eunit);
  }

  inline T reflect(int k) {
    return laz[k] == eunit ? dat[k] : g(dat[k], laz[k]);
  }

  inline void eval(int k) {
    if (laz[k] == eunit) return;
    laz[k << 1] = h(laz[k << 1], laz[k]);
    laz[(k << 1) | 1] = h(laz[(k << 1) | 1], laz[k]);
    dat[k] = reflect(k);
    laz[k] = eunit;
  }

  inline void thrust(int k) {
    for (int i = height; i; --i) eval(k >> i);
  }

  void recalc(int k) {
    while (k >>= 1) dat[k] = f(reflect(k << 1), reflect((k << 1) | 1));
  }
  // [a,b)
  void update(int a, int b, E newdata) {
    thrust(a += n);
    thrust(b += n - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1) laz[l] = h(laz[l], newdata), l++;
      if (r & 1) --r, laz[r] = h(laz[r], newdata);
    }
    recalc(a);
    recalc(b);
  }

  void set_val(int k, T newdata) {
    thrust(k += n);
    dat[k] = newdata;
    laz[k] = eunit;
    recalc(k);
  }

  // [a,b)
  T query(int a, int b) {
    thrust(a += n);
    thrust(b += n - 1);
    T vl = tunit, vr = tunit;
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1) vl = f(vl, reflect(l++));
      if (r & 1) vr = f(reflect(--r), vr);
    }
    return f(vl, vr);
  }
};

struct HeavyLightDecomposition {
  int root;
  vector<vector<int>> g;
  vector<int> sz, par, dep, in, out, head;
  HeavyLightDecomposition(int n = 1, int _root = 0)
      : root(_root), g(n), sz(n), par(n), dep(n), in(n), out(n), head(n) {}
  HeavyLightDecomposition(const vector<vector<int>> &_g, const int _root = 0)
      : root(_root),
        g(_g),
        sz(_g.size()),
        par(_g.size()),
        dep(_g.size()),
        in(_g.size()),
        out(_g.size()),
        head(_g.size()) {
    build();
  }
  void add(int a, int b) {
    g[a].push_back(b);
    g[b].push_back(a);
  }
  void build() {
    dfs_sz(root, -1, 0);
    int t = 0;
    dfs_hld(root, -1, t);
  }
  void dfs_sz(int now, int bf, int d) {
    dep[now] = d;
    par[now] = bf;
    sz[now] = 1;
    if (g[now].size() && g[now][0] == bf) swap(g[now][0], g[now].back());
    for (auto &to : g[now]) {
      if (to == bf) continue;
      dfs_sz(to, now, d + 1);
      sz[now] += sz[to];
      if (sz[g[now][0]] < sz[to]) swap(g[now][0], to);
    }
  }
  void dfs_hld(int now, int bf, int &t) {
    in[now] = t++;
    for (auto &to : g[now]) {
      if (to == bf) continue;
      head[to] = (g[now][0] == to ? head[now] : to);
      dfs_hld(to, now, t);
    }
    out[now] = t;
  }
  int lca(int x, int y) {
    for (;; y = par[head[y]]) {
      if (in[x] > in[y]) swap(x, y);
      if (head[x] == head[y]) return x;
    }
  }
  int chil(int x, int y) { return dep[x] < dep[y] ? y : x; }
  //[l,r)
  template <typename F>
  void for_each(int x, int y, const F &f) {
    for (;; y = par[head[y]]) {
      if (in[x] > in[y]) swap(x, y);
      f(max(in[head[y]], in[x]), in[y] + 1);
      if (head[x] == head[y]) return;
    }
  }
  //[l,r)
  template <typename F>
  void for_eachq(int x, int y, const F &f) {
    bool ch = 0;
    for (;; y = par[head[y]]) {
      if (in[x] > in[y]) {
        swap(x, y);
        ch = !ch;
      }
      f(max(in[head[y]], in[x]), in[y] + 1, ch);
      if (head[x] == head[y]) return;
    }
  }
};

struct dat {
  int all, lef, righ, res, cnt;
  dat() {}
  dat(int a, int l, int r, int re, int c)
      : all(a), lef(l), righ(r), res(re), cnt(c) {}
};

int n, q;
vector<vector<int>> g;
vector<dat> initv;
SegmentTreeLaze<dat, int> seg;
HeavyLightDecomposition hld;

int main() {
  auto sectmerge = [](dat l, dat r) {
    if (l.res == -inf) return r;
    if (r.res == -inf) return l;
    dat resd = l;
    resd.all += r.all;
    resd.lef = max(l.lef, l.all + r.lef);
    resd.righ = max(l.righ + r.all, r.righ);
    resd.res = max({resd.lef, resd.righ, l.res, r.res, l.righ + r.lef});
    resd.cnt += r.cnt;
    return resd;
  };
  auto affect = [](dat l, int x) {
    if (x == inf) return l;
    int num = max(l.cnt * x, x);
    return dat(l.cnt * x, num, num, num, l.cnt);
  };
  auto queryupdate = [](int l, int r) { return r; };
  cin >> n >> q;
  g.resize(n);
  initv.resize(n);
  seg = SegmentTreeLaze<dat, int>(n, sectmerge, affect, queryupdate,
                                  dat(0, 0, 0, -inf, 0), inf);
  for (int i = 0; i < n; ++i) {
    cin >> initv[i].all;
    initv[i].lef = initv[i].righ = initv[i].res = initv[i].all;
    initv[i].cnt = 1;
  }
  for (int i = 1; i < n; ++i) {
    int x, y;
    cin >> x >> y;
    g[--x].push_back(--y);
    g[y].push_back(x);
  }
  hld = HeavyLightDecomposition(g);
  for (int i = 0; i < n; ++i) seg.set_val(hld.in[i], initv[i]);
  for (int i = 0; i < q; ++i) {
    int t, a, b, c;
    cin >> t >> a >> b >> c;
    if (t == 1)
      hld.for_each(--a, --b, [&](int l, int r) { seg.update(l, r, c); });
    else {
      dat resl(0, 0, 0, -inf, 0), resr(0, 0, 0, -inf, 0);
      auto calc = [&](int l, int r, bool ch) {
        if (ch)
          resl = sectmerge(seg.query(l, r), resl);
        else
          resr = sectmerge(seg.query(l, r), resr);
      };
      hld.for_eachq(--a, --b, calc);
      swap(resl.lef, resl.righ);
      cout << sectmerge(resl, resr).res << endl;
    }
  }
  return 0;
}



Measured memory_bytes: 55356