#include <bits/stdc++.h>
#define int long long
#define pii pair<int,int>
#define FOR(i,a,b) for(int i=(a);i<(b);++i)
#define REP(i,n) FOR(i,0,n)
#define ALL(c) (c).begin(),(c).end()
#define ZERO(a) memset(a,0,sizeof(a))
#define MINUS(a) memset(a,0xff,sizeof(a))
#define MINF(a) memset(a,0x3f,sizeof(a))
#define POW(n) (1LL<<(n))
#define IN(i,a,b) (a <= i && i <= b)
using namespace std;
template <typename T> inline bool CHMIN(T& a,T b) { if(a>b) { a=b; return 1; } return 0; }
template <typename T> inline bool CHMAX(T& a,T b) { if(a<b) { a=b; return 1; } return 0; }
template <typename T> inline void SORT(T& a) { sort(ALL(a)); }
template <typename T> inline void REV(T& a) { reverse(ALL(a)); }
template <typename T> inline void UNI(T& a) { sort(ALL(a)); a.erase(unique(ALL(a)),a.end()); }
template <typename T> inline void LB(vector<T>& v, T& a) { return *lower_bound(ALL(v),a); }
template <typename T> inline void LBP(vector<T>& v, T& a) { return lower_bound(ALL(v),a) - v.begin(); }
template <typename T> inline void UB(vector<T>& v, T& a) { return *upper_bound(ALL(v),a); }
template <typename T> inline void UBP(vector<T>& v, T& a) { return upper_bound(ALL(v),a) - v.begin(); }
template <typename T1, typename T2> ostream& operator<< (ostream& os, const pair<T1,T2>& p) { os << p.first << " " << p.second; return os; }
template <typename T1, typename T2> istream& operator>> (istream& is, pair<T1,T2>& p) { is >> p.first >> p.second; return is; }
template <typename T> ostream& operator<< (ostream& os, const vector<T>& v) { REP(i,v.size()) { if (i) os << " "; os << v[i]; } return os; }
template <typename T> istream& operator>> (istream& is, vector<T>& v) { for(T& in : v) is >> in; return is; }
template <typename T = int> vector<T> make_v(size_t a) { return vector<T>(a); }
template <typename T, typename... Ts> auto make_v(size_t a, Ts... ts) { return vector<decltype(make_v<T>(ts...))>(a,make_v<T>(ts...)); }
template< typename T, typename V > typename enable_if< is_class< T >::value == 0 >::type fill_v(T &t, const V &v) { t = v; }
template< typename T, typename V > typename enable_if< is_class< T >::value != 0 >::type fill_v(T &t, const V &v) { for(auto &e : t) fill_v(e, v); }
const int MOD = 1000000007;
const int INF = 0x3f3f3f3f3f3f3f3f;
const double EPS = 1e-10;

template <typename T>
struct edge {
  int s, t;
  T c;
  edge() {}
  edge(int t, T c) : s(-1), t(t), c(c) {}
  edge(int s, int t, T c) : s(s), t(t), c(c) {}
};

template <typename T> using Edges = vector<edge<T>>;
template <typename T> using WeightedGraph = vector<Edges<T>>;
using UnWeightedGraph = vector<vector<int>>;
template <typename T> using Matrix = vector<vector<T>>;

class HeavyLightDecomposition {
private:
  void dfs_sz(int v) {
    for (int& nv: g[v]) if (nv != par[v]) {
      par[nv] = v;
      dep[nv] = dep[v] + 1;
      dfs_sz(nv);
      sub[v] += sub[nv];
      if (sub[nv] > sub[g[v][0]]) swap(nv, g[v][0]);
    }
  }
  void dfs_hld(int v, int c, int& pos) {
    vid[v] = pos++;
    inv[vid[v]] = v;
    type[v] = c;
    for (int nv : g[v]) if (nv != par[v]) {
      head[nv] = (nv == g[v][0] ? head[v] : nv);
      dfs_hld(nv, c, pos);
    }
  }
public:
  UnWeightedGraph g;
  vector<int> vid, head, sub, par, dep, inv, type;
  HeavyLightDecomposition(UnWeightedGraph& g) :
    g(g), vid(g.size(), -1), head(g.size()), sub(g.size(), 1),
    par(g.size(), -1), dep(g.size(), 0), inv(g.size()), type(g.size()) {}
  
  void build(vector<int> rs = {0}) {
    int c = 0, pos = 0;
    for (int r : rs) {
      dfs_sz(r);
      head[r] = r;
      dfs_hld(r, c++, pos);
    }
  }
  int lca(int u, int v) {
    while (1) {
      if (vid[u] > vid[v]) swap(u, v);
      if (head[u] == head[v]) return u;
      v = par[head[v]];
    }
  }
  int distance(int u, int v) {
    return dep[u] + dep[v] - 2 * dep[lca(u, v)];
  }
  template <typename F>
  void for_each(int u, int v, const F& f) {
    while (1) {
      if (vid[u] > vid[v]) swap(u, v);
      f(max(vid[head[v]], vid[u]), vid[v] + 1);
      if (head[u] != head[v]) v = par[head[v]];
      else break;
    }
  }
  template <typename F>
  void for_each_edge(int u, int v, const F& f) {
    while (1) {
      if (vid[u] > vid[v]) swap(u, v);
      if (head[u] != head[v]) {
        f(vid[head[v]], vid[v] + 1);
        v = par[head[v]];
      } else {
        if (u != v) f(vid[u] + 1, vid[v] + 1);
        break;
      }
    }
  }
};

template <typename M, typename OM = M>
struct LazySegmentTree {
  using F = function<M(M,M)>;
  using G = function<M(M,OM)>;
  using H = function<OM(OM,OM)>;
  using P = function<OM(OM,int)>;
  int n,lev;
  F f;
  G g;
  H h;
  P p;
  M M1;
  OM OM0;
  vector<M> d;
  vector<OM> lz;
  LazySegmentTree() {}
  LazySegmentTree(F f, G g, H h, M M1, OM OM0, P p = [](OM a, int b) { return a; }) : f(f), g(g), h(h), M1(M1), OM0(OM0), p(p) {}
  void init(int n_) {
    for (n = 1, lev = 0; n < n_; n <<= 1, lev++);
    d.assign(n << 1, M1);
    lz.assign(n << 1, OM0);
  }
  void build(const vector<M>& v) {
    int n_ = v.size();
    init(n_);
    for (int i = 0; i < n_; i++) d[n + i] = v[i];
    for (int i = n - 1; i > 0; i--) {
      d[i] = f(d[(i << 1) | 0], d[(i << 1) | 1]);
    }
  }
  inline M reflect(int k, int len) {
    return lz[k] == OM0 ? d[k] : g(d[k], p(lz[k], len));
  }
  inline void eval(int k, int len) {
    if (lz[k] == OM0) return;
    lz[(k << 1) | 0] = h(lz[(k << 1) | 0], lz[k]);
    lz[(k << 1) | 1] = h(lz[(k << 1) | 1], lz[k]);
    d[k] = reflect(k, len);
    lz[k] = OM0;
  }
  inline void thrust(int k) {
    for (int i = lev; i > 0; i--) eval(k >> i, n >> (lev - i));
  }
  inline void recalc(int k) {
    int len = 1;
    while (k >>= 1, len <<= 1) {
      d[k] = f(reflect((k << 1) | 0, len >> 1), reflect((k << 1) | 1, len >> 1));
    }
  }
  void update(int a, int b, OM x) {
    thrust(a += n);
    thrust(b += n - 1);
    for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
      if (l & 1) lz[l] = h(lz[l], x), l++;
      if (r & 1) --r, lz[r] = h(lz[r], x);
    }
    recalc(a);
    recalc(b);
  }
  M query(int a, int b) {
    thrust(a += n);
    thrust(b += n - 1);
    M L = M1, R = M1;
    for (int l = a, r = b + 1, len = 1; l < r; l >>= 1, r >>= 1, len <<= 1) {
      if (l & 1) L = f(L, reflect(l++, len));
      if (r & 1) R = f(reflect(--r, len), R);
    }
    return f(L, R);
  }
  void set(int k, M x) {
    thrust(k += n);
    d[k] = x;
    lz[k] = OM0;
    recalc(k);
  }
  M operator[] (int k) {
    thrust(k += n);
    return d[k];
  }
};

signed main() {
  cin.tie(nullptr);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  int n;
  cin >> n;
  UnWeightedGraph G(n);
  REP(i,n) {
    int k;
    cin >> k;
    REP(j,k) {
      int c;
      cin >> c;
      G[i].push_back(c);
    }
  }

  HeavyLightDecomposition HLD(G);
  HLD.build();

  auto f = [](int a, int b) { return a+b; };
  auto g = [](int a, int b) { return a+b; };
  auto h = [](int a, int b) { return a+b; };
  auto p = [](int a, int b) { return a*b; };
  LazySegmentTree<int> LST(f,g,h,0,0,p);
  LST.build(vector<int>(n,0));

  int q;
  cin >> q;
  REP(i,q) {
    int c;
    cin >> c;
    if (c == 0) {
      int v,w;
      cin >> v >> w;
      HLD.for_each_edge(0,v,[&](int l, int r) { LST.update(l,r,w); });
    } else {
      int u;
      cin >> u;
      int ans = 0;
      HLD.for_each_edge(0,u,[&](int l, int r){ ans += LST.query(l,r); });
      cout << ans << endl;
    }
  }
  
  return 0;
}


Measured memory_bytes: 28420