// https://szkopul.edu.pl/problemset/problem/1asri4nHTSmINAOKJ-iUZf6f/site/?key=statement
// Wielki Upadek
#include <bits/stdc++.h>
struct Node {
int64_t cnt;
int64_t cost_sum;
};
const int MAX_H = 1000005;
Node tree[4 * MAX_H];
int tree_size;
void build(int node, int start, int end) {
tree[node].cnt = 0;
tree[node].cost_sum = 0;
if (start == end) return;
int mid = (start + end) / 2;
build(2 * node, start, mid);
build(2 * node + 1, mid + 1, end);
}
void update(int node, int start, int end, int idx, int op, int64_t cost) {
if (start == end) {
tree[node].cnt += op;
tree[node].cost_sum += op * cost;
return;
}
int mid = (start + end) / 2;
if (idx <= mid)
update(2 * node, start, mid, idx, op, cost);
else
update(2 * node + 1, mid + 1, end, idx, op, cost);
tree[node].cnt = tree[2 * node].cnt + tree[2 * node + 1].cnt;
tree[node].cost_sum = tree[2 * node].cost_sum + tree[2 * node + 1].cost_sum;
}
int64_t query_top_k_cost(int node, int start, int end, int64_t k) {
if (k <= 0 || tree[node].cnt == 0) return 0;
if (tree[node].cnt <= k) return tree[node].cost_sum;
if (start == end) {
int64_t single_cost = tree[node].cost_sum / tree[node].cnt;
return k * single_cost;
}
int mid = (start + end) / 2;
int64_t right_cnt = tree[2 * node + 1].cnt;
if (k <= right_cnt) {
return query_top_k_cost(2 * node + 1, mid + 1, end, k);
} else {
return tree[2 * node + 1].cost_sum + query_top_k_cost(2 * node, start, mid, k - right_cnt);
}
}
struct Domino {
int64_t x;
int h;
};
int64_t solve_one_direction(int n, const std::vector<Domino>& doms, int64_t cntBig, int hBig, int64_t cntSmall, int hSmall) {
std::vector<int> group_sizes;
std::vector<int64_t> gaps;
if (n == 0) return 0;
int current_group_size = 0;
int64_t current_reach = -2e18;
for (int i = 0; i < n; i++) {
if (i == 0) {
current_reach = doms[i].x + doms[i].h;
current_group_size = 1;
} else {
if (doms[i].x <= current_reach) {
current_reach = std::max(current_reach, doms[i].x + doms[i].h);
current_group_size++;
} else {
group_sizes.push_back(current_group_size);
gaps.push_back(doms[i].x - current_reach);
current_group_size = 1;
current_reach = doms[i].x + doms[i].h;
}
}
}
group_sizes.push_back(current_group_size);
int m = group_sizes.size();
tree_size = hBig;
build(1, 0, tree_size - 1);
int64_t max_dominoes = 0;
int64_t current_dominoes = 0;
int64_t needed_base_H = 0;
int64_t total_rem_L_cost = 0;
int R = 0;
for (int L = 0; L < m; L++) {
while (R < m) {
if (L == R) {
current_dominoes += group_sizes[R];
R++;
continue;
}
int64_t gap_len = gaps[R - 1];
int64_t base_h = gap_len / hBig;
int64_t rem = gap_len % hBig;
int64_t rem_cost_l = (rem + hSmall - 1) / hSmall;
needed_base_H += base_h;
update(1, 0, tree_size - 1, (int)rem, 1, rem_cost_l);
total_rem_L_cost += rem_cost_l;
bool possible = false;
if (cntBig >= needed_base_H) {
int64_t surplus = cntBig - needed_base_H;
int64_t saved = query_top_k_cost(1, 0, tree_size - 1, surplus);
int64_t needed_L = total_rem_L_cost - saved;
if (cntSmall >= needed_L) possible = true;
} else {
int64_t deficit = needed_base_H - cntBig;
int64_t ratio = hBig / hSmall;
if (cntSmall / ratio >= deficit) {
int64_t conversion_cost = deficit * ratio;
if (cntSmall - conversion_cost >= total_rem_L_cost) {
possible = true;
}
}
}
if (possible) {
current_dominoes += group_sizes[R];
R++;
} else {
needed_base_H -= base_h;
update(1, 0, tree_size - 1, (int)rem, -1, rem_cost_l);
total_rem_L_cost -= rem_cost_l;
break;
}
}
max_dominoes = std::max(max_dominoes, current_dominoes);
current_dominoes -= group_sizes[L];
if (R == L + 1) {
R--;
} else {
if (L < m - 1) {
int64_t gap_len = gaps[L];
int64_t base_h = gap_len / hBig;
int64_t rem = gap_len % hBig;
int64_t rem_cost_l = (rem + hSmall - 1) / hSmall;
needed_base_H -= base_h;
update(1, 0, tree_size - 1, (int)rem, -1, rem_cost_l);
total_rem_L_cost -= rem_cost_l;
}
}
}
return max_dominoes;
}
int main() {
std::ios_base::sync_with_stdio(0);
std::cin.tie(0);
std::cout.tie(0);
int n;
std::cin >> n;
std::vector<Domino> doms(n);
for (int i = 0; i < n; i++) {
std::cin >> doms[i].x >> doms[i].h;
}
int64_t N1, N2;
int H1, H2;
std::cin >> N1 >> H1 >> N2 >> H2;
int64_t cntBig, cntSmall;
int hBig, hSmall;
if (H1 >= H2) {
hBig = H1;
cntBig = N1;
hSmall = H2;
cntSmall = N2;
} else {
hBig = H2;
cntBig = N2;
hSmall = H1;
cntSmall = N1;
}
int64_t ans1 = solve_one_direction(n, doms, cntBig, hBig, cntSmall, hSmall);
std::vector<Domino> rev_doms(n);
for (int i = 0; i < n; i++) {
rev_doms[i].x = -doms[n - 1 - i].x;
rev_doms[i].h = doms[n - 1 - i].h;
}
int64_t ans2 = solve_one_direction(n, rev_doms, cntBig, hBig, cntSmall, hSmall);
int64_t ans = std::max(ans1, ans2) + N1 + N2;
std::cout << ans << std::endl;
return 0;
}