Problem: Problem

Aizu Magic School is a school where people who can use magic gather. Aizu Magic School has classrooms numbered from 1 to N and a corridor connecting the classrooms. You can go through the classrooms and corridors as many times as you like. In addition, Aizu Magic School has only one route that allows you to move between any classroom u and v through 0 or more classrooms and a corridor once. A magic circle is set up in each classroom. This magic square increases or decreases the magical power of those who enter the classroom each time they enter the classroom. Please answer the following two questions to help the students move.

question 1
0 A B
I want you to output the remaining amount of magical power when you move from classroom A to B. Including increase / decrease in classrooms A and B. Also, the amount of magical power at the beginning of this question is 0 each time.

Question 2
1 A C
The amount of increase / decrease in the magical power of classroom A changes by C.

Constraints

The input satisfies the following conditions.

* 1 ≤ N ≤ 2000
* 1 ≤ Ai ≤ 2000
* 1 ≤ Bi ≤ 2000
* 1 ≤ aj, bj ≤ N
* 1 ≤ Q ≤ 1000000
* -10000 ≤ Ci ≤ 10000

Input


N
cost1
::
costN
a1 b1
::
aN-1 bN-1
Q
query1
::
queryQ


The number N of classrooms is given at the beginning of the input. The following N lines are given the amount of magical power that increases or decreases when entering each classroom. The value on the i-line corresponds to the information in the classroom on the i-th line. Corridor information is given to the following N-1 line. The corridor on the jth line represents connecting the ajth and bjth classrooms. Then the number of questions Q is given. The following Q line is given the question in the above format.

Output

Output the answer to one line for each question 1.

Example

Input

7
1
2
3
4
5
6
7
1 2
1 3
3 4
3 5
5 6
5 7
10
0 1 7
0 2 7
1 1 15
0 1 7
0 2 7
0 1 1
1 1 -15
0 1 7
0 2 7
0 1 1


Output

16
18
31
33
16
16
18
1

Solution (in CPP):

Solution:
#include <bits/stdc++.h>
using namespace std;

#define dump(...) (cerr<<#__VA_ARGS__<<" = "<<(DUMP(),__VA_ARGS__).str()<<endl)
struct DUMP : stringstream {
    template<class T>
    DUMP &operator,(const T &t) {
        if(this->tellp()) *this << ", ";
        *this << t;
        return *this;
    }
};

class BIT {
private:
    int size;
    vector<long long> bit;

public:
    BIT(int n = 0):size(n), bit(n + 1, 0) {}

    void add(int i, long long x) {
        while(i <= size) {
            bit[i] += x;
            i += i & -i;
        }
    }

    long long sum(int i) const {
        long long s = 0;
        while(i > 0) {
            s += bit[i];
            i -= i & -i;
        }
        return s;
    }
};

const int MAX_N = 2000;
const int MAX_LOG_N = 12;

int n;
int parent[MAX_LOG_N][MAX_N];
int depth[MAX_N];

long long cost[MAX_N];
vector<int> edges[MAX_N];

int pos_plus[MAX_N];
int pos_minus[MAX_N];

BIT bit(MAX_N * 2);

void dfs(int v, int p, int d, int &index) {
    parent[0][v] = p;
    depth[v] = d;

    pos_plus[v] = index;
    bit.add(index++, cost[v]);

    for(const auto &to : edges[v]) {
        if(to != p) dfs(to, v, d + 1, index);
    }

    pos_minus[v] = index;
    bit.add(index++, -cost[v]);
}

void calc() {
    int index = 1;
    dfs(0, -1, 0, index);
	assert(index == 2 * n + 1);
    for(int k = 0; k < MAX_LOG_N - 1; ++k) {
        for(int v = 0; v < n; ++v) {
            parent[k + 1][v] = (parent[k][v] == -1 ? -1 : parent[k][parent[k][v]]);
        }
    }
}

int lca(int u, int v) {
    if(depth[u] > depth[v]) swap(u, v);
    for(int k = 0; k < MAX_LOG_N; ++k) {
        if((depth[v] - depth[u]) >> k & 1) v = parent[k][v];
    }
    if(u == v) return u;
    for(int k = MAX_LOG_N - 1; k >= 0; --k) {
        if(parent[k][u] != parent[k][v]) {
            u = parent[k][u];
            v = parent[k][v];
        }
    }
    return parent[0][u];
}

int main() {
	cin.tie(nullptr);
	ios::sync_with_stdio(false);

    cin >> n;

    for(int i = 0; i < n; ++i) {
        cin >> cost[i];
    }

    for(int i = 0; i < n - 1; ++i) {
        int a, b;
        cin >> a >> b;
        --a; --b;
        edges[a].emplace_back(b);
        edges[b].emplace_back(a);
    }

    calc();

    int q;
    cin >> q;
	while(q--) {
        int x;
        cin >> x;

        if(x) {
            int a;
			long long c;
            cin >> a >> c;
            --a;
            cost[a] += c;
            bit.add(pos_plus[a], c);
            bit.add(pos_minus[a], -c);
        }
        else {
            int a, b;
            cin >> a >> b;
            --a; --b;
            if(pos_plus[a] > pos_plus[b]) swap(a, b);
            const int l = lca(a, b);
            cout << (bit.sum(pos_plus[a]) - bit.sum(pos_plus[l])) - (bit.sum(pos_minus[l]) - bit.sum(pos_minus[b] - 1)) << endl;
        }
    }

    return 0;
}