#include <bits/stdc++.h>
int diru[] = {-1, -1, -1, 0, 0, 1, 1, 1};
int dirv[] = {-1, 0, 1, -1, 1, -1, 0, 1};
using namespace std;
struct debugger {
  template <typename T>
  debugger &operator,(const T &v) {
    cerr << v << " ";
    return *this;
  }
} dbg;
template <class T>
T sq(T n) {
  return n * n;
}
template <class T>
T gcd(T a, T b) {
  return (b != 0 ? gcd<T>(b, a % b) : a);
}
template <class T>
T lcm(T a, T b) {
  return (a / gcd<T>(a, b) * b);
}
template <class T>
bool inside(T a, T b, T c) {
  return a <= b && b <= c;
}
template <class T>
void setmax(T &a, T b) {
  if (a < b) a = b;
}
template <class T>
void setmin(T &a, T b) {
  if (b < a) a = b;
}
template <class T>
T power(T N, T P) {
  return (P == 0) ? 1 : N * power(N, P - 1);
}
vector<int> G[200100];
int par[200100];
int in[200100];
int depth[200100];
int cnt[2][200100];
int lazy[2][200100 * 4];
int tree[2][200100 * 4];
int pos[2][200100];
vector<int> pre[2];
void dfs(int f, int u, int p, int d) {
  if ((d & 1) == f) {
    par[u] = p;
    depth[u] = f;
    pos[f][u] = ((int)pre[f].size());
    pre[f].push_back(u);
    cnt[f][u] = 1;
  }
  int i, v;
  for (i = 0; i < ((int)G[u].size()); i++) {
    v = G[u][i];
    if (v == p) continue;
    dfs(f, v, u, d + 1);
    cnt[f][u] += cnt[f][v];
  }
}
int x, y, val;
int update(int *F, int *dp, int node, int b, int e) {
  if (b > e) return 0;
  int p, q;
  if ((x <= b && y >= e) || y < b || x > e) goto second;
  p = update(F, dp, 2 * node, b, (b + e) / 2);
  q = update(F, dp, 2 * node + 1, 1 + (b + e) / 2, e);
  dp[node] = p + q;
second:;
  if (x <= b && y >= e) F[node] += val;
  dp[node] += F[node] * (int)(e - b + 1);
  if (b != e) {
    F[2 * node] += F[node];
    F[2 * node + 1] += F[node];
  }
  F[node] = 0;
  return dp[node];
}
int query(int *F, int *dp, int node, int b, int e) {
  if (b > e) return 0;
  if (y < b || x > e) return 0;
  if (b != e) {
    F[2 * node] += F[node];
    F[2 * node + 1] += F[node];
  }
  dp[node] += F[node] * (int)(e - b + 1);
  F[node] = 0;
  if (x <= b && y >= e) {
    return dp[node];
  }
  int p = query(F, dp, 2 * node, b, (b + e) / 2);
  int q = query(F, dp, 2 * node + 1, 1 + (b + e) / 2, e);
  return p + q;
}
int getC(int u) {
  int v, i;
  for (i = 0; i < ((int)G[u].size()); i++) {
    v = G[u][i];
    if (v == par[u]) continue;
    return v;
  }
  return -1;
}
int main() {
  int n, T, t = 1, m, i, j, k, u, s, ans, q, v;
  scanf("%d", &n);
  scanf("%d", &m);
  for (i = 1; i < n + 1; i++) scanf("%d", &in[i]);
  G[0].push_back(1);
  for (i = 1; i < n; i++) {
    scanf("%d", &j);
    scanf("%d", &k);
    G[j].push_back(k);
    G[k].push_back(j);
  }
  dfs(0, 0, 0, 0);
  dfs(1, 0, 0, 0);
  for (u = 1; u < n + 1; u++) {
    s = in[u];
    k = depth[u];
    x = pos[k][u];
    y = pos[k][u];
    val = s;
    update(lazy[k], tree[k], 1, 0, ((int)pre[k].size()) - 1);
  }
  while (m--) {
    scanf("%d", &q);
    if (q == 1) {
      scanf("%d", &u);
      scanf("%d", &s);
      k = depth[u];
      x = pos[k][u];
      y = pos[k][u] + cnt[k][u] - 1;
      val = s;
      update(lazy[k], tree[k], 1, 0, ((int)pre[k].size()) - 1);
      k = 1 - k;
      v = getC(u);
      if (v == -1) continue;
      x = pos[k][v];
      y = x + cnt[k][u] - 1;
      val = -s;
      update(lazy[k], tree[k], 1, 0, ((int)pre[k].size()) - 1);
    } else {
      scanf("%d", &u);
      k = depth[u];
      x = pos[k][u];
      y = pos[k][u];
      ans = query(lazy[k], tree[k], 1, 0, ((int)pre[k].size()) - 1);
      printf("%d\n", ans);
    }
  }
  return 0;
}
