#include <bits/stdc++.h>
using namespace std;
ifstream fin("atac.in");
ofstream fout("atac.out");
const int NMAX = 32e3 + 5, MMAX = 5e5 + 4;
int A, B, C, D, x, y;
int n, q, p, depth[NMAX];
int peuler[2 * NMAX + 5], nrpeuler = 0;
int rmq[2 * NMAX + 5][22], firstPos[NMAX];
int ans[MMAX], treeRMQ[NMAX][22];//treeRMQ[node][j] retin muchia minima pt nodes[node][j]
int father[NMAX], nodes[NMAX][22];//nodes[node][j] retin nodul cu 1 << j pozitii mai sus
vector <int> g[NMAX];
map < pair <int, int>, int > costMuchii;
bitset <NMAX> viz;
inline void citire()
{
memset(firstPos, 0, sizeof(firstPos));
memset(peuler, 0, sizeof(peuler));
fin >> n >> q >> p;
for(int i = 2; i <= n; ++i)
{
fin >> x >> y;
costMuchii[{min(x, i), max(x, i)}] = y;
g[i].push_back(x);
g[x].push_back(i);
father[i] = x;
}
fin >> x >> y >> A >> B >> C >> D;
}
inline int newX(int X, int Y)
{
return (X * A + Y * B) % n + 1;
}
inline int newY(int Y, int Z)
{
return (Y * C + Z * D) % n + 1;
}
void DFS(int node, int dp)
{
if(firstPos[node] == 0)
firstPos[node] = nrpeuler + 1;
if(depth[node] == 0)
depth[node] = dp;
viz[node] = 1;
peuler[++nrpeuler] = node;
for(auto &it: g[node])
{
if(viz[it] == 1)
continue;
//peuler[++nrpeuler] = costMuchii[{min(node, it), max(node, it)}];
DFS(it, dp + 1);
peuler[++nrpeuler] = node;
}
//peuler[++nrpeuler] = costMuchii[aa];
}
inline void build_rmq()
{
int i, j;
for(i = 1; i <= nrpeuler; ++i)
rmq[i][0] = peuler[i];
for(j = 1; 1 << j <= nrpeuler; ++j)
{
for(i = 1; i + (1 << j) - 1 <= nrpeuler; ++i)
{
if(depth[rmq[i][j-1]] < depth[rmq[i + (1 << (j-1))][j-1]])
rmq[i][j] = rmq[i][j-1];
else rmq[i][j] = rmq[i + (1 << (j-1))][j-1];
}
}
}
inline void build_treeRMQ()
{
int i, j;
for(i = 1; i <= n; ++i)
nodes[i][0] = father[i], treeRMQ[i][0] = costMuchii[{min(i, father[i]), max(i, father[i])}];
for(j = 1; 1 << j <= n; ++j)
{
for(i = 2; i <= n; ++i)
{
if(depth[i] - (1 << j) + 1 < 1)
{
//nodes[i][j] = -1;
continue;
}
//treeRMQ[i][j] = min(treeRMQ[i][j-1], treeRMQ[nodes[i][j-1]][j-1]);
nodes[i][j] = nodes[ nodes[i][j-1] ][j-1];
treeRMQ[i][j] = min(treeRMQ[i][j-1], treeRMQ[ nodes[i][j-1] ][j-1]);
}
}
}
inline int LCA()
{
int xx, yy;
xx = x;
yy = y;
if(firstPos[xx] > firstPos[yy])
swap(xx, yy);
int lung = log2(firstPos[yy] - firstPos[xx] + 1);
if(depth[rmq[firstPos[xx]][lung]] < depth[rmq[firstPos[yy] - (1 << lung) + 1][lung]])
return rmq[firstPos[xx]][lung];
return rmq[firstPos[yy] - (1 << lung) + 1][lung];
}
inline int toLca(int x, int lca)
{
int dist = depth[x] - depth[lca];
int sol = INT_MAX, ax;
while(dist)
{
ax = log2(dist);
sol = min(sol, treeRMQ[x][ax]);
dist -= 1 << ax;
x = nodes[x][ax];
}
return sol;
}
int main()
{
citire();
costMuchii[{0, 0}] = 0;
DFS(1, 1);
build_rmq();
build_treeRMQ();
// for(int j = 0; 1 << j <= n; ++j)
// {
// fout << j << '\n';
// for(int i = 1; i <= n; ++i)
// {
// fout << i << ' ' << nodes[i][j] << ' ' << treeRMQ[i][j] << '\n';
// }
// fout << '\n';
// }
int xx, yy, i, lca, currentAns, qq = q;
i = 0;
while(q)
{
--q;
xx = x;
yy = y;
if(x == y)
{
ans[++i] = 0;
x = newX(xx, yy);
y = newY(yy, ans[i]);
continue ;
}
lca = LCA();
currentAns = min(toLca(x, lca), toLca(y, lca));
ans[++i] = currentAns;
x = newX(xx, yy);
y = newY(yy, ans[i]);
}
for(i = qq - p + 1; i <= qq; ++i)
fout << ans[i] << '\n';
// for(int j = 0; 1 << j <= nrpeuler; ++j)
// {
// for(int i = 1; i + (1 << j) - 1 <= nrpeuler; ++i)
// fout << rmq[i][j] << ' ';
// fout << '\n';
// }
// for(int i = 1; i <= nrpeuler; ++i)
// fout << peuler[i] << ' ';
return 0;
}