### BUGGY CODE ###

import sys
import numpy as np
from numba import njit

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

@njit('(i4[:],i4[:],i4)', cache=True)
def solve(values, weights, lim):
    N = len(values)
    if N == 1:
        if weights[0] <= lim:
            return values[0]
        else:
            return 0

    def compute_half(values, weights, lim):
        N = len(values)
        V = np.empty(1 << N, np.int32)
        W = np.empty(1 << N, np.int32)
        V[0], W[0] = 0, 0
        for i in range(N):
            for j in range(1 << i):
                V[j + (1 << i)] = V[j] + values[i]
                W[j + (1 << i)] = W[j] + weights[i]
        ind = W.argsort()
        V = V[ind]
        W = W[ind]
        for i in range(1, 1 << N):
            V[i] = max(V[i - 1], V[i])
        ind1 = W <= lim
        V = V[ind1]
        W = W[ind1]
        return V, W

    n = N // 2
    VL, WL = compute_half(values[:n], weights[:n], lim)
    VR, WR = compute_half(values[n:], weights[n:], lim)
    best = 0
    j = len(WR) - 1
    for i in range(len(WL)):
        while WL[i] + WR[j] > lim:
            j -= 1
        x = VL[i] + VR[j]
        best = max(best, x)
    return best

@njit('(i4,i4[:],i4[:],i4[:],i4[:])', cache=True)
def main(N, V, W, v, L):
    Q = len(v)
    values = np.empty(18, np.int32)
    weights = np.empty(18, np.int32)
    for i in range(Q):
        n = v[i]
        p = 0
        while n:
            values[p] = V[n]
            weights[p] = W[n]
            p += 1
            n >>= 1
        x = solve(values[:p], weights[:p], L[i])
        print(x)

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2], query[1::2]

main(N, V, W, v, L)

### FIXED CODE ###

import sys
import numpy as np
from numba import njit

read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

# ノード、重さ→価値
@njit('(i4,i4[:],i4[:])', cache=True)
def precompute(N, V, W):
    U = 10**5 + 10
    dp = np.zeros((1024, U), np.int32)
    for v in range(1, min(1024, N + 1)):
        p = v // 2
        dp[v] = dp[p]
        dp[v, W[v]:] = np.maximum(dp[v, W[v]:], dp[p, :-W[v]] + V[v])
        for i in range(1, U):
            dp[v][i] = max(dp[v][i], dp[v][i - 1])
    return dp

@njit('(i4,i4[:],i4[:],i4[:],i4[:])', cache=True)
def main(N, V, W, v, L):
    dp = precompute(N, V, W)
    values = np.empty(1024, np.int32)
    weights = np.empty(1024, np.int32)

    def solve(i, lim, values, weights, dp):
        if i < 1024:
            return dp[i][lim]
        values[0] = 0
        weights[0] = 0
        p = 0
        while i >= 1024:
            for j in range(1 << p):
                values[j + (1 << p)] = values[j] + V[i]
                weights[j + (1 << p)] = weights[j] + W[i]
            p += 1
            i >>= 1
        best = 0
        for n in range(1 << p):
            if weights[n] > lim:
                continue
            x = dp[i][lim - weights[n]] + values[n]
            best = max(best, x)
        return best

    Q = len(v)
    for i in range(Q):
        x = solve(v[i], L[i], values, weights, dp)
        print(x)

N = int(readline())
stdin = np.array(read().split(), np.int32)
V = np.zeros(N + 1, np.int32)
W = np.zeros(N + 1, np.int32)
V[1:] = stdin[:N + N:2]
W[1:] = stdin[1:N + N:2]
query = stdin[N + N + 1:]
v, L = query[::2], query[1::2]

main(N, V, W, v, L)