//题意:有一棵树,有两个指令
// 指令1:0 u delta,这棵树长出了一些果子, 即u的子树中的每个节点都会长出delta个果子
// 指令2:1 k u1 v1 ... uk vk,小明希望你求出几条树枝上的果子数. 一条树枝其实就是一个从某个节点到根的路径的一段. 每次小明会选定一些树枝, 让你求出在这些树枝
// 上的节点的果子数的和。注意, 树枝之间可能会重合, 这时重合的部分的节点的果子只要算一次。
//思路:第一个指令很简单,直接dfs序区间操作就好
// 主要是第二个指令,充分发挥了树剖将路径操作转化为区间的性质
// 将路径转化许多区间之后,如果有路径重合,那么就是有区间重合,我们直接并区间就好
// (ps:本题的查询部分的树状数组懒得写了,只写到区间并的阶段)
//
#include<bits/stdc++.h>
using namespace std;
#define int long long
const int N = 2e5 + 10;
int tr[N];
int n, q;
vector<int> mp[N];
int dep[N], siz[N], son[N], L[N], R[N], f[N], tot, top[N], idx[N];
void dfs(int x, int fa) {
dep[x] = dep[fa] + 1;
f[x] = fa;
siz[x] = 1;
for (auto y : mp[x]) {
if (y == fa) continue;
dfs(y, x);
siz[x] += siz[y];
if (siz[son[x]] < siz[y])
son[x] = y;
}
}//重链剖分前置处理
void dfs1(int x, int w) {
L[x] = ++tot;
top[x] = w;
idx[tot] = x;
if (son[x]) dfs1(son[x], w);
for (auto y : mp[x]) {
if (y == f[x] || y == son[x]) continue;
dfs1(y, y);
}
R[x] = tot;
}//重链剖分,注意dfs序是这个时候的dfs序,因为之后要根据这个来更新线段树的(这道题用树状数组来整)
void modify(int x, int s) {
for (; x <= n; x += x & (-x))
tr[x] += s;
}
pair<int, int> edge[4 * N]; int cnt;
void query(int u, int v) {
while(top[u]!=top[v]){
if (dep[top[u]] < dep[top[v]]) {
edge[++cnt] = { L[top[v]], L[v] };
v = f[top[v]];
}
else {
edge[++cnt] = { L[top[u]], L[u] };
u = f[top[u]];
}
}
if (dep[u] <= dep[v]) edge[++cnt] = { L[u],L[v] };
else edge[++cnt] = { L[v],L[u] };
}
int way[4 * N][2]; int cnt1;//记录最终路径数
void merge() {
sort(edge + 1, edge + 1 + cnt);
way[0][0] = 0, way[0][1] = 0;
for (int i = 1; i <= cnt; i++) {
if (edge[i].first <= way[cnt1][1])
way[cnt1][1] = max(way[cnt1][1], edge[i].second);
else if (edge[i].first > way[cnt1][1]) {
way[++cnt1][0] = edge[i].first;
way[cnt1][1] = edge[i].second;
}
}
}//合并所有询问区间
int lookfor(int x) {
int s = 0;
for (; x; x -= x & (-x))
s += tr[x];
return s;
}
int query1() {
int ans = 0;
for (int i = 1; i <= cnt1; i++) {
ans = ans - lookfor(way[i][0]);
ans = ans + lookfor(way[i][1]);
//cout << way[i][0] << " " << way[i][1] << endl;
}
return ans;
}
signed main() {
cin >> n;
for (int i = 1; i <= n - 1; i++) {
int a, b; cin >> a >> b;
mp[a].push_back(b);
mp[b].push_back(a);
}
dep[0] = 0;
dfs(1, 0);
dfs1(1, 1);
cin >> q;
for (int i = 1; i <= q; i++) {
int od, a, b, c; cin >> od;
if (od == 0) {
cin >> a >> b;
//modify(R[a], b);
//modify(L[a], -b);
}
else {
cin >> c;
for (int j = 1; j <= c; j++) {
cin >> a >> b;
query(a, b);
}
merge();
int ans = 0;
ans = ans + query1();
//for (int i = 1; i <= cnt; i++)
//cout << edge[i].first << " " << edge[i].second << endl;
cout << ans << endl;
}
}
return 0;
}