macro_rules ! input { ( source = $ s : expr , $ ( $ r : tt ) * ) => { let mut iter = $ s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; ( iter = $ iter : ident , $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut $ iter = s . split_whitespace ( ) ; input_inner ! { $ iter , $ ( $ r ) * } } ; ( $ ( $ r : tt ) * ) => { let s = { use std :: io :: Read ; let mut s = String :: new ( ) ; std :: io :: stdin ( ) . read_to_string ( & mut s ) . unwrap ( ) ; s } ; let mut iter = s . split_whitespace ( ) ; input_inner ! { iter , $ ( $ r ) * } } ; }
macro_rules ! input_inner { ( $ iter : expr ) => { } ; ( $ iter : expr , ) => { } ; ( $ iter : expr , mut $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let mut $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , mut $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , mut $ var : usize $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident : $ t : tt $ ( $ r : tt ) * ) => { let $ var = read_value ! ( $ iter , $ t ) ; input_inner ! { $ iter $ ( $ r ) * } } ; ( $ iter : expr , $ var : ident $ ( $ r : tt ) * ) => { input_inner ! { $ iter , $ var : usize $ ( $ r ) * } } ; }
macro_rules ! read_value { ( $ iter : expr , ( $ ( $ t : tt ) ,* ) ) => { ( $ ( read_value ! ( $ iter , $ t ) ) ,* ) } ; ( $ iter : expr , [ $ t : tt ; $ len : expr ] ) => { ( 0 ..$ len ) . map ( | _ | read_value ! ( $ iter , $ t ) ) . collect ::< Vec < _ >> ( ) } ; ( $ iter : expr , { chars : $ base : expr } ) => { read_value ! ( $ iter , String ) . chars ( ) . map ( | c | ( c as u8 - $ base as u8 ) as usize ) . collect ::< Vec < usize >> ( ) } ; ( $ iter : expr , { char : $ base : expr } ) => { read_value ! ( $ iter , { chars : $ base } ) [ 0 ] } ; ( $ iter : expr , chars ) => { read_value ! ( $ iter , String ) . chars ( ) . collect ::< Vec < char >> ( ) } ; ( $ iter : expr , char ) => { read_value ! ( $ iter , chars ) [ 0 ] } ; ( $ iter : expr , usize1 ) => { read_value ! ( $ iter , usize ) - 1 } ; ( $ iter : expr , $ t : ty ) => { $ iter . next ( ) . unwrap ( ) . parse ::<$ t > ( ) . unwrap ( ) } ; }
pub trait Monoid {
    type T: Clone + PartialEq;
    fn mempty(&self) -> Self::T;
    fn mappend(&self, x: &Self::T, y: &Self::T) -> Self::T;
}
pub trait Group: Monoid {
    fn invert(&self, x: &Self::T) -> Self::T;
}
#[derive(Clone, Debug)]
pub struct BinaryIndexedTree<M: Monoid> {
    bit: Vec<M::T>,
    monoid: M,
}
impl<M: Monoid> BinaryIndexedTree<M> {
    #[inline]
    pub fn new(n: usize, monoid: M) -> BinaryIndexedTree<M> {
        let bit = vec![monoid.mempty(); n + 1];
        BinaryIndexedTree {
            bit: bit,
            monoid: monoid,
        }
    }
    #[inline]
    pub fn ident(&self) -> M::T {
        self.monoid.mempty()
    }
    #[inline]
    pub fn operate(&self, x: &M::T, y: &M::T) -> M::T {
        self.monoid.mappend(x, y)
    }
    #[inline]
    #[doc = " 0-indexed [1, k)"]
    pub fn query(&self, k: usize) -> M::T {
        let mut res = self.ident();
        let mut k = k;
        while k > 0 {
            res = self.operate(&res, &self.bit[k]);
            k -= k & !k + 1;
        }
        res
    }
    #[inline]
    #[doc = " 1-indexed"]
    pub fn update(&mut self, k: usize, x: M::T) {
        assert!(k > 0);
        let mut k = k;
        while k < self.bit.len() {
            self.bit[k] = self.operate(&self.bit[k], &x);
            k += k & !k + 1;
        }
    }
}
impl<G: Group> BinaryIndexedTree<G> {
    #[inline]
    pub fn invert(&self, x: &G::T) -> G::T {
        self.monoid.invert(x)
    }
    #[inline]
    #[doc = " 0-indexed [l, r)"]
    pub fn query_section(&self, l: usize, r: usize) -> G::T {
        self.operate(&self.invert(&self.query(l)), &self.query(r))
    }
    #[inline]
    #[doc = " 1-indexed"]
    pub fn get_val(&self, k: usize) -> G::T {
        self.query_section(k - 1, k)
    }
    #[inline]
    #[doc = " 1-indexed"]
    pub fn set_val(&mut self, k: usize, x: G::T) {
        let y = self.invert(&self.get_val(k));
        let z = self.operate(&y, &x);
        self.update(k, z);
    }
}
impl<M: Monoid> BinaryIndexedTree<M>
where
    M::T: Ord,
{
    #[doc = " 1-indexed"]
    pub fn lower_bound(&self, x: M::T) -> (usize, M::T) {
        let n = self.bit.len() - 1;
        let mut acc = self.ident();
        let mut pos = 0;
        let mut k = 1 << format!("{:b}", n).len();
        while k > 0 {
            if k + pos <= n && self.operate(&acc, &self.bit[k + pos]) < x {
                pos += k;
                acc = self.operate(&acc, &self.bit[pos]);
            }
            k >>= 1;
        }
        (pos + 1, acc)
    }
}
#[derive(Clone)]
pub struct EdgeAttributeEulerTourBIT<'a, M: Monoid> {
    bit: BinaryIndexedTree<M>,
    euler: &'a EulerTourTree,
}
impl<'a, G: Group> EdgeAttributeEulerTourBIT<'a, G> {
    pub fn update_based_on_path(&mut self, eid: usize, x: G::T) {
        let e = &self.euler.es[eid];
        self.bit.update(e.l + 1, x.clone());
        let y = self.bit.invert(&x);
        self.bit.update(e.r + 1, y);
    }
    pub fn query_based_on_path(&self, u: usize) -> G::T {
        self.bit.query(self.euler.es[self.euler.vs[u].p].l + 1)
    }
}
impl EulerTourTree {
    pub fn gen_bit<'a, M: Monoid>(&'a self, monoid: M) -> EdgeAttributeEulerTourBIT<'a, M> {
        EdgeAttributeEulerTourBIT {
            bit: BinaryIndexedTree::new(self.etrace.len(), monoid),
            euler: self,
        }
    }
}
#[derive(Clone, Copy, Debug, Default, PartialEq, Eq)]
pub struct Adjacent {
    pub to: usize,
    pub id: usize,
}
impl Adjacent {
    pub fn new(to: usize, id: usize) -> Adjacent {
        Adjacent { to: to, id: id }
    }
}
#[derive(Clone, Debug, Default)]
pub struct Graph {
    pub vsize: usize,
    pub esize: usize,
    pub graph: Vec<Vec<Adjacent>>,
}
impl Graph {
    pub fn new(vsize: usize) -> Graph {
        Graph {
            vsize: vsize,
            esize: 0,
            graph: vec![vec![]; vsize],
        }
    }
    pub fn add_edge(&mut self, from: usize, to: usize) {
        self.graph[from].push(Adjacent::new(to, self.esize));
        self.esize += 1;
    }
    pub fn add_undirected_edge(&mut self, u: usize, v: usize) {
        self.graph[u].push(Adjacent::new(v, self.esize));
        self.graph[v].push(Adjacent::new(u, self.esize));
        self.esize += 1;
    }
    pub fn vertexes(&self) -> std::ops::Range<usize> {
        0..self.vsize
    }
    pub fn adjacency(&self, from: usize) -> &Vec<Adjacent> {
        &self.graph[from]
    }
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Vertex {
    l: usize,
    r: usize,
    d: i64,
    p: usize,
}
#[derive(Clone, Debug, Default, PartialEq, Eq, Hash)]
pub struct Edge {
    l: usize,
    r: usize,
}
#[derive(Clone, Debug, Default)]
pub struct EulerTourTree {
    root: usize,
    vs: Vec<Vertex>,
    es: Vec<Edge>,
    vtrace: Vec<usize>,
    etrace: Vec<usize>,
}
impl EulerTourTree {
    pub fn new() -> Self {
        Default::default()
    }
    fn euler_tour(&mut self, u: usize, p: usize, d: i64, graph: &Graph) {
        self.vs[u].l = self.vtrace.len();
        self.vs[u].d = d;
        self.vtrace.push(u);
        for a in graph.adjacency(u) {
            if a.to != p {
                self.es[a.id].l = self.etrace.len();
                self.etrace.push(a.id);
                self.euler_tour(a.to, u, d + 1, graph);
                self.vtrace.push(u);
                self.es[a.id].r = self.etrace.len();
                self.etrace.push(a.id);
                self.vs[a.to].p = a.id;
            }
        }
        self.vs[u].r = self.vtrace.len() - 1;
    }
    pub fn build(&mut self, root: usize, graph: &Graph) {
        let n = graph.vsize;
        self.root = root;
        self.vs = vec![Default::default(); n];
        self.es = vec![Default::default(); n - 1];
        self.vtrace.clear();
        self.etrace.clear();
        self.euler_tour(root, n, 0, graph);
    }
    pub fn vertex_in_range(&self, u: usize, v: usize) -> (usize, usize) {
        let (mut l, mut r) = (self.vs[u].l, self.vs[v].l);
        if l > r {
            std::mem::swap(&mut l, &mut r);
        }
        (l, r + 1)
    }
    pub fn subtree_range(&self, u: usize) -> (usize, usize) {
        (self.vs[u].l, self.vs[u].r + 1)
    }
}
#[derive(Clone, Debug)]
pub struct AddGroup<T: Copy + std::ops::Add<Output = T> + std::ops::Neg<Output = T>> {
    zero: T,
}
impl<T: Copy + std::ops::Add<Output = T> + std::ops::Neg<Output = T>> AddGroup<T> {
    pub fn new(zero: T) -> AddGroup<T> {
        AddGroup { zero: zero }
    }
}
impl<T: Copy + std::ops::Add<Output = T> + std::ops::Neg<Output = T> + PartialEq> Monoid
    for AddGroup<T>
{
    type T = T;
    #[inline]
    fn mempty(&self) -> T {
        self.zero.clone()
    }
    #[inline]
    fn mappend(&self, x: &T, y: &T) -> T {
        *x + *y
    }
}
impl<T: Copy + std::ops::Add<Output = T> + std::ops::Neg<Output = T> + PartialEq> Group
    for AddGroup<T>
{
    fn invert(&self, x: &T) -> T {
        -*x
    }
}
fn main() {
    input! { iter=iter, n };
    let mut graph = Graph::new(n);
    let mut euler = EulerTourTree::new();
    for u in 0..n {
        input_inner! { iter, k, c: [usize; k] };
        for &v in &c {
            graph.add_undirected_edge(u, v);
        }
    }
    euler.build(0, &graph);
    let mut bit = euler.gen_bit(AddGroup::new(0i64));
    input_inner! { iter, q };
    for _ in 0..q {
        input_inner! { iter, qty };
        if qty == 0 {
            input_inner! { iter, v, w: i64 };
            let i = euler.vs[v].p;
            bit.update_based_on_path(i, w);
        } else {
            input_inner! { iter, u };
            let ans = if u == 0 {
                0
            } else {
                bit.query_based_on_path(u)
            };
            println!("{}", ans);
        }
    }
}



Measured memory_bytes: 39432