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 ,{$t :tt =>$f :expr } ) =>{$f (read_value !($iter ,$t ) ) } ;($iter :expr ,chars ) =>{read_value !($iter ,String ) .chars () .collect ::<Vec <char >>() } ;($iter :expr ,usize1 ) =>{read_value !($iter ,usize ) -1 } ;($iter :expr ,$t :ty ) =>{$iter .next () .unwrap () .parse ::<$t >() .unwrap () } ;}
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 !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 ) *} } ;}
/// binary search helper
pub trait Bisect: Copy {
    /// return between two elements
    fn halve(self, other: Self) -> Self;
    /// the end condition of binary search
    fn section_end(self, other: Self) -> bool;
}
pub mod bisect_impl {
    use super::*;
    macro_rules !impl_bisect_unsigned {($($t :ty ) *) =>{$(impl Bisect for $t {fn halve (self ,other :Self ) ->Self {if self >other {other +(self -other ) /2 } else {self +(other -self ) /2 } } fn section_end (self ,other :Self ) ->bool {(if self >other {self -other } else {other -self } ) <=1 } } ) *} ;}
    macro_rules !impl_bisect_signed {($($t :ty ) *) =>{$(impl Bisect for $t {fn halve (self ,other :Self ) ->Self {(self +other ) /2 } fn section_end (self ,other :Self ) ->bool {(self -other ) .abs () <=1 } } ) *} ;}
    macro_rules !impl_bisect_float {($($t :ty ) *) =>{$(impl Bisect for $t {fn halve (self ,other :Self ) ->Self {(self +other ) /2. } fn section_end (self ,other :Self ) ->bool {(self -other ) .abs () <=1e-8 } } ) *} ;}
    impl_bisect_unsigned !(u8 u16 u32 u64 usize ) ;
    impl_bisect_signed !(i8 i16 i32 i64 isize ) ;
    impl_bisect_float !(f32 f64 ) ;
}
pub fn binary_search<T: Bisect, F: Fn(T) -> bool>(f: F, ok: T, err: T) -> T {
    let mut ok = ok;
    let mut err = err;
    while !ok.section_end(err) {
        let m = ok.halve(err);
        if f(m) {
            ok = m;
        } else {
            err = m;
        }
    }
    ok
}
pub fn lower_bound<T: Bisect + Ord>(v: &[T], x: T) -> usize {
    binary_search(|i| v[i as usize] >= x, v.len() as i64, -1) as usize
}
pub fn upper_bound<T: Bisect + Ord>(v: &[T], x: T) -> usize {
    binary_search(|i| v[i as usize] > x, v.len() as i64, -1) as usize
}
#[macro_export]
macro_rules !min {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::min ($e ,min !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmin {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::min ($dst ,min !($($src ) ,+) ) ;$dst =x ;} } ;}
#[macro_export]
macro_rules !max {($e :expr ) =>{$e } ;($e :expr ,$($es :expr ) ,+) =>{std ::cmp ::max ($e ,max !($($es ) ,+) ) } ;}
#[macro_export]
macro_rules !chmax {($dst :expr ,$($src :expr ) ,+) =>{{let x =std ::cmp ::max ($dst ,max !($($src ) ,+) ) ;$dst =x ;} } ;}
fn main() {
    #[allow(unused_imports)]
    use std::io::Write as _;
    let __out = std::io::stdout();
    #[allow(unused_mut, unused_variables)]
    let mut __out = std::io::BufWriter::new(__out.lock());
    #[allow(unused_macros)]
    macro_rules !print {($($arg :tt ) *) =>(::std ::write !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules !println {($($arg :tt ) *) =>(::std ::writeln !(__out ,$($arg ) *) .unwrap () ) }
    #[allow(unused_macros)]
    macro_rules! echo {
        ($iter :expr ) => {
            echo!($iter, "\n")
        };
        ($iter :expr ,$sep :expr ) => {
            let mut iter = $iter;
            if let Some(item) = iter.next() {
                print!("{}", item);
            }
            for item in iter {
                print!("{}{}", $sep, item);
            }
            println!();
        };
    }
    input!(n, vw: [(u32, u32); n], q, ul: [(usize, u32); q]);
    let th: usize = min!(1 << 9, n);
    let mut arr = vec![vec![]; n + 1];
    let mut need = vec![false; n + 1];
    let mut qp = vec![0; q];
    for (i, &(u, _l)) in ul.iter().enumerate() {
        let mut p = u;
        while p > th {
            need[p] = true;
            p /= 2;
        }
        qp[i] = p;
    }
    arr[0].push((0u32, 0u32));
    for i in 1..=n {
        if i > th && !need[i] {
            continue;
        }
        if i > th && i / 2 <= th {
            arr[i].push((0, 0));
            arr[i].push(vw[i - 1]);
            continue;
        }
        let ln = arr[i / 2].len();
        arr[i].reserve(ln * 2);
        let (mut j, mut k) = (0, 0);
        let (v, w) = vw[i - 1];
        while j < ln && k < ln {
            let (v1, w1) = arr[i / 2][j];
            let (v2, w2) = arr[i / 2][k];
            match w1.cmp(&(w2 + w)) {
                std::cmp::Ordering::Less => {
                    arr[i].push((v1, w1));
                    j += 1;
                }
                std::cmp::Ordering::Equal => {
                    arr[i].push((max!(v1, v2 + v), w1));
                    j += 1;
                    k += 1;
                }
                std::cmp::Ordering::Greater => {
                    arr[i].push((v2 + v, w2 + w));
                    k += 1;
                }
            }
        }
        while j < ln {
            let t = arr[i / 2][j].clone();
            arr[i].push(t);
            j += 1;
        }
        while k < ln {
            let (vs, ws) = arr[i / 2][k];
            arr[i].push((vs + v, ws + w));
            k += 1;
        }
        for j in 1..arr[i].len() {
            chmax!(arr[i][j].0, arr[i][j - 1].0);
        }
    }
    for (i, (u, l)) in ul.into_iter().enumerate() {
        if u <= th {
            let j = binary_search(|j| arr[u][j].1 <= l, 0, arr[u].len());
            println!("{}", arr[u][j].0);
        } else {
            let xs = &arr[u];
            let ys = &arr[qp[i]];
            let mut j = ys.len() - 1;
            let mut ans = 0;
            'o: for i in 0..xs.len() {
                while xs[i].1 + ys[j].1 > l {
                    if j == 0 {
                        break 'o;
                    }
                    j -= 1;
                }
                chmax!(ans, xs[i].0 + ys[j].0);
            }
            println!("{}", ans);
        }
    }
}


Measured memory_bytes: 554204