#include<bits/stdc++.h>
using namespace std;
struct _IO{_IO(){ios::sync_with_stdio(0);cin.tie(0);}}_io;

#pragma GCC optimize(2)
#define int ll
using ll = long long;
using db = long double;
using pi = pair<int, int>;
using mi = map<int, int>;
using vi = vector<int>;
#define fi first
#define se second
#define eb emplace_back
#define vt vector
#define sz size()
#define be begin()
#define rbe rbegin()
#define all(x) x.begin(), x.end()
#define rep(i, l, r) for (int i = (l); i < (r); ++i)
#define per(i, r, l) for (int i = (r); i >= (l); --i)

void prl() {cout << '\n';} template <class T, class ...U> void prl(T x, U ...y) {cout << x << ' ', prl(y...);}

template <class T, class U> ostream &operator << (ostream &out, pair<T, U> p) { return out << "(" << p.fi << ", " << p.se << ")"; }
template <class T> ostream &operator << (ostream &out, vt<T> &v) { out << "{"; rep(i, 0, v.sz) { if (i) out << ", "; out << v[i]; } return out << "}"; }
#ifdef LOCAL
#define dbg(...) prl(__VA_ARGS__), cout.flush()
#define __int128 ll
#else
#define dbg(...) 233
#endif

const int N = 2e5 + 5, M = 1e9 + 7;
using ull = unsigned long long;

int a[N], fa[N];

int Find(int x) {
	if (fa[x] == x) return x;
	return fa[x] = Find(fa[x]);
}
map<int, int> cnt[N];

signed main() {
	int n, m;
	cin >> n >> m;
	for (int i = 0; i < n; i++) {
		int x;
		cin >> x;
		cnt[i + 1][x] = 1;
	}
	iota(fa, fa + n + 1, 0);
	while (m--) {
		int op, x, y;
		cin >> op >> x >> y;
		if (op == 1) {
			x = Find(x), y = Find(y);
			if (x == y) continue;
			fa[x] = y;
			if (cnt[y].sz < cnt[x].sz) swap(cnt[x], cnt[y]);
			for (auto &p : cnt[x]) {
				cnt[y][p.fi] += p.se;
			}
		} else {
			x = Find(x);
			if (cnt[x].count(y)) {
				cout << cnt[x][y];
			} else {
				cout << 0;
			}
			cout << '\n';
		}
	}
}

#pragma GCC target("avx2")
#pragma GCC optimize("O3")
#pragma GCC optimize("unroll-loops")
#pragma warning(disable : 4996)

//#define ATCODER
#ifdef ATCODER
#include<atcoder/all>
using namespace atcoder;
#endif


#include <algorithm>
#include <utility>
#include <vector>
#include <limits.h>
#include <math.h>
#include <time.h>
#include <algorithm>
#include <array>
#include <bitset>
#include <cassert>
#include <complex>
#include <cstdio>
#include <cstring>
#include <functional>
#include <iomanip>
#include <iostream>
#include <iterator>
#include <map>
#include <numeric>
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <vector>
#include <cassert>
#include <numeric>
#include <type_traits>

using namespace std;



#ifdef _MSC_VER
#include"stdafx.h"
#include <intrin.h>
#define __builtin_popcount __popcnt
#define __builtin_popcountll __popcnt64
void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
	cerr << " " << (H);
	debug_out(T...);
}
#define DEBUG(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define DEBUG(...) 42
#endif



#define ll long long
#define REP(i, n) for (ll i = 0; i < (n); ++i)
#define REPR(i, n) for (ll i = (n) - 1; i >= 0; --i)
#define FOR(i, m, n) for (ll i = (m); i < (n); ++i)
#define VSORT(v) sort(v.begin(), v.end());
#define VREVERSE(v) reverse(v.begin(), v.end())

#define print(x) cout << (x) << '\n'
#define spa <<" "<<
#define lb(v, n) lower_bound(v.begin(), v.end(), (n))
#define ub(v, n) upper_bound(v.begin(), v.end(), (n))
#define int long long
//#define double long double
#define all(x) (x).begin(), (x).end()
#define print_space(v) REP(i, v.size()) cout << v[i] << " \n"[i==(int)v.size()-1]
template <typename T1, typename T2> inline bool chmin(T1 & a, T2 b) { if (a > b) { a = b; return true; }return false; }
template <typename T1, typename T2> inline bool chmax(T1& a, T2 b) { if (a < b) { a = b; return true; }return false; }
typedef pair<int, int> pii;
typedef pair<long long, long long> pll;
std::random_device rd;
std::mt19937 mt(rd());
constexpr ll MOD = 1e9 + 7;
constexpr int MAX = 400040;
const double pi = acos(-1);
constexpr long double EPS = 1e-14;
const int dx[4] = { 0,0,-1,1 }, dy[4] = { -1,1,0,0 };
using ld = long double;

struct edge {
	int from, to;
};
vector<edge>es;
vector<int>G[200020];
int par[200020];
void init_dfs(int n) {
	for (auto nxt : G[n]) {
		if (nxt == par[n])continue;
		par[nxt] = n;
		init_dfs(nxt);
	}
}

int C[200020];

void dfs(int n) {
	for (auto nxt : G[n]) {
		if (nxt == par[n])continue;
		C[nxt] += C[n];
		dfs(nxt);
	}
}

void solve() {
	int N; cin >> N;
	REP(_, N - 1) {
		int u, v; cin >> u >> v;
		u--, v--;
		G[u].push_back(v);
		G[v].push_back(u);
		es.push_back({ u,v });
	}
	init_dfs(0);
	int Q; cin >> Q;
	REP(_, Q) {
		int t, e, x; cin >> t >> e >> x;
		e--;
		int a = es[e].from, b = es[e].to;
		if (t == 2)swap(a, b);
		DEBUG(a+1, b+1, x);
		if (a == par[b]) {
			C[0] += x;
			C[b] -= x;
		}
		else {
			C[a] += x;
		}
	}
	dfs(0);
	REP(i, N) {
		print(C[i]);
	}
}

signed main() {
	cin.tie(0);
	ios::sync_with_stdio(false);
	//int q; cin >> q;
	//while (q--)
	solve();
}