#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <climits>
#include <vector>
#include <string>
#include <queue>
#include <deque>
#include <list>
#include <stack>
#include <set>
#include <map>
#include <unordered_set>
#include <unordered_map>
#include <algorithm>

#define int long long
#define MOD 1000000007

#define rep(i, n) for (int i = 0; i < (n); i++)
#define itrep(i, a) for (auto i = (a).begin(); i != (a).end(); i++)
#define REP(i, a, n) for (int i = (a); i <= (n); i++)
#define all(a) (a).begin(), (a).end()
#define mp(a, b) make_pair((a), (b))

using namespace std;

int dx[4] = { 1, 0, -1, 0 };
int dy[4] = { 0, -1, 0, 1 };

template<class T> void inputVector(vector<T>& v, int n) {
    v.resize(n);
    for (int i = 0; i < v.size(); i++) cin >> v[i];
}

const int INF = LLONG_MAX / 10;
const int BORDER = 11;

int N;
vector<int> V, W;
vector<vector<pair<int, int>>> m;

int getMaxValue(const vector<pair<int, int>> &m, int L) {
    auto it = upper_bound(all(m), mp(L, INF));
    it--;
    return it->second;
}

int getDepth(int now) {
    now++;
    int ret = -1;
    while (now) {
        now >>= 1;
        ret++;
    }
    return ret;
}

void f(int now, vector<pair<int, int>> &parentMap) {
    if (now >= N) return;

    m[now] = parentMap;
    for (auto &pr : parentMap) {
        if (pr.first == INF) break;
        m[now].push_back(mp(pr.first + W[now], pr.second + V[now]));
    }

    sort(all(m[now]));

    vector<int> eraseIds;
    int prevVal = -1;
    rep(i, m[now].size()) {
        auto &pr = m[now][i];
        if (pr.first == INF) break;
        if (pr.first == m[now][i + 1].first) eraseIds.push_back(i);
        else if (pr.second <= prevVal) eraseIds.push_back(i);
        else prevVal = pr.second;
    }

    rep(i, eraseIds.size()) {
        m[now].erase(m[now].begin() + (eraseIds[i] - i));
    }

    if (getDepth(now) == BORDER) {
        vector<pair<int, int>> tmp;
        tmp.push_back(mp(0, 0));
        tmp.push_back(mp(INF, INF));
        f(now * 2 + 1, tmp);
        f(now * 2 + 2,tmp );
    } else {
        f(now * 2 + 1, m[now]);
        f(now * 2 + 2, m[now]);
    }
    // cerr << "node " << now << endl;
    // for (auto &pr : m[now]) {
    //     cerr << " " << pr.first << " -> " << pr.second << endl;
    // }

    // cerr << " complete " << now << " : size=" << m[now].size() << endl;
}

int solve(int v, int L) {
    int depth = getDepth(v);
    if (depth <= BORDER) {
        return getMaxValue(m[v], L);
    }

    //cerr << "PASS" << endl;

    int parent = v;
    while (depth > BORDER) {
        parent = (parent - 1) / 2;
        depth--;
    }

    // cerr << " child:" << endl;
    // for (auto &pr : m[v]) cerr << "  (" << pr.first << ", " << pr.second << ")" << endl;
    // cerr << " parent(" << parent << "):" << endl;
    // for (auto &pr : m[parent]) cerr << "  (" << pr.first << ", " << pr.second << ")" << endl;

    int ret = 0;
    for (auto &pr : m[v]) {
        if (pr.first > L) break;

        ret = max(ret, pr.second + getMaxValue(m[parent], L - pr.first));
    }
    return ret;
}

signed main() {
    cin >> N;

    V.resize(N);
    W.resize(N);
    m.resize(N);

    rep(i, N) cin >> V[i] >> W[i];

    vector<pair<int, int>> tmp;
    tmp.push_back(mp(0, 0));
    tmp.push_back(mp(INF, INF));
    f(0, tmp);

    int Q;
    cin >> Q;
    rep(_, Q) {
        int v, L;
        cin >> v >> L;
        v--;

        cout << solve(v, L) << endl;
    }

    return 0;
}


Measured memory_bytes: 356144