#pragma GCC optimize("O3", "unroll-loops")
#pragma GCC target("avx")

#include <iostream>
#include <algorithm>
#include <cstring>

constexpr int INPUT_SIZE = 1 << 17;
char Input[INPUT_SIZE];
inline char get_char(void){
    static int index_ptr = INPUT_SIZE; 
    if(index_ptr == INPUT_SIZE){ fread_unlocked(Input, sizeof(char), INPUT_SIZE, stdin); index_ptr = 0; }
    return Input[index_ptr++];
}
inline int getint(void){
    int res = 0, c;
    while( (c = get_char() - '0') >= 0 ) res = 10 * res + c;
    return res;
}

inline void println(int x){
    static char S[10]; static char* ptr = S;
    if(x){
        while(x){ *(ptr++) = x % 10; x /= 10; }
        while(ptr != S) putchar_unlocked(*(--ptr) | '0');
    }
    else putchar_unlocked('0');
    putchar_unlocked('\n');
}

constexpr int MAX_N = 1 << 18;
constexpr int MAX_M = 1 << 9;
constexpr int MAX_L = 100000;
constexpr int MAX_Q = 100000;
int dp[MAX_M][MAX_L + 1];
int V[MAX_N], W[MAX_N];
int Query[MAX_Q];
long long int P[MAX_Q + 1];
int Begin[(1 << 18) + 1];
int Stack[MAX_N];
int stack_len = 0;
int bitDPw[MAX_M];
int bitDPv[MAX_M];

constexpr int mask0 = (1 << 20) - 1;

int main(void){
    const int n = getint();
    for(int i = 0; i < n; ++i) V[i] = getint(), W[i] = getint();
    const int q = getint();
    for(int i = 0; i < q; ++i){
        const int v = getint(), L = getint();
        P[i] = ((long long int)(v - 1) << 40) | ((long long int)(i) << 20) | L;
    }
    std::sort(P, P + q); P[q] = -1;
    for(int i = 0, j = 0; i < n; ++i){
        Begin[i] = j;
        while((P[j] >> 40) == i) P[j++] ^= (long long int)(i) << 40;
    } Begin[n] = q;

    {
        constexpr int Size = sizeof(dp[0]);
        const int e = (MAX_M > n) ? n : MAX_M;
        for(int i = 0; i < e; ++i){
            for(int j1 = MAX_L, j2 = MAX_L - W[i]; j2 > 0; --j1, --j2) if(dp[i][j2]){
                const int&& val = dp[i][j2] + V[i]; if(val > dp[i][j1]) dp[i][j1] = val;
            } if(dp[i][W[i]] < V[i]) dp[i][W[i]] = V[i];

            const int p1 = 2 * i + 1; if(p1 < e) std::memcpy(dp[p1], dp[i], Size); else if(p1 < n) Stack[stack_len++] = p1;
            const int p2 = 2 * i + 2; if(p2 < e) std::memcpy(dp[p2], dp[i], Size); else if(p2 < n) Stack[stack_len++] = p2;
            dp[i][0] = 0;
            for(int j = 1; j <= MAX_L; ++j){
                if( dp[i][j] < dp[i][j - 1] ) dp[i][j] = dp[i][j - 1];
            }

            for(int idx = Begin[i]; idx < Begin[i + 1]; ++idx) Query[P[idx] >> 20] = dp[i][P[idx] & mask0];
        }
    }
    while(stack_len--){
        const int bit = (Stack[stack_len] >> 20), v = Stack[stack_len] & mask0;
        {
            const int p1 = 2 * v + 1; if(p1 < n) Stack[stack_len++] = ((bit + 1) << 20) | p1;
            const int p2 = 2 * v + 2; if(p2 < n) Stack[stack_len++] = ((bit + 1) << 20) | p2;
        }
        const int len = 1 << bit;
        for(int i = 0; i < len; ++i){
            bitDPv[i | len] = bitDPv[i] + V[v];
            bitDPw[i | len] = bitDPw[i] + W[v];
        }
        const int len_two = len << 1;
        const int par = ((v + 1) >> (bit + 1)) - 1;
        for(int idx = Begin[v]; idx < Begin[v + 1]; ++idx){
            const int res_idx = (P[idx] >> 20) & mask0, l = P[idx] & mask0;
            for(int i = 0; i < len_two; ++i) if(bitDPw[i] <= l){
                const int&& val = bitDPv[i] + dp[par][l - bitDPw[i]];
                if(val > Query[res_idx]) Query[res_idx] = val;
            }
        }
    }
    for(int i = 0; i < q; ++i) println(Query[i]);
    return 0;
}

Measured memory_bytes: 207956