#include<iostream>
#include<vector>
#include<tuple>
#include<vector>
#include<cmath>
#include<vector>
#include<cassert>
namespace ProconLib {

	template<class graph_t>
	class LCA {
	private:
		static int safeLog2(int N) { return std::ceil(std::log2(N + 1)) + 1; }
		void dfs(int v, int pre, const graph_t& g);

	protected:
		int N;
		int logN;
		std::vector<std::vector<int>> par;
		std::vector<int> dep;

	public:
		LCA(std::vector<int> root, const graph_t &g);
		LCA(int root, const graph_t &g) :LCA(std::vector<int>(1, root), g) {};
		int query(int a, int b);
		int depth(int v) { return dep[v]; }
	};

	template<class graph_t>
	void LCA<graph_t>::dfs(int v, int pre, const graph_t& g) {
		par[0][v] = pre;
		for (auto e : g[v]) {
			if (e.to == pre) continue;
			par[0][e.to] = v;
			dep[e.to] = dep[v] + 1;
			dfs(e.to, v, g);
		}
	}

	template<class graph_t>
	LCA<graph_t>::LCA(std::vector<int> roots, const graph_t &g) : N(g.size()),
		logN(safeLog2(N)),
		par(logN, std::vector<int>(N)),
		dep(N)
	{
		for (auto root : roots) {
			par[0][root] = root;
			dep[root] = 0;
			dfs(root, root, g);
		}
		for (int i = 0; i + 1<logN; i++) {
			for (int j = 0; j<N; j++) {
				par[i + 1][j] = par[i][par[i][j]];
			}
		}
	}


	template<class graph_t>
	int LCA<graph_t>::query(int a, int b) {
		if (dep[a]<dep[b]) std::swap(a, b);
		int u = dep[a] - dep[b];
		for (int i = logN - 1; i >= 0; i--) {
			if ((u >> i) & 1) a = par[i][a];
		}
		assert(dep[a] == dep[b]);
		if (a == b) return a;
		for (int i = logN - 1; i >= 0; i--) {
			if (par[i][a] != par[i][b]) {
				a = par[i][a];
				b = par[i][b];
			}
		}
		assert(a != b);
		a = par[0][a], b = par[0][b];
		if (a != b) return -1; // if (g is a forest) and (a and b is disconnected).
		return a;
	}

}
namespace ProconLib {

	template<class MUStruct>
	class LazySegmentTree {
	public:
		using Monoid = typename MUStruct::Monoid;
		using Update = typename MUStruct::Update;
		using value_t = typename Monoid::value_t;
		using update_t = typename Update::update_t;

	protected:

		int N;
		std::vector<value_t> dat;
		std::vector<update_t> lazy;
		std::vector<char> flag;

		static int calcN(int n) { int res = 1; while (res<n) res *= 2; return res; };
		void propagate(int node);
		void applyLazy(int node, update_t x);
		void applyImpl(int l, int r, int k, int lb, int ub, update_t f);
		void updateImpl(int pos, int k, int lb, int ub, value_t x);
		value_t queryImpl(int l, int r, int k, int lb, int ub);
		value_t getValue(int node) { return flag[node] ? MUStruct::evaluate(dat[node], lazy[node]) : dat[node]; }

	public:
		LazySegmentTree(int N);
		void apply(int l, int r, update_t f);
		void updateALL(std::vector<value_t> x);
		void update(int pos, value_t v);
		value_t query(int a, int b);
	};

	// struct MUStructExample{
	//     struct Monoid{
	//         using value_t=int;
	//         static constexpr value_t E(){return 1e9;}
	//         static value_t op(value_t lhs,value_t rhs){ return min(lhs,rhs);}
	//     };
	//     struct Update{
	//         using update_t = int;
	//         static update_t op(update_t lhs,update_t rhs){ return lhs+rhs;}
	//     };
	//     static Monoid::value_t evaluate(Monoid::value_t v,Update::update_t u){ return v+u;}
	// };

	template<class MUStruct>
	LazySegmentTree<MUStruct>::LazySegmentTree(int n) :N(calcN(n)), dat(N * 2 - 1, Monoid::E()), lazy(N * 2 - 1), flag(N * 2 - 1, false) {}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::propagate(int node) {
		if (flag[node]) {
			flag[node] = false;
			applyLazy(node * 2 + 1, lazy[node]);
			applyLazy(node * 2 + 2, lazy[node]);
			dat[node] = Monoid::op(getValue(node * 2 + 1), getValue(node * 2 + 2));
		}
	}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::applyLazy(int node, update_t x) {
		if (flag[node]) {
			lazy[node] = Update::op(lazy[node], x);
		}
		else {
			flag[node] = true;
			lazy[node] = x;
		}
	}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::applyImpl(int l, int r, int k, int lb, int ub, update_t x) {
		if (r <= lb || ub <= l) return;
		if (l <= lb && ub <= r) {
			applyLazy(k, x);
			return;
		}
		propagate(k);
		int mid = (lb + ub) / 2;
		applyImpl(l, r, k * 2 + 1, lb, mid, x);
		applyImpl(l, r, k * 2 + 2, mid, ub, x);
		dat[k] = Monoid::op(getValue(k * 2 + 1), getValue(k * 2 + 2));
	}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::updateImpl(int pos, int k, int lb, int ub, value_t x) {
		if (!(lb <= pos && pos<ub))return;
		if (pos == lb && pos == ub - 1) {
			flag[k] = false;
			dat[k] = x;
			return;
		}
		propagate(k);
		int mid = (lb + ub) / 2;
		updateImpl(pos, k * 2 + 1, lb, mid, x);
		updateImpl(pos, k * 2 + 2, mid, ub, x);
		dat[k] = Monoid::op(getValue(k * 2 + 1), getValue(k * 2 + 2));
	}

	template<class MUStruct>
	typename LazySegmentTree<MUStruct>::value_t LazySegmentTree<MUStruct>::queryImpl(int l, int r, int k, int lb, int ub) {
		if (r <= lb || ub <= l) return Monoid::E();
		if (l <= lb && ub <= r) {
			return getValue(k);
		}
		propagate(k);
		int mid = (lb + ub) / 2;
		value_t lhs = queryImpl(l, r, k * 2 + 1, lb, mid);
		value_t rhs = queryImpl(l, r, k * 2 + 2, mid, ub);
		return Monoid::op(lhs, rhs);
	}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::apply(int l, int r, update_t x) {
		applyImpl(l, r, 0, 0, N, x);
	}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::update(int pos, value_t x) {
		updateImpl(pos, 0, 0, N, x);
	}

	template<class MUStruct>
	void LazySegmentTree<MUStruct>::updateALL(std::vector<value_t> xs) {
		for (int i = 0; i<xs.size(); i++) {
			dat[i + N - 1] = xs[i];
		}
		for (int i = xs.size(); i<N; i++) dat[i + N - 1] = Monoid::E(), flag[i + N - 1] = false;
		for (int i = N - 2; i >= 0; i--) {
			flag[i] = false;
			value_t c1v = dat[i * 2 + 1], c2v = dat[i * 2 + 2];
			dat[i] = Monoid::op(c1v, c2v);
		}
	}

	template<class MUStruct>
	typename LazySegmentTree<MUStruct>::value_t LazySegmentTree<MUStruct>::query(int l, int r) {
		return queryImpl(l, r, 0, 0, N);
	}
};


namespace ProconLib {

	template<class graph_t>
	class HeavyLightDecomposition {
		int N;
		int K = 0;
		std::vector<int> hId;
		std::vector<int> subId;
		std::vector<int> sz;
		std::vector<int> hPar;
		std::vector<int> hSz;
		int dfsSZ(int v, int pre, const graph_t& g);
		int dfsHL(int v, int pre, const graph_t& g);
	public:
		void build(int root, const graph_t& g);
		HeavyLightDecomposition(std::vector<int> roots, const graph_t& g) :N(g.size()), hId(N, -1), subId(N, -1), sz(N, -1), hPar(1, 0), hSz(N) { for (auto root : roots) build(root, g); }
		HeavyLightDecomposition(int root, const graph_t& g) :HeavyLightDecomposition(std::vector<int>(1, root), g) {}

		int size() { return K; }
		int size(int h) { return hSz[h]; }
		int getHId(int v) { return hId[v]; }
		int getSubId(int v) { return subId[v]; }
		int getHPar(int v) { return hPar[v]; }
	};


	template<class graph_t>
	int HeavyLightDecomposition<graph_t>::dfsSZ(int v, int pre, const graph_t& g) {
		sz[v] = 1;
		for (auto& e : g[v]) {
			if (e.to == pre) continue;
			sz[v] += dfsSZ(e.to, v, g);
		}
		return sz[v];
	}

	template<class graph_t>
	int HeavyLightDecomposition<graph_t>::dfsHL(int v, int pre, const graph_t& g) {
		int maxC = -1;
		int maxSZ = -1;
		for (auto &e : g[v]) {
			if (e.to == pre) continue;
			if (maxSZ<sz[e.to]) {
				maxC = e.to;
				maxSZ = sz[e.to];
			}
		}
		if (maxC == -1) subId[v] = 0;
		else {
			for (auto &e : g[v]) {
				if (e.to == pre) continue;
				if (e.to == maxC) {
					hId[e.to] = hId[v];
					subId[v] = dfsHL(e.to, v, g) + 1;
				}
				else {
					hId[e.to] = K++;
					hPar.push_back(v);
					assert(hPar.size() == K);
					dfsHL(e.to, v, g);
				}
			}
		}
		hSz[hId[v]] = subId[v] + 1;
		return subId[v];
	}

	template<class graph_t>
	void HeavyLightDecomposition<graph_t>::build(int root, const graph_t& g) {
		dfsSZ(root, -1, g);
		hId[root] = K++;
		dfsHL(root, -1, g);
	}


	struct HLDQManagerInterface {
		struct Monoid;
		struct DataStructure;
		struct Update {
			using update_t = long long;
			static void VertexUpdate(DataStructure& ds, int pos, update_t x);
			static void RangeUpdate(DataStructure& ds, int l, int r, update_t x);
		};
		struct Query {
			static void VertexQuery(DataStructure& ds, int pos);
			static void RangeUpdate(DataStructure& ds, int l, int r);
		};
	};

	template<class graph_t, class HLDQManager>
	class HLDecompositionQuery {
		using HLD = HeavyLightDecomposition<graph_t>;
		using DS = typename HLDQManager::DataStructure;

		using Monoid = typename HLDQManager::Monoid;
		using value_t = typename Monoid::value_t;

		using Update = typename HLDQManager::Update;
		using Query = typename HLDQManager::Query;
		using update_t = typename Update::update_t;

		HLD hld;
		LCA<graph_t> _lca;
		std::vector<DS> dsv;

		struct UStruct {
			value_t x;
			UStruct(value_t x) :x(x) {}
			void doForVertex(int hid, int v, std::vector<DS>& dsv) { Update::VertexUpdate(dsv[hid], v, x); }
			void doForRange(int hid, int l, int r, std::vector<DS>& dsv) { Update::RangeUpdate(dsv[hid], l, r, x); }
		};
		struct QStruct {
			value_t res = Monoid::E();
			void doForVertex(int hid, int id, std::vector<DS>& dsv) { res = Monoid::op(res, Query::VertexQuery(dsv[hid], id)); }
			void doForRange(int hid, int l, int r, std::vector<DS>& dsv) { res = Monoid::op(res, Query::RangeQuery(dsv[hid], l, r)); }
		};

		template<typename Struct>
		void pathImpl(int u, int v, Struct& st) {
			int w = lca(u, v);
			// [u,w)
			while (u != w) {
				int to = hld.getHPar(hld.getHId(u));
				if (depth(to)<depth(w)) to = w;
				int l = hld.getSubId(u);
				int r = (hld.getHId(u) != hld.getHId(to) ? hld.size(hld.getHId(u)) : hld.getSubId(to));
				st.doForRange(hld.getHId(u), l, r, dsv);
				u = to;
			}
			// [w,w]
			st.doForVertex(hld.getHId(w), hld.getSubId(w), dsv);
			// (w,v]
			using T3 = std::tuple<int, int, int>;
			std::vector<T3> rs;
			while (v != w) {
				int to = hld.getHPar(hld.getHId(v));
				if (depth(to)<depth(w)) to = w;
				int l = hld.getSubId(v);
				int r = (hld.getHId(v) != hld.getHId(to) ? hld.size(hld.getHId(v)) : hld.getSubId(to));
				rs.push_back(T3(hld.getHId(v), r, l));
				v = to;
			}
			for (int i = (int)(rs.size()) - 1; i >= 0; i--) st.doForRange(std::get<0>(rs[i]), std::get<1>(rs[i]), std::get<2>(rs[i]), dsv);
			return;
		}
	public:

		HLDecompositionQuery(std::vector<int> roots, const graph_t& g) :hld(roots, g), _lca(roots, g) {
			for (int i = 0; i<hld.size(); i++) dsv.emplace_back(hld.size(i));
		}
		HLDecompositionQuery(int root, const graph_t& g) :HLDecompositionQuery(std::vector<int>(1, root), g) {};

		void pathUpdate(int u, int v, value_t x) {
			UStruct st(x);
			pathImpl(u, v, st);
		}
		value_t pathQuery(int u, int v) {
			QStruct st;
			pathImpl(u, v, st);
			return st.res;
		}
		int lca(int u, int v) {
			return _lca.query(u, v);
		}
		int depth(int v) { return _lca.depth(v); }

		template<typename T>
		void SingleUpdate(int v,T x){
			Update::SingleUpdate(dsv[hld.getHId(v)],hld.getSubId(v),x);
		}
	};
}

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

struct Edge {
	int to;
};
using Graph = vector<vector<Edge>>;

struct MUStruct {
	struct Monoid {
		using value_t = pair<int, long long>;
		static constexpr value_t E() { return make_pair(0, 0LL); }
		static value_t op(value_t lhs, value_t rhs) { return make_pair(lhs.first + rhs.first, lhs.second + rhs.second); };
	};
	struct Update {
		using update_t = long long;
		static update_t op(update_t lhs, update_t rhs) { return lhs + rhs; }
	};
	static Monoid::value_t evaluate(Monoid::value_t v, Update::update_t u) { return make_pair(v.first, v.second + v.first*u); }
};



using LS = LazySegmentTree<MUStruct>;

struct HLDQManager {
	struct Monoid {
		using value_t = long long;
		static constexpr value_t E() { return 0; }
		static value_t op(value_t lhs, value_t rhs) { return lhs + rhs; }
	};
	using DataStructure = LS;
	struct Update {
		using update_t = long long;
		static void VertexUpdate(DataStructure& ds, int pos, update_t x) {};
		static void SingleUpdate(DataStructure& ds, int pos, pair<int,long long> p) {ds.update(pos,p);};
		static void RangeUpdate(DataStructure& ds, int l, int r, update_t x) { ds.apply(l, r, x); };
	};
	struct Query {
		static Monoid::value_t VertexQuery(DataStructure& ds, int pos) { return 0LL; };
		static Monoid::value_t RangeQuery(DataStructure& ds, int l, int r) {
            auto ret = ds.query(l, r).second;
            return ret;
        }
	};
};

int main() {
	int n;
	cin >> n;
	Graph g(n);
	vector<int> par(n);
	for (int i = 0; i<n; i++) {
		int k; cin >> k;
		while (k--) {
			int c; cin >> c;
			par[c]=i;
			g[i].push_back(Edge{ c });
			g[c].push_back(Edge{ i });
		}
	}

	HLDecompositionQuery<Graph, HLDQManager> hldQ(0, g);
    for(int i=1;i<n;i++) hldQ.SingleUpdate(i,make_pair(1,0LL));
	int q;
	cin >> q;
	while (q--) {
		int type; cin >> type;
		if (type == 0) {
			int v, x;
			cin >> v >> x;
			hldQ.pathUpdate(v, 0, x);
		}
		else {
			int v;
			cin >> v;
			cout << hldQ.pathQuery(v, 0) << endl;
		}

	}
	return 0;
}


Measured memory_bytes: 36824