#include <iostream>
#include <vector>
#include <queue>
#include <stack>
#include <set>
#include <map>
#include <limits.h>
#include <algorithm>
#include <math.h>
#include <array>
using ll = long long;
using namespace std;
struct OT
{
double t;
ll slow, fast;
const bool operator<(const OT other) const
{
if (t != other.t) return t < other.t;
else if (slow != other.slow) return slow > other.slow;
else return fast < other.fast;
}
};
vector<double> roots(array<ll, 3> coeffs, ll i = -1, ll j = -1) //the real ones
{
ll d = coeffs[1] * coeffs[1] - 4 * coeffs[0] * coeffs[2];
if (d < 0) return {};
double sqd = sqrt(d);
double plusd = (-static_cast<double>(coeffs[1]) + sqd) / static_cast<double>(2 * coeffs[0]);
if (d == 0) return { (-static_cast<double>(coeffs[1]) + sqd) / static_cast<double>(2 * coeffs[0]) };
double minusd = (-static_cast<double>(coeffs[1]) - sqd) / static_cast<double>(2 * coeffs[0]);
return { (-static_cast<double>(coeffs[1]) + sqd) / static_cast<double>(2 * coeffs[0]),
(-static_cast<double>(coeffs[1]) - sqd) / static_cast<double>(2 * coeffs[0]) };
}
vector<array<ll, 3>> queries;
vector<OT> overtakes; //on which T, slower car, faster car, late
vector<ll> order;
vector<ll> carsbyid;
int nextovertakeidx = 0;
void ff(int t)
{
while (nextovertakeidx < overtakes.size() && overtakes[nextovertakeidx].t < t) //update order up until t
{
if (carsbyid[overtakes[nextovertakeidx].slow] < carsbyid[overtakes[nextovertakeidx].fast])
{
swap(order[carsbyid[overtakes[nextovertakeidx].slow]], order[carsbyid[overtakes[nextovertakeidx].fast]]);
swap(carsbyid[overtakes[nextovertakeidx].slow], carsbyid[overtakes[nextovertakeidx].fast]);
}
nextovertakeidx++;
}
int sortid = nextovertakeidx;
while (sortid < overtakes.size() && overtakes[sortid].t == t) //sort overtakes on t by id
{
if (carsbyid[min(overtakes[sortid].slow, overtakes[sortid].fast)] > carsbyid[max(overtakes[sortid].slow, overtakes[sortid].fast)])
{
swap(order[carsbyid[overtakes[sortid].slow]], order[carsbyid[overtakes[sortid].fast]]);
swap(carsbyid[overtakes[sortid].slow], carsbyid[overtakes[sortid].fast]);
}
sortid++;
}
}
int main()
{
iostream::sync_with_stdio(0);
cin.tie(0);
int n, i, j, q;
cin >> n;
vector<array<ll, 3>> cars(n);
for (array<ll, 3>& in : cars) cin >> in[0] >> in[1] >> in[2];
cin >> q;
overtakes.reserve(n / 2 * n);
for (i = 0; i < n; i++)
{
for (j = i+1; j < n; j++)
{
vector<double> rv = roots({ cars[i][0] - cars[j][0], cars[i][1] - cars[j][1], cars[i][2] - cars[j][2] });
for (double r : rv)
{
if (0 < r && r <= 1e6)
{
if (r*cars[i][0]*2+cars[i][1] < r*cars[j][0]*2+cars[j][1])
overtakes.push_back({ r, i, j });
else
overtakes.push_back({ r, j, i });
}
if (r == 0) //no derivative here
{
if (1e-7*cars[i][0]*2+cars[i][1] < 1e-7*cars[j][0]*2+cars[j][1])
overtakes.push_back({ r, i, j });
else
overtakes.push_back({ r, j, i });
}
}
}
}
sort(overtakes.begin(), overtakes.end());
order.resize(n);
vector<array<ll, 2>> cs(n);
for (i = 0; i < n; i++) cs[i] = { cars[i][2], -i };
sort(cs.begin(), cs.end());
carsbyid.resize(n);
for (i = 0; i < n; i++) order[i] = -cs[n-i-1][1], carsbyid[order[i]] = i;
queries.resize(q); // time, place, idx
for (i = 0; i < q; i++)
{
queries[i][2] = i,
cin >> queries[i][1] >> queries[i][0];
queries[i][1]--;
}
sort(queries.begin(), queries.end());
vector<int> out(q);
for (i = 0; i < q; i++)
{
ff(queries[i][0]);
out[queries[i][2]] = order[queries[i][1]];
}
for (i = 0; i < q; i++) cout << out[i] + 1 << '\n';
}
//3
//2 3 1
//2 3 1
//2 3 1
//5
//1 0
//2 0
//1 10
//3 500000
//2 999999