# Original solution
import sys
from collections import deque
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
inf = 10**6


def main():
    N = int(eval(input()))
    VW = [(inf, inf)] + [list(map(int, input().split())) for _ in range(N)]
    Q = int(eval(input()))
    query = tuple(tuple(map(int, input().split())) for _ in range(Q))
    D = N.bit_length()

    for n, L in query:
        memo1 = deque([(0, 0)])  # w,v
        memo2 = deque([(0, 0)])  # w,v
        while n > 0:
            vi, wi = VW[n]
            if n <= 2048:
                res = deque([(-1, -1)])
                m1 = deque([(wi + w, vi + v) for w, v in memo1])
                while m1 and memo1:
                    if m1[0][0] >= memo1[0][0]:
                        w, v = memo1.popleft()
                    else:
                        w, v = m1.popleft()
                    if res[-1][0] < w:
                        res.append((w, v))
                    elif res[-1][1] < v:
                        res.pop()
                        res.append((w, v))
                while m1:
                    w, v = m1.popleft()
                    if res[-1][0] < w:
                        res.append((w, v))
                    elif res[-1][1] < v:
                        res.pop()
                        res.append((w, v))
                while memo1:
                    w, v = memo1.popleft()
                    if res[-1][0] < w:
                        res.append((w, v))
                    elif res[-1][1] < v:
                        res.pop()
                        res.append((w, v))
                res.popleft()
                memo1 = res
            else:
                res = deque([(-1, -1)])
                m2 = deque([(wi + w, vi + v) for w, v in memo2])
                while m2 and memo2:
                    if m2[0][0] >= memo2[0][0]:
                        w, v = memo2.popleft()
                    else:
                        w, v = m2.popleft()
                    if res[-1][0] < w:
                        res.append((w, v))
                    elif res[-1][1] < v:
                        res.pop()
                        res.append((w, v))
                while m2:
                    w, v = m2.popleft()
                    if res[-1][0] < w:
                        res.append((w, v))
                    elif res[-1][1] < v:
                        res.pop()
                        res.append((w, v))
                while memo2:
                    w, v = memo2.popleft()
                    if res[-1][0] < w:
                        res.append((w, v))
                    elif res[-1][1] < v:
                        res.pop()
                        res.append((w, v))
                res.popleft()
                memo2 = res
            n //= 2

        ans = 0
        memo2.reverse()
        j = len(memo2) - 1
        for w, v in memo1:
            if w > L:
                break
            while j >= 0 and w + memo2[j][0] > L:
                j -= 1
            if j < 0:
                break
            ans = max(ans, v + memo2[j][1])
        print(ans)


if __name__ == "__main__":
    main()

# Optimized solution
import sys
import bisect
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)


def merge(a, b):
    res = []
    i, j = 0, 0
    while i < len(a) or j < len(b):
        if j >= len(b) or (i < len(a) and a[i][0] < b[j][0]):
            w, v = a[i]
            i += 1
        else:
            w, v = b[j]
            j += 1
        if not res or (res[-1][1]) < v:
            res.append((w, v))
        elif res[-1][0] == w and res[-1][1] <= v:
            res.pop()
            res.append((w, v))
    return res


def best(L, a, b):
    res = 0
    i = 0
    j = len(b) - 1
    # for w, v in a:
    while i < len(a):
        w, v = a[i]
        if j < 0:
            break
        if b[j][0] + w > L:
            j -= 1
            continue
        res = max(res, v + b[j][1])
        i += 1
    return res


def main():
    N = int(eval(input()))
    VW = [(-1, -1)] + [list(map(int, input().split())) for _ in range(N)]
    Q = int(eval(input()))
    query = tuple(tuple(map(int, input().split())) for _ in range(Q))

    dp = [[] for _ in range(1024)]
    dp[0] = [(0, 0)]
    for i in range(1, min(N + 1, 1024)):
        vi, wi = VW[i]
        a1 = dp[i // 2]
        a2 = [(w + wi, v + vi) for w, v in a1]
        dp[i] = merge(a1, a2)

    for n, L in query:
        if n < 1024:
            w, v = list(zip(*dp[n]))
            i = bisect.bisect_right(w, L) - 1
            print((v[i]))
        else:
            a = [(0, 0)]
            while n >= 1024:
                vi, wi = VW[n]
                b = [(w + wi, v + vi) for w, v in a]
                a = merge(a, b)
                n //= 2
            print((best(L, a, dp[n])))


if __name__ == "__main__":
    main()