/*
	18 February 2020
	islingr
*/

#pragma region Boilerplate
#include <bits/stdc++.h>
#include <ext/pb_ds/tree_policy.hpp>
#include <ext/pb_ds/assoc_container.hpp>
using namespace std;
using namespace __gnu_pbds;
 
using ll = long long;
using ld = long double;

using pii = pair<int, int>;
using pll = pair<ll, ll>;

using vi = vector<int>;
using vl = vector<ll>;

#define sz(x) (int)x.size()
#define all(x) begin(x), end(x)
#define rall(x) (x).rbegin(), (x).rend() 
#define rsz resize
#define ins insert 
#define ft front
#define bk back
#define pf push_front 
#define pb push_back
#define eb emplace_back 
#define lb lower_bound 
#define ub upper_bound 
#define fi first
#define se second

#define rep(i, a, b) for (auto i = (a); i < (b); ++i) // [a, b)
#define per(i, a, b) for (auto i = (b) - 1; i >= (a); --i) // (b, a]
#define trav(e, x) for (auto &e : x)

template<class T>
bool ckmin(T& a, const T& b) { 
	return a > b ? a = b, 1 : 0;
}
template<class T>
bool ckmax(T& a, const T& b) { 
	return a < b ? a = b, 1 : 0;
}

mt19937 rng((uint32_t)chrono::steady_clock::now().time_since_epoch().count());

template <class T> using ost = tree<T, null_type, less<T>, 
	rb_tree_tag, tree_order_statistics_node_update>;
#define ook order_of_key
#define fbo find_by_order

namespace helper {
	template<class T, class = decltype(begin(declval<T>()))>
	inline constexpr auto is_iterable(int) { return true_type{}; }

	template<class>
	inline constexpr auto is_iterable(unsigned) { return false_type{}; }
}

namespace input {
	void re(string &s) { cin >> s; }

	template<class T> void re(T& x);
	template<class P, class Q> void re(pair<P, Q>&);
	template<class T, class... Ts> void re(T& t, Ts&... ts);
	
	template<class T> void re(T& x, false_type) { cin >> x; }
	template<class T> void re(T& x, true_type) {
		for (auto &v : x) re(v);
	}
	template<class T> void re(T& x) {
		re(x, helper::is_iterable<T>(0));
	} 
	template<class P, class Q>
	void re(pair<P, Q> &p) {
		re(p.first, p.second);
	}
	template<class T, class... Ts> void re(T& t, Ts&... ts) {
		re(t);
		re(ts...);
	}
}

namespace output {
	template <typename T> void pr(const T&);
	template<class T, class... Ts> void pr(const T&, const Ts&...);

	template<class S, class T>
	void pr(const pair<S, T> &p) {
		pr("(", p.first, ",", p.second, ")");
	}

	template<class T>
	void pr(queue<T> q) {
		pr("{"); bool c = false;
		while (!q.empty())
			pr(c ? ", " : "", q.front()),
			q.pop(),
			c = true;
		pr("}");
	}
	template<class T>
	void pr(priority_queue<T> q) {
		pr("{"); bool c = false;
		while (!q.empty())
			pr(c ? ", " : "", q.top()),
			q.pop(),
			c = true;
		pr("}");
	}
	template<class T>
	void pr(stack<T> s) {
		pr("{"); bool c = false;
		while (!s.empty())
			pr(c ? ", " : "", s.top()),
			s.pop(),
			c = true;
		pr("}");
	}
	void pr(const string &s) { cout << s; }

	template<typename T>
	void pr(const T& x, false_type) { cout << x; }

	template<typename T>
	void pr(const T& x, true_type) {
		pr("{"); bool f = false;
		for (const auto &v : x)
			pr(f ? ", " : "", v),
			f = true;
		pr("}");
	}

	template <typename T>
	void pr(const T& x) {
		pr(x, helper::is_iterable<T>(0));
	}
	
	template<class T, class... Ts>
	void pr(const T& t, const Ts&... ts) { pr(t); pr(ts...); }
	
	void pc() { pr("]\n"); } // debug w/ commas

	template<class T, class... Ts>
	void pc(const T& t, const Ts&... ts) { 
		pr(t);
		if (sizeof...(ts)) pr(", ");
		pc(ts...); 
	}

	#define dbg(x...) pr("[", #x, "] = ["), pc(x);
}

struct IO {
	IO(bool b) {
		if (b) fastio();
		cout << fixed << setprecision(numeric_limits<ld>::digits10);
	}
	IO(bool b, string s) : IO(b) {
		setIn(s + ".in");
		setOut(s + ".out");
	}
	void fastio() {
		ios_base::sync_with_stdio(false);
		cin.tie(nullptr);
	}
	void setIn(string s) { freopen(s.c_str(), "r", stdin); }
	void setOut(string s) { freopen(s.c_str(), "w", stdout); }
};
#pragma endregion 

using namespace input;
using namespace output;
IO io = IO(true);

template<typename T, typename U> struct seg_tree_lazy {
	int S, H;
	
	T zero;
	vector<T> value;
	
	U noop;
	vector<bool> dirty;
	vector<U> prop;
	
	seg_tree_lazy<T, U>(int _S, T _zero = T(), U _noop = U()) : S{_S},
	noop{_noop}, zero{_zero}, H{int(8 * sizeof(int) - __builtin_popcount(_S))} {
		value.resize(2 * S, zero);
		dirty.resize(2 * S, false);
		prop.resize(S, noop);
	}
	
	void set_leaves(const vector<T> &leaves) {
		copy(leaves.begin(), leaves.end(), value.begin() + S);
		
		for (int i = S - 1; i > 0; i--)
			value[i] = value[2 * i] + value[2 * i + 1];
	}
	
	void apply(int i, U& update) {
		value[i] = update(value[i]);
		if (i < S) {
			prop[i] = prop[i] + update;
			dirty[i] = true;
		}
	}
	
	void rebuild(int i) {
		for (int l = i >> 1; l; l >>= 1) {
			T combined = value[l << 1|0] + value[l << 1|1];
			value[l] = prop[l](combined);
		}
	}
	
	void propagate(int i) {
		for (int h = H; h > 0; h--) {
			int l = i >> h;
			
			if (dirty[l]) {
				apply(l << 1|0, prop[l]);
				apply(l << 1|1, prop[l]);
				
				prop[l] = noop;
				dirty[l] = false;
			}
		}
	}
	
	void upd(int i, int j, U update) {
		i += S, j += S;
		propagate(i), propagate(j);
		
		for (int l = i, r = j; l <= r; l /= 2, r /= 2) {
			if ((l & 1) == 1) apply(l++, update);
			if ((r & 1) == 0) apply(r--, update);
		}
		rebuild(i), rebuild(j);
	}
	
	T query(int i, int j) {
		i += S, j += S;
		propagate(i), propagate(j);
		T res_left = zero, res_right = zero;
		for(; i <= j; i >>= 1, j >>= 1) {
			if ((i & 1) == 1) res_left = res_left + value[i++];
			if ((j & 1) == 0) res_right = value[j--] + res_right;
		}
		return res_left + res_right;
	}
};

struct snode {
	ll s;
	int w;
	snode(ll a = 0, int b = 0) : s{a}, w{b} { }
	snode operator+(const snode &n) {
		return snode(s + n.s, w + n.w);
	}
};

struct supdate {
	ll v;
	supdate(ll a = 0) : v{a} { }
	snode operator()(const snode &n) {
		return snode(n.s + n.w * v, n.w);
	}
	supdate operator+(const supdate &u) {
		return supdate(v + u.v);
	}
};

int n;
vector<vi> g;
vi nxt, sz, in, p;
int t = 0;

void dfs_sz(int u) {
	sz[u] = 1;
	trav(v, g[u]) {
		dfs_sz(v);
		sz[u] += sz[v];
		if (sz[v] > sz[g[u][0]])
			swap(v, g[u][0]);
	}
}

void dfs_hld(int u) {
	in[u] = t++;
	trav(v, g[u]) {
		nxt[v] = v == g[u][0] ? nxt[u] : v;
		dfs_hld(v);
	}
}

signed main() {
	int n; re(n);
	g.rsz(n); nxt.rsz(n); sz.rsz(n); in.rsz(n); p.rsz(n);
	rep(u, 0, n) {
		int k; re(k);
		g[u].rsz(k);
		trav(v, g[u]) {
			re(v);
			p[v] = u;
		}
	}
	dfs_sz(0); dfs_hld(0);

	seg_tree_lazy<snode, supdate> S(n);
	S.set_leaves(vector<snode>(n, {0, 1}));

	int q; re(q);
	while (q--) {
		int t; re(t);
		if (t) {
			int u; re(u); ll ans = 0;
			while (u != 0) {
				ans += S.query(max(1, in[nxt[u]]), in[u]).s;
				u = p[nxt[u]];
			}
			pr(ans, '\n');
		} else {
			int u; ll w; re(u, w);
			while (u != 0) {
				S.upd(max(1, in[nxt[u]]), in[u], {w});
				u = p[nxt[u]];
			}
		}
	}
}


Measured memory_bytes: 19996