#include <fstream>
#include <vector>
using namespace std;
ifstream fin("atac.in");
ofstream fout("atac.out");
const int NMAX = 32009;
const int INF = (1 << 30);
int N; int M; int P; int X; int Y; int A; int B; int C; int D;
int T[NMAX]; int Cost[NMAX]; bool see[NMAX];int lg[NMAX];int H[20][2 * NMAX];int C_min[20][2 * NMAX];
int Euler[NMAX * 2]; int Arb[4 * NMAX];int min_ind;int Level[2 * NMAX]; int Level_nod[NMAX];
vector<pair <int, int> > G[NMAX];
int F[NMAX];
void read() {
fin >> N >> M >> P;
for(int i = 2; i <= N; ++i) {
int u, v;
fin >> u >> v;
G[i].push_back(make_pair(u, v));
G[u].push_back(make_pair(i, v));
}
fin >> X >> Y >> A >> B >> C >> D;
}
void dfs(int nod, int level) {
see[nod] = true; int cost;
Euler[++Euler[0]] = nod;
F[nod] = Euler[0];
Level[Euler[0]] = level;
Level_nod[nod] = level;
for(unsigned i = 0 ;i < G[nod].size(); ++i) {
if(see[G[nod][i].first] == false) {
T[G[nod][i].first] = nod;
Cost[G[nod][i].first] = G[nod][i].second;
dfs(G[nod][i].first, level + 1);
Euler[++Euler[0]] = nod;
Level[Euler[0]] = nod;
}
}
}
void update(int nod, int st, int dr, const int &pos) {
if(st == dr) {
Arb[nod] = pos;
return;
}
int mid = (st + dr) / 2;
if(pos <= mid) update(nod * 2, st, mid, pos);
else update(nod * 2 + 1, mid + 1, dr, pos);
Arb[nod] = Arb[nod * 2];
if(Level[Arb[nod * 2 + 1]] < Level[Arb[nod]])
Arb[nod] = Arb[nod * 2 + 1];
}
void query(int nod, int st, int dr, const int &pos_st, const int & pos_dr) {
if(pos_st <= st && dr <= pos_dr){
if(min_ind == 0 || Level[min_ind] > Level[Arb[nod]])
min_ind = Arb[nod];
return ;
}
int mid = (st + dr) / 2;
if(pos_st <= mid) query(nod * 2, st, mid, pos_st, pos_dr);
if(mid < pos_dr) query(nod * 2 + 1, mid + 1, dr, pos_st, pos_dr);
}
void rmq_arbore() {
for(int i = 2; i <= N; ++i)
lg[i] = lg[i/2] + 1;
for(int i = 0 ; i <= lg[N]; ++i)
for(int j = 1; j <= N; ++j)
C_min[i][j] = INF;
for(int i = 1; i <= N; ++i) {
H[0][i] = T[i];
C_min[0][i] = Cost[i];
}
for(int i = 1; i <= lg[N]; ++i)
for(int j = 1; j <= N; ++j) {
H[i][j] = H[i - 1][H[i - 1][j]];
C_min[i][j] = min(C_min[i - 1][j], C_min[i - 1][H[i - 1][j]]);
}
}
int query_cost(int X, int Y) {
int l1 = Level_nod[X]; int l2 = Level_nod[Y];
int min_value = (1 << 30);
while(l1 != l2) {
min_value = min(C_min[lg[l1 - l2]][X], min_value);
X = H[lg[l1 - l2]][X];
l1 = Level_nod[X];
}
return min_value;
}
int main() {
read();
dfs(1, 0);
rmq_arbore();
for(int i = 1; i <= Euler[0]; ++i)
update(1, 1, Euler[0], i);
Level[0] = (1 << 30);
int Z; int min_cost;
if(X == Y) min_cost = 0 ;
else {
min_ind = 0;
query(1, 1, Euler[0], min(F[X], F[Y]), max(F[Y], F[X]));
min_cost = min(query_cost(X, min_ind), query_cost(Y, min_ind));
}
X = (X * A + Y * B) % N + 1;
Y = (Y * C + min_cost * D) % N + 1;
for(int i = 2; i <= M; ++i) {
X = (X * A + Y * B) % N + 1;
Y = (Y * C + min_cost * D) % N + 1;
if(X == Y)
min_cost = 0;
else {
min_ind = 0;
query(1, 1, Euler[0], min(F[X], F[Y]), max(F[Y], F[X]));
min_cost = min(query_cost(X, Euler[min_ind]), query_cost(Y, Euler[min_ind]));
if(i >= M - P)
fout << min_cost <<'\n';
}
}
return 0;
}