#include <bits/stdc++.h>

#define LOCAL
using std::to_string;
auto to_string(std::string s) -> std::string {
  return '"' + s + '"';
}
auto to_string(char c) -> std::string {
  return "'" + std::string{c} + "'";
}
auto to_string(const char* s) -> std::string {
  return to_string((std::string) s);
}
auto to_string(bool b) -> std::string {
  return (b ? "true" : "false");
}
template <typename T, typename U>
auto to_string(std::pair<T, U> p) -> std::string {
  return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}
template <size_t N>
auto to_string(std::bitset<N> bs) -> std::string {
  std::string res{};
  for (size_t i = 0; i < N; i++)
    res.insert(res.begin(), bs.test(i) ? '1' : '0');
  return res;
}
template <typename T>
auto to_string(T v) -> std::string {
  bool flg = false;
  std::string res = "{";
  for (auto const&x : v) {
    if (flg) res += ", ";
    else flg = true;
    res += to_string(x);
  }
  res += "}";
  return res;
}
void debug_out() { std::cerr << std::endl; }
template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
  std::cerr << " " << to_string(H);
  debug_out(T...);
}
#ifdef LOCAL
#define debug(...) std::cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
#else
#define debug(...) 42
#endif

class heavy_light_decomposition
{
  public:
    using size_type  = int;
    using index_type = int;
    using id_type    = int;
    using graph_type = std::vector<std::vector<index_type>>;
    using tablele_type = std::vector<int>;

  private:
    size_type  n;
    graph_type graph;
    tablele_type prt, sz, depth, vid, ord, head;

    // Helper
    void first_dfs(index_type x)
    {
      for (auto& y : graph.at(x))
      {
        if (y == prt.at(x)) continue;
        prt.at(y)   = x;
        depth.at(y) = depth.at(x) + 1;

        first_dfs(y);

        sz.at(x) += sz.at(y);
        auto& h = graph.at(x).front();
        if (sz.at(h) < sz.at(y))
        {
          std::swap(h, y);
        }
      }
    }

    // Helper
    void second_dfs(index_type x, id_type& counter)
    {
      ord.at(vid.at(x) = counter++) = x;
      for (auto y : graph.at(x))
      {
        if (y == prt.at(x)) continue;
        head.at(y) = y == graph.at(x).front()
          ? head.at(x)
          : y;
         second_dfs(y, counter);
      }
    }

  public:
    heavy_light_decomposition()=default;
    heavy_light_decomposition(const heavy_light_decomposition&)=default;
    heavy_light_decomposition(heavy_light_decomposition&&)=default;
    heavy_light_decomposition& operator=(const heavy_light_decomposition&)=default;
    heavy_light_decomposition& operator=(heavy_light_decomposition&&)=default;

    heavy_light_decomposition(int n) :
      n     (n),
      graph (n),
      prt   (n),
      sz    (n, 1),
      depth (n, 0),
      vid   (n),
      ord   (n),
      head  (n)
      {}

    // Accessers.
    auto id(index_type x) const {return vid.at(x);}

    void build (index_type root = 0)
    {
      id_type counter = 0;
      first_dfs(root);
      second_dfs(root, counter);
    }

    void insert (index_type x, index_type y)
    {
      graph.at(x).push_back(y);
      graph.at(y).push_back(x);
    }

    template <typename RangeOp>
    void for_each
    (
      index_type     x,
      index_type     y,
      RangeOp const& op,   // range-operation f([vid(x), vid(y)[)
      bool           skip  // skip the top vertex
    )
    {
      while (true)
      {
        if (id(x) > id(y)) std::swap(x, y);
        if (head.at(x) == head.at(y))
        {
          op(id(x) + skip, id(y) + 1);
          break;
        }
        op(id(head.at(y)), id(y) + 1);
        y = prt.at(head.at(y));
      }
    }
};

template<
  typename Value1,    typename Value2,
  typename BinaryOp1, typename BinaryOp2, typename BinaryOp3,
  typename UnaryOp1,  typename UnaryOp2
  >
class lazy_segment_tree
{
  public:
    using size_type = int;

  private:
    struct node
    {
      size_type id, l, r;
      node (size_type id, size_type l, size_type r):
        id(id), l(l), r(r)
        {};

      auto size () const {return r - l;}

      auto left_child  () const
      {
        assert(size() > 1);
        return node(id * 2, l, (l + r) / 2);
      }

      auto right_child () const
      {
        assert(size() > 1);
        return node(id * 2 + 1, (l + r) / 2, r);
      }
    };

    size_type           n, N;
    BinaryOp1           op1;
    BinaryOp2           op2;
    BinaryOp3           op3;
    Value1              id1;
    Value2              id2;
    UnaryOp1            expand;
    UnaryOp2            shrink;
    std::vector<Value1> table;
    std::vector<Value2> lazy;
    node                initial_node;

    auto& op1_eq (Value1& x, Value1 y) {return x = op1(x, y);}
    auto& op2_eq (Value1& x, Value2 y) {return x = op2(x, y);}
    auto& op3_eq (Value2& x, Value2 y) {return x = op3(x, y);}

    void cal (size_type u)
    {
      table.at(u) = op1(table.at(2 * u), table.at(2 * u + 1));
    }

    auto prop (size_type u)
    {
      op2_eq(table.at(u), lazy.at(u));
      if (u < n)
      {
        op3_eq(lazy.at(2 * u),     shrink(lazy.at(u)));
        op3_eq(lazy.at(2 * u + 1), shrink(lazy.at(u)));
      }
      lazy.at(u)     = id2;
      return table.at(u);
    }

    auto query_base (size_type l, size_type r, Value2 val, const node& now)
    {
      prop(now.id);
      if (now.r <= l || r <= now.l) return id1;
      else if (l <= now.l && now.r <= r)
      {
        op3_eq(lazy.at(now.id), val);
        return prop(now.id);
      }
      else
      {
        auto ret =op1(
          query_base(l, r, shrink(val), now.left_child()),
          query_base(l, r, shrink(val), now.right_child())
        );
        cal(now.id);
        return ret;
      }
    }

  public:
    lazy_segment_tree
    (
      size_type size,
      BinaryOp1  op1,
      BinaryOp2  op2,
      BinaryOp3  op3,
      Value1     id1,
      Value2     id2,
      UnaryOp1   expand,
      UnaryOp2   shrink
    ):
      n (std::pow(2, int(std::log2(size)) + 1)), N(n * 2),
      op1(std::move(op1)), op2(std::move(op2)), op3(std::move(op3)),
      id1(id1), id2(id2),
      expand(std::move(expand)), shrink(std::move(shrink)),
      table(N, id1), lazy(N, id2),
      initial_node(1, 0, n)
      {
        std::mt19937 mt(std::random_device{}());
        std::uniform_int_distribution<int> dist(-1'000'000, 1'000'000);
        for (int i = 0; i < 20; i++) {
          Value1 ex1 = dist(mt), ex1_ = dist(mt);
          Value2 ex2 = dist(mt);
          assert(op1(ex1, id1)       == ex1);
          assert(op2(ex1, id2)       == ex1);
          assert(op3(ex2, id2)       == ex2);
          assert(shrink(expand(ex2)) == ex2);
          assert(op2(op1(ex1, ex1_), expand(ex2)) == op1(op2(ex1, ex2), op2(ex1_, ex2)));
        }
      }

    void build (const std::vector<Value1>& v)
    {
      assert(int(v.size()) <= n);
      std::move(v.begin(), v.end(), table.begin() + n);
      for (int i = n - 1; i >= 0; i--) cal(i);
    }

    auto at (size_type i) const -> Value1
    {
      return table.at(n + i);
    }

    void act (size_type l, size_type r, Value2 val)
    {
      for (int i = 1; i < n; i *= 2) {
        val = expand(val);
      }
      query_base(l, r, val, initial_node);
    }

    auto query (size_type l, size_type r)
    {
      return query_base(l, r, id2, initial_node);
    }
};

template<
  typename Value1,    typename Value2,
  typename BinaryOp1, typename BinaryOp2, typename BinaryOp3,
  typename UnaryOp1,  typename UnaryOp2
  >
auto make_lazy_segment_tree
(
  int        size,
  BinaryOp1  op1,
  BinaryOp2  op2,
  BinaryOp3  op3,
  Value1     id1,
  Value2     id2,
  UnaryOp1   expand,
  UnaryOp2   shrink
)
{
  return lazy_segment_tree<
    Value1,    Value2,
    BinaryOp1, BinaryOp2, BinaryOp3,
    UnaryOp1,  UnaryOp2
    >
    (
      size, std::move(op1), std::move(op2), std::move(op3),
      id1, id2, std::move(expand), std::move(shrink)
    );
}


template<
  typename Value1,    typename Value2,
  typename BinaryOp1, typename BinaryOp2, typename BinaryOp3
  >
auto make_lazy_segment_tree
(
  int        size,
  BinaryOp1  op1,
  BinaryOp2  op2,
  BinaryOp3  op3,
  Value1     id1,
  Value2     id2
)
{
  auto f = [](auto x){return x;};
  return make_lazy_segment_tree
    (
      size, std::move(op1), std::move(op2), std::move(op3),
      id1, id2, std::move(f), std::move(f)
    );
}

int main() {
  std::cin.tie(0); std::cin.sync_with_stdio(false);
  int n; std::cin >> n;
  auto hld = heavy_light_decomposition(n);
  for (int i = 0; i < n; i++) {
    int k; std::cin >> k;
    while (k--)
    {
      int j; std::cin >> j;
      hld.insert(i, j);
    }
  }
  hld.build();
  auto sum_tree = make_lazy_segment_tree<long long>
  (
    n,
    [](auto x, auto y){return x + y;},
    [](auto x, auto y){return x + y;},
    [](auto x, auto y){return x + y;},
    0,
    0,
    [](auto x){return x * 2;},
    [](auto x){return x / 2;}
  );
  int root = 0;
  int q; std::cin >> q;
  while (q--)
  {
    int c; std::cin >> c;
    if (c == 0)
    {
      int v, w; std::cin >> v >> w;
      hld.for_each(root, v, [&](auto l, auto r){
        sum_tree.act(l, r, w);
      }, true);
    }
    else
    {
      int u; std::cin >> u;
      long long ret = 0;
      hld.for_each(root, u, [&](auto l, auto r){
        ret += sum_tree.query(l, r);
      }, true);
      std::cout << ret << std::endl;
    }
  }
  return 0;
}


Measured memory_bytes: 19764