#include <iostream>
#include <vector>
#include "algotester.h"
using namespace std;
#define alpha _alpha
#define beta _beta
#define gamma _gamma
const int BILLION = 1'000'000'000;
struct ComputeUnit
{
long long u, f, d, c, e;
};
struct QueryParams
{
int N;
double tau;
vector<long long> I;
vector<long long> O;
};
int l;
int h;
long long F;
int n;
int m;
double alpha;
double beta;
double gamma;
vector<ComputeUnit> units;
vector<QueryParams> queries;
void read_test(AlgotesterReader& test)
{
l = test.readInt();
h = test.readInt();
F = test.readInt();
alpha = test.readDouble();
beta = test.readDouble();
gamma = test.readDouble();
n = test.readInt();
m = test.readInt();
for (int i = 0; i < n; i++)
{
int u = test.readInt();
long long f = test.readInt() * BILLION;
long long d = test.readInt() * BILLION;
long long c = test.readInt() * BILLION;
long long e = test.readInt() * BILLION;
units.push_back({u, f, d, c, e});
}
for (int j = 0; j < m; j++)
{
int N = test.readInt();
double tau = test.readDouble();
auto I = test.readVectorInt(N);
auto O = test.readVectorInt(N);
queries.push_back({N, tau, I, O});
}
}
vector<int> p, t, b;
vector<vector<int> > g, w;
vector<vector<int> > A;
vector<int> inst;
int P;
void read_user_output(AlgotesterReader& reader)
{
p.resize(n);
t.resize(n);
b.resize(n);
P = 0;
for (int i = 0; i < n; i++)
{
p[i] = reader.readInt();
t[i] = reader.readInt();
b[i] = reader.readInt();
P += p[i];
}
for (int i = 0; i < n; i++)
{
for (int x = 0; x < p[i]; x++)
{
inst.push_back(i);
}
}
g.resize(m);
w.resize(m);
A.resize(m);
for (int j = 0; j < m; j++)
{
g[j].resize(queries[j].N);
w[j].resize(queries[j].N);
A[j].resize(P);
for (int r = 0; r < queries[j].N; r++)
{
g[j][r] = reader.readInt();
w[j][r] = reader.readInt();
g[j][r]--;
w[j][r]--;
A[j][g[j][r]]++;
}
for (int s = 0; s < P; s++)
{
A[j][s] = (A[j][s] + b[inst[s]] - 1) / b[inst[s]];
}
}
}
int H(int a, int b)
{
return a == b;
}
double min_io()
{
double res = 1e47;
for (int j = 0; j < m; j++)
{
for (int r = 0; r < queries[j].N; r++)
{
res = min<double>(res, queries[j].I[r] + queries[j].O[r]);
}
}
return res;
}
double min_i()
{
double res = 1e47;
for (int j = 0; j < m; j++)
{
for (int r = 0; r < queries[j].N; r++)
{
res = min<double>(res, queries[j].I[r]);
}
}
return res;
}
double min_o()
{
double res = 1e47;
for (int j = 0; j < m; j++)
{
for (int r = 0; r < queries[j].N; r++)
{
res = min<double>(res, queries[j].O[r]);
}
}
return res;
}
double min_nj()
{
double res = 1e47;
for (int j = 0; j < m; j++)
{
res = min<double>(res, queries[j].N);
}
return res;
}
double max_ui()
{
double res = 0;
for (int i = 0; i < n; i++)
{
res = max<double>(res, units[i].u);
}
return res;
}
double max_fi()
{
double res = 0;
for (int i = 0; i < n; i++)
{
res = max<double>(res, units[i].f);
}
return res;
}
double L_opt()
{
double res = 2 * F / max_ui() * m * min_nj() * min_io() / (max_ui() * max_fi());
return res;
}
double L_opt_prefill()
{
double res = 2 * F / max_ui() * m * min_nj() * min_i() / (max_ui() * max_fi());
return res;
}
double L_opt_decode()
{
double res = 2 * F / max_ui() * m * min_nj() * min_o() / (max_ui() * max_fi());
return res;
}
double V_accu(int s, int j)
{
if (A[j][s] <= 1) return 0;
double res = 0;
for (int x = 0; x < A[j][s] - 1; x++)
{
double max_val = 0;
for (int r = 0; r < queries[j].N; r++)
{
double o_jr = queries[j].O[r];
double i_jr = queries[j].I[r];
double cur = o_jr * (i_jr + 0.5 * (o_jr - 1)) * H(w[j][r], x) * H(g[j][r], s);
max_val = max(max_val, cur);
}
res += max_val;
}
res *= b[inst[s]];
return res;
}
double V_last_batch(int s, int j)
{
double res = 0;
for (int r = 0; r < queries[j].N; r++)
{
res += H(w[j][r], A[j][s] - 1) * H(g[j][r], s);
}
double max_val = 0;
for (int r = 0; r < queries[j].N; r++)
{
double o_jr = queries[j].O[r];
double i_jr = queries[j].I[r];
double cur = o_jr * (i_jr + 0.5 * (o_jr - 1)) * H(w[j][r], A[j][s] - 1) * H(g[j][r], s);
max_val = max(max_val, cur);
}
res *= max_val;
return res;
}
double L_comm(int s, int j)
{
double res = 8 * l * h * (V_accu(s, j) + V_last_batch(s, j));
res /= units[inst[s]].e;
res *= (t[inst[s]] - 1) / (double)t[inst[s]];
return res;
}
double L_decode_mem_comm(int s, int j)
{
double res = 2 * F + 8 * l * h * (V_accu(s, j) + V_last_batch(s, j));
res /= t[inst[s]] * units[inst[s]].c;
return res;
}
double L_decode_comp(int s, int j)
{
double res = 2 * F / (double)t[inst[s]];
double sum = 0;
for (int r = 0; r < queries[j].N; r++)
{
sum += queries[j].O[r] * H(g[j][r], s);
}
res *= sum;
res /= units[inst[s]].f;
return res;
}
double L_prefill(int s, int j)
{
double res = 2 * F / (double)t[inst[s]];
double sum = 0;
for (int r = 0; r < queries[j].N; r++)
{
sum += queries[j].I[r] * H(g[j][r], s);
}
res *= sum;
res /= units[inst[s]].f;
return res;
}
double L(int s, int j)
{
double ls = L_prefill(s, j) + L_decode_comp(s, j) + L_decode_mem_comm(s, j) + L_comm(s, j);
return max(ls, queries[j].tau);
}
double L_decode(int s)
{
double res = 0;
for (int j = 0; j < m; j++)
{
res += L_decode_comp(s, j) + L_decode_mem_comm(s, j);
}
return res;
}
double L_prefill(int s)
{
double res = 0;
for (int j = 0; j < m; j++)
{
res += L_prefill(s, j);
}
return res;
}
double L(int s)
{
double res = 0;
for (int j = 0; j < m; j++)
{
res += L(s, j);
}
return res;
}
double L_total()
{
double res = 0;
for (int s = 0; s < P; s++)
{
res = max(res, L(s));
}
return res;
}
double L_total_prefill()
{
double res = 0;
for (int s = 0; s < P; s++)
{
res = max(res, L_prefill(s));
}
return res;
}
double L_total_decode()
{
double res = 0;
for (int s = 0; s < P; s++)
{
res = max(res, L_decode(s));
}
return res;
}
double L_first_token()
{
double res = L_total_prefill() * P;
double sum = 0;
for (int j = 0; j < m; j++)
{
sum += queries[j].N;
}
res /= sum;
return res;
}
double L_incremental_token()
{
double res = L_total_prefill() * P;
double sum = 0;
for (int j = 0; j < m; j++)
{
for (int r = 0 ; r < queries[j].N; r++)
{
sum += queries[j].O[r];
}
}
res /= sum;
return res;
}
long long get_score()
{
long long a = L_opt() * 1e7 / L_total();
long long b = L_opt_prefill() * 1e7 / L_total_prefill();
long long c = L_opt_decode() * 1e7 / L_total_decode();
long long score = a * alpha + b * beta + c * gamma;
double l_first_token_threshold = 1;
double pen_first = min(l_first_token_threshold / L_first_token(), 1.0);
double l_incremental_token_threshold = 0.05;
double pen_incremental = min(l_incremental_token_threshold / L_incremental_token(), 1.0);
score *= pen_first * pen_incremental;
return score;
}
int main(int argc, char* argv[])
{
//ios::sync_with_stdio(false); cin.tie(0);
auto readers = initChecker(argc, argv);
auto test = readers[0];
auto user = readers[1];
read_test(test);
read_user_output(user);
long long score = get_score();
cout<<score<<endl;
return 0;
}