OI XXVII - wie

// 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;
}