#include <algorithm>
#include <array>
#include <bitset>
#include <boost/multiprecision/cpp_bin_float.hpp>
#include <boost/multiprecision/cpp_int.hpp>
#include <boost/rational.hpp>
#include <cassert>
#include <chrono>
#include <climits>
#include <cmath>
#include <complex>
#include <cstddef>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <deque>
#include <forward_list>
#include <functional>
#include <initializer_list>
#include <iomanip>
#include <iostream>
#include <limits>
#include <list>
#include <map>
#include <memory>
#include <numeric>
#include <optional>
#include <queue>
#include <random>
#include <regex>
#include <set>
#include <sstream>
#include <stack>
#include <string>
#include <tuple>
#include <type_traits>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <variant>
#include <vector>
// using namespace std;

namespace my_atcoder
{
	using std::cout, std::endl, std::vector, std::string, std::array;
	constexpr int64_t MOD = 1000000007;

	template <class T>
	class read_impl;

	template <class T, size_t n>
	class read_impl<array<T, n>>
	{
	public:
		using ret_type = array<T, n>;
		ret_type operator()() const
		{
			ret_type v;
			for (size_t i = 0; i < n; i++) v[i] = read_impl<T>()();
			return v;
		}
	};

	template <class... Ts>
	class read_impl<std::tuple<Ts...>>
	{
	public:
		using ret_type = std::tuple<Ts...>;
		ret_type operator()() const
		{
			ret_type v;
			std::apply([](auto&... args) { (void)std::initializer_list<int>{(void(f(args)), 0)...}; }, v);
			return v;
		}

	private:
		template <class T>
		static int f(T& arg)
		{
			arg = read_impl<T>()();
			return 0;
		}
	};

	template <class T1, class T2>
	class read_impl<std::pair<T1, T2>>
	{
	public:
		using ret_type = std::pair<T1, T2>;
		ret_type operator()() const { return ret_type{read_impl<T1>()(), read_impl<T2>()()}; }
	};

	template <class T, class Allocator>
	class read_impl<vector<T, Allocator>>
	{
	public:
		using ret_type = vector<T, Allocator>;
		ret_type operator()(size_t len) const
		{
			ret_type v;
			for (size_t i = 0; i < len; i++) v.push_back(read_impl<T>()());
			return v;
		}
	};

	template <class T>
	class read_impl
	{
	public:
		using ret_type = T;
		T operator()() const
		{
			T v;
			std::cin >> v;
			return v;
		}
	};

	template <class T, class... Ts>
	auto read(Ts... args)
	{
		return read_impl<T>()(std::forward<Ts>(args)...);
	}

	template <class T, size_t n>
	std::ostream& operator<<(std::ostream& os, const array<T, n>& v)
	{
		auto f = false;
#ifdef MY_RICH_PRINT
		os << "array(";
#endif
		for (auto& e : v)
		{
			if (f)
#ifdef MY_RICH_PRINT
				os << ", ";
#else
				os << " ";
#endif
			os << e;
			f = true;
		}
#ifdef MY_RICH_PRINT
		os << ")";
#endif
		return os;
	}

	template <class T>
	static int my_cout_impl(const T& arg, std::ostream& os, bool& f)
	{
		if (f)
#ifdef MY_RICH_PRINT
			os << ", ";
#else
			os << " ";
#endif
		os << arg;
		f = true;
		return 0;
	}

	template <class... Ts>
	std::ostream& operator<<(std::ostream& os, const std::tuple<Ts...>& v)
	{
		auto f = false;
#ifdef MY_RICH_PRINT
		os << "tuple(";
#endif
		apply([&os, &f](const auto&... args) { (void)std::initializer_list<int>{(void(my_cout_impl(args, os, f)), 0)...}; }, v);
#ifdef MY_RICH_PRINT
		os << ")";
#endif
		return os;
	}

	template <class T1, class T2>
	std::ostream& operator<<(std::ostream& os, const std::pair<T1, T2>& v)
	{
#ifdef MY_RICH_PRINT
		return os << "pair(" << v.first << ", " << v.second << ")";
#else
		return os << v.first << " " << v.second;
#endif
	}

	template <class T, class Allocator>
	std::ostream& operator<<(std::ostream& os, const vector<T, Allocator>& v)
	{
		auto f = false;
#ifdef MY_RICH_PRINT
		os << "vector(";
#endif
		for (auto& e : v)
		{
			if (f)
#ifdef MY_RICH_PRINT
				os << ", ";
#else
				os << " ";
#endif
			os << e;
			f = true;
		}
#ifdef MY_RICH_PRINT
		os << ")";
#endif
		return os;
	}

	template <class Key, class T, class Compare, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::map<Key, T, Compare, Allocator>& v)
	{
#ifndef MY_RICH_PRINT
		assert(0);
#endif
		auto f = false;
		os << "map(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p.first << ": " << p.second;
			f = true;
		}
		return os << ")";
	}

	template <class Key, class T, class Compare, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::multimap<Key, T, Compare, Allocator>& v)
	{
#ifndef MY_RICH_PRINT
		assert(0);
#endif
		auto f = false;
		os << "multimap(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p.first << ": " << p.second;
			f = true;
		}
		return os << ")";
	}

	template <class Key, class Compare, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::set<Key, Compare, Allocator>& v)
	{
		auto f = false;
#ifdef MY_RICH_PRINT
		os << "set(";
#endif
		for (auto& p : v)
		{
			if (f)
#ifdef MY_RICH_PRINT
				os << ", ";
#else
				os << " ";
#endif
			os << p;
			f = true;
		}
#ifdef MY_RICH_PRINT
		os << ")";
#endif
		return os;
	}

	template <class Key, class Compare, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::multiset<Key, Compare, Allocator>& v)
	{
		auto f = false;
		os << "multiset(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p;
			f = true;
		}
		return os << ")";
	}

	template <class Key, class T, class Hash, class Pred, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::unordered_map<Key, T, Hash, Pred, Allocator>& v)
	{
#ifndef MY_RICH_PRINT
		assert(0);
#endif
		auto f = false;
		os << "unordered_map(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p.first << ": " << p.second;
			f = true;
		}
		return os << ")";
	}

	template <class Key, class T, class Hash, class Pred, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::unordered_multimap<Key, T, Hash, Pred, Allocator>& v)
	{
#ifndef MY_RICH_PRINT
		assert(0);
#endif
		auto f = false;
		os << "unordered_multimap(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p.first << ": " << p.second;
			f = true;
		}
		return os << ")";
	}

	template <class Key, class Hash, class Pred, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::unordered_set<Key, Hash, Pred, Allocator>& v)
	{
		auto f = false;
		os << "unordered_set(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p;
			f = true;
		}
		return os << ")";
	}

	template <class Key, class Hash, class Pred, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::unordered_multiset<Key, Hash, Pred, Allocator>& v)
	{
		auto f = false;
		os << "unordered_multiset(";
		for (auto& p : v)
		{
			if (f) os << ", ";
			os << p;
			f = true;
		}
		return os << ")";
	}

	template <class T, class Container>
	std::ostream& operator<<(std::ostream& os, const std::queue<T, Container>& v)
	{
		std::queue<T, Container> v2 = v;
		auto f = false;
		os << "queue(";
		while (!v2.empty())
		{
			os << (f ? ", " : "front: ") << v2.front();
			v2.pop();
			f = true;
		}
		return os << ")";
	}

	template <class T, class Container>
	std::ostream& operator<<(std::ostream& os, const std::stack<T, Container>& v)
	{
		std::stack<T, Container> v2 = v;
		auto f = false;
		os << "stack(";
		while (!v2.empty())
		{
			os << (f ? ", " : "top: ") << v2.top();
			v2.pop();
			f = true;
		}
		return os << ")";
	}

	template <class T, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::deque<T, Allocator>& v)
	{
		auto f = false;
		os << "deque(";
		for (auto& e : v)
		{
			if (f) os << ", ";
			os << e;
			f = true;
		}
		return os << ")";
	}

	template <class T, class Container, class Compare>
	std::ostream& operator<<(std::ostream& os, const std::priority_queue<T, Container, Compare>& v)
	{
		std::priority_queue<T, Container, Compare> v2 = v;
		auto f = false;
		os << "priority_queue(";
		while (!v2.empty())
		{
			os << (f ? ", " : "top: ") << v2.top();
			v2.pop();
			f = true;
		}
		return os << ")";
	}

	template <class T, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::list<T, Allocator>& v)
	{
		auto f = false;
		os << "list(";
		for (auto& e : v)
		{
			if (f) os << ", ";
			os << e;
			f = true;
		}
		return os << ")";
	}

	template <class T>
	std::ostream& operator<<(std::ostream& os, const std::initializer_list<T>& v)
	{
		auto f = false;
		os << "initializer_list(";
		for (auto& e : v)
		{
			if (f) os << ", ";
			os << e;
			f = true;
		}
		return os << ")";
	}

	template <class T, class Allocator>
	std::ostream& operator<<(std::ostream& os, const std::forward_list<T, Allocator>& v)
	{
		auto f = false;
		os << "forward_list(";
		for (auto& e : v)
		{
			if (f) os << ", ";
			os << e;
			f = true;
		}
		return os << ")";
	}

	// 座圧
	template <class T, class Int = int>
	[[nodiscard]] std::map<T, Int> compress(const vector<T>& v)
	{
		std::map<T, Int> m;
		for (auto x : v) m[x] = 0;
		Int n = 0;
		for (auto& t : m) t.second = n++;
		return m;
	}

	// [b, ..., e] must be a shuffle of [0, 1, ..., len - 1] (len = e - b)
	template <class RanIt>
	[[nodiscard]] vector<vector<typename std::iterator_traits<RanIt>::value_type>> to_cycles(RanIt b, RanIt e)
	{
		using T = typename std::iterator_traits<RanIt>::value_type;
		vector<vector<T>> cycs;
		T len = e - b;
		vector<bool> done(len, false);
		for (T i = 0; i < len; ++i)
		{
			if (done[i]) continue;
			vector<T> cyc{i};
			auto j = b[i];
			while (j != i)
			{
				cyc.push_back(j);
				done[j] = true;
				j = b[j];
			}
			cycs.push_back(std::move(cyc));
		}
		return cycs;
	}

	template <class T>
	[[nodiscard]] auto to_cycles(const T& v)
	{
		using std::begin, std::end;
		return to_cycles(begin(v), end(v));
	}

	template <class T, size_t n>
	[[nodiscard]] double norm(const array<T, n>& p)
	{
		auto s = 0.0;
		for (int i = 0; i < n; ++i) s += double(p[i]) * p[i];
		return std::sqrt(s);
	}
	template <class T, size_t n>
	[[nodiscard]] double dist(const array<T, n>& p, const array<T, n>& q)
	{
		array<T, n> d;
		for (int i = 0; i < n; ++i) d[i] = p[i] - q[i];
		return norm(d);
	}

	template <class Int>
	[[nodiscard]] array<Int, 2> solve_linear(Int n, Int m)
	{
		static_assert(std::is_integral_v<Int> && std::is_signed_v<Int>);
		using V = array<Int, 2>;
		auto A = array{V{n < 0 ? -Int(1) : 1, 0}, V{0, m < 0 ? -Int(1) : 1}};
		if (n < 0) n *= -1;
		if (m < 0) m *= -1;
		while (m > 0)
		{
			Int q = n / m, r = n % m;
			n = m;
			m = r;
			for (int i = 0; i < 2; ++i)
			{
				Int x = A[i][1];
				A[i][1] = A[i][0] - q * x;
				A[i][0] = x;
			}
		}
		return {A[0][0], A[1][0]};
	}

	template <class Int>
	[[nodiscard]] Int mod(Int a, Int mod)
	{
		static_assert(std::is_integral_v<Int>);
		return (a % mod + mod) % mod;
	}

	template <class Int>
	[[nodiscard]] Int inverse(Int a, Int M)
	{
		return mod(solve_linear(mod(a, M), M)[0], M);
	}

	template <class Int>
	[[nodiscard]] Int pow(Int a, Int p, Int mod)
	{
		static_assert(std::is_integral_v<Int>);
		Int y = 1;
		Int x = a;
		while (p > 0)
		{
			if ((p & 1) == 1) y = (y * x) % mod;
			p >>= 1;
			x = (x * x) % mod;
		}
		return y;
	}

	template <class Int, class Pred>
	[[nodiscard]] Int first_binary(Int min, Int max, Pred pred)
	{
		static_assert(std::is_integral_v<Int>);
		while (min < max)
		{
			Int mid = min + (max - min) / 2;
			if (pred(mid))
				max = mid;
			else
				min = mid + 1;
		}
		return min;
	}

	template <class Int>
	[[nodiscard]] vector<Int> get_fact(int max, Int mod)
	{
		vector<Int> x{1};
		for (Int i = 1; i <= max; ++i) x.push_back(i * x.back() % mod);
		return x;
	}

	template <class Int>
	[[nodiscard]] vector<Int> get_fact_inv(int max, Int mod)
	{
		Int fc = 1;
		for (Int i = 2; i <= max; i++) fc = fc * i % mod;
		vector<Int> x(max + 1);
		x[max] = inverse(fc, mod);
		for (Int i = max; i >= 1; --i) x[i - 1] = x[i] * i % mod;
		return x;
	}

	class union_find
	{
		int n_;
		std::unique_ptr<int[]> par_, rk_, sz_;

	public:
		union_find(int cap)
		    : n_(cap), par_(std::make_unique<int[]>(cap)), rk_(std::make_unique<int[]>(cap)), sz_(std::make_unique<int[]>(cap))
		{
			for (int i = 0; i < n_; ++i)
			{
				par_[i] = i;
				rk_[i] = 0;
				sz_[i] = 1;
			}
		}
		int size(int v) { return sz_[root(v)]; }
		int root(int v) { return par_[v] == v ? v : par_[v] = root(par_[v]); }
		bool unite(int u, int v)
		{
			if ((u = root(u)) == (v == root(v))) return false;
			if (rk_[u] < rk_[v])
			{
				par_[u] = v;
				sz_[v] += sz_[u];
			}
			else
			{
				par_[v] = u;
				sz_[u] += sz_[v];
				if (rk_[u] == rk_[v]) ++rk_[u];
			}
			return true;
		}
		bool has_united(int u, int v) { return root(u) == root(v); }
	};

	template <class T>
	bool ch_min(T& x, const T& y)
	{
		if (x > y)
		{
			x = y;
			return true;
		}
		return false;
	}
	template <class T>
	bool ch_max(T& x, const T& y)
	{
		if (x < y)
		{
			x = y;
			return true;
		}
		return false;
	}

	template <class Int = int>
	[[nodiscard]] vector<Int> get_primes(Int n)
	{
		if (n < 3) n = 3;
		Int m = (n - 1) >> 1;
		vector<Int> ps{2};
		ps.reserve(n / std::log(n));
		vector<bool> ok(m, true);
		for (Int i = 0; i < m; ++i)
			if (ok[i])
			{
				Int p = 2 * i + 3;
				ps.push_back(p);
				for (Int k = 3 * i + 3; k < m; k += p) ok[k] = false;
			}
		return ps;
	}

	[[nodiscard]] bool is_prime(uint64_t n)
	{
		if (n <= 1 || (n > 2 && n % 2 == 0)) return false;
		// constexpr auto test = array{2, 3, 5, 7, 11, 13, 17, 19, 23, 111};
		auto d = n - 1;
		int s = 0;
		while (d % 2 == 0)
		{
			++s;
			d /= 2;
		}
		auto f = [n, d, s](uint64_t t) {
			auto x = pow(t, d, n);
			if (x == 1) return true;
			for (int r = 0; r < s; ++r)
			{
				if (x == n - 1) return true;
				x = (x * x) % n;
			}
			return false;
		};
		for (auto i : {2, 3, 5, 7, 11, 13, 17, 19, 23})
		{
			if (i >= n) return true;
			if (!f(i)) return false;
		}
		// for (int i = 0; test[i] < n && test[i] != 111; ++i)
		//	if (!f(test[i])) return false;
		return true;
	}

	namespace mp = boost::multiprecision;
	using real = mp::number<mp::cpp_bin_float<200>>;
	using integer = mp::cpp_int;
	using rational = boost::rational<integer>;

	[[nodiscard]] real to_real(const rational& r) { return real(r.numerator()) / real(r.denominator()); }

	struct Item
	{
		int v, w;
		Item() : v(0), w(0) {}
		Item(int v, int w) : v(v), w(w) {}
		friend Item operator+(const Item& a, const Item& b) { return {a.v + b.v, a.w + b.w}; }
		friend bool operator<(const Item& a, const Item& b) { return a.w < b.w; }
	};
	void normalize(vector<Item>& t)
	{
		std::sort(t.begin(), t.end());
		auto it = t.begin(), it2 = t.begin();
		int best = -1;
		while (it != t.end())
			if (it->v > best)
			{
				best = it->v;
				std::swap(*(it++), *(it2++));
			}
			else
				++it;
		t.erase(it2, t.end());
	}

	struct Query
	{
		int i, L;
		Query() : i(0), L(0) {}
		Query(int i, int L) : i(i), L(L) {}
		friend bool operator<(const Query& a, const Query& b) { return a.L < b.L; }
	};

	void solve()
	{
		auto N = read<int>();
		// int N = (1 << 18) - 1;
		vector<Item> items;
		// std::random_device rd;
		// std::mt19937 mt(rd());
		// std::uniform_int_distribution<int> dist(1, 100000);
		// for (int i = 0; i < N; ++i) items.push_back({dist(mt), dist(mt)});
		for (int i = 0; i < N; ++i)
		{
			auto [v, w] = read<array<int, 2>>();
			items.push_back({v, w});
		}
		auto Q = read<int>();
		// int Q = 100000;
		vector<Query> queries;
		// for (int i = 0; i < Q; ++i) queries.push_back({dist(mt) - 1, dist(mt)});
		for (int i = 0; i < Q; ++i)
		{
			auto [v, L] = read<array<int, 2>>();
			queries.push_back({v - 1, L});
		}
		auto L_MAX = std::max_element(queries.begin(), queries.end())->L;
		std::chrono::high_resolution_clock::time_point start, end;
		start = std::chrono::high_resolution_clock::now();
		vector<vector<Item>> memo;
		memo.push_back(vector{Item()});
		if (items[0].w <= L_MAX) memo[0].push_back({items[0].v, items[0].w});
		for (int i = 1; i < 2048 && i < N; ++i)
		{
			auto x = items[i];
			int p = (i + 1) / 2 - 1, l = int(memo[p].size());
			vector<Item> t = memo[p];
			for (auto y : memo[p])
			{
				auto z = x + y;
				if (z.w <= L_MAX) t.push_back(z);
			}
			normalize(t);
			memo.push_back(std::move(t));
		}
		//		end = std::chrono::high_resolution_clock::now();
		//#ifdef MY_RICH_PRINT
		//		cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << endl;
		//#endif
		for (auto q : queries)
		{
			int i = q.i;
			if (i < memo.size())
			{
				auto it = std::upper_bound(memo[i].begin(), memo[i].end(), Item{0, q.L});
				--it;
				cout << it->v << endl;
				continue;
			}
			vector<int> pars;
			while (i >= memo.size())
			{
				pars.push_back(i);
				i = (i + 1) / 2 - 1;
			}
			auto& half = memo[i];
			vector<Item> left;
			int ALL = (1 << pars.size()) - 1;
			for (int s = 0; s <= ALL; ++s)
			{
				Item item;
				for (int j = 0; j < pars.size(); ++j)
					if ((s >> j) & 1) item = item + items[pars[j]];
				if (item.w <= q.L) left.push_back(item);
			}
			normalize(left);
			int best = 0;
			for (auto x : left)
			{
				auto it = std::upper_bound(half.begin(), half.end(), Item{0, q.L - x.w});
				--it;
				best = std::max(best, it->v + x.v);
			}
			cout << best << endl;
		}
		// end = std::chrono::high_resolution_clock::now();
		//#ifdef MY_RICH_PRINT
		// cout << std::chrono::duration_cast<std::chrono::milliseconds>(end - start).count() << endl;
		//#endif
	}
}  // namespace my_atcoder

int main()
{
	std::cin.tie(nullptr);
	std::ios::sync_with_stdio(false);
	my_atcoder::solve();
	std::cout << std::flush;
	return 0;
}


Measured memory_bytes: 27072