#include <bits/stdc++.h>

using std::cin;
using std::cout;
using std::cerr;

using std::vector;
using std::string;
using std::array;
using std::pair;
using std::make_pair;

using std::min;
using std::max;
using std::abs;

template <typename T>
T input() {
    T res;
    cin >> res;
    return res;
}

#define DO_CHECK

#ifdef DO_CHECK
#define LASSERT(x) assert(x)
#else
#define LASSERT(x) {}
#endif

#define int32_t int64_t

struct TAKING {
    int32_t x;
    int32_t a;
};

struct SELLING {
    int32_t y;
    int32_t b;
    int32_t c;
};

const int32_t MAXC = 1000 * 1000 + 3;
struct segtree_node {
    int64_t b;
    int64_t sums;

    segtree_node operator+(segtree_node other) const {
        return segtree_node {b + other.b, sums + other.sums};
    }
};

segtree_node tree[4 * MAXC];
void build() {
    std::fill(tree, tree + 4 * MAXC, segtree_node{0, 0});
}
void add(int32_t node, int32_t node_l, int32_t node_r, int32_t pos, int32_t db) {
    tree[node].sums += db * pos;
    tree[node].b += db;

    if (node_l == node_r - 1) {
        LASSERT(node_l == pos);
    } else {
        int32_t mid = node_l + (node_r - node_l) / 2;
        if (pos < mid)
            add(2 * node + 1, node_l, mid, pos, db);
        else
            add(2 * node + 2, mid, node_r, pos, db);
    }
}

segtree_node get(int32_t node, int32_t node_l, int32_t node_r, int32_t L, int32_t R) {
    if (L <= node_l and node_r <= R)
        return tree[node];
    else if (node_r <= L or R <= node_l)
        return segtree_node{0, 0};
    else {
        int32_t mid = node_l + (node_r - node_l) / 2;
        return get(2 * node + 1, node_l, mid, L, R)
                + get(2 * node + 2, mid, node_r, L, R);
    }
}

int32_t godown(int32_t node, int32_t node_l, int32_t node_r, int32_t tg_b) {
    if (node_l == node_r - 1) {
        if (tg_b == 0)
            return node_l;
        else
            return node_r;
    } else {
        int32_t mid = node_l + (node_r - node_l) / 2;
        if (tree[2 * node + 2].b >= tg_b)
            return godown(2 * node + 2, mid, node_r, tg_b);
        else
            return godown(2 * node + 1, node_l, mid, tg_b - tree[2 * node + 2].b);
    }
}

char buf[400];

void input_2(int32_t& out1, int32_t& out2) {
#ifdef LOCAL
    cin >> out1 >> out2;
#else
    fgets(buf, sizeof(buf), stdin);
    auto p_sp = std::find(buf, buf + sizeof(buf), ' ') - buf;
    buf[p_sp] = 0;
    out1 = std::atoi(buf);
    out2 = std::atoi(buf + p_sp + 1);
#endif
}

void input_3(int32_t& out1, int32_t& out2, int32_t& out3) {
#ifdef LOCAL
    cin >> out1 >> out2 >> out3;
#else
    fgets(buf, sizeof(buf), stdin);
    auto p_sp = std::find(buf, buf + sizeof(buf), ' ') - buf;
    buf[p_sp] = 0;
    auto p_sp2 = std::find(buf, buf + sizeof(buf), ' ') - buf;
    buf[p_sp2] = 0;
    out1 = std::atoi(buf);
    out2 = std::atoi(buf + p_sp + 1);
    out3 = std::atoi(buf + p_sp2 + 1);
#endif
}

int main() {
    // save with C-x C-s
    std::iostream::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);
#ifndef LOCAL
#define TASK "fisher"
    freopen(TASK ".in", "r", stdin);
    freopen(TASK ".out", "w", stdout);
#endif

    int32_t n, m, p;
    input_3(n, m, p);

    build();

    vector<int32_t> coords;
    vector<TAKING> take(n);
    for (int32_t i = 0; i != n; ++i)
        input_2(take[i].x, take[i].a), coords.push_back(take[i].x);

    vector<SELLING> sell(m);
    for (int32_t i = 0; i != m; ++i)
        input_3(sell[i].y, sell[i].b, sell[i].c), coords.push_back(sell[i].y);

    std::sort(coords.begin(), coords.end());
    coords.resize(std::unique(coords.begin(), coords.end()) - coords.begin());

    int64_t best = 0;
    int32_t p_take = 0, p_sell = 0;

    int64_t cur_fish = 0;
    for (int32_t crd: coords) {
        while (p_take != n and take[p_take].x <= crd) {
            cur_fish += take[p_take].a;
            ++p_take;
        }
        while (p_sell != m and sell[p_sell].y <= crd) {
            add(0, 0, MAXC, sell[p_sell].c, sell[p_sell].b);
            ++p_sell;
        }

        int64_t do_sell = min(cur_fish, tree[0].b);
        if (do_sell != 0) {
            int64_t cur = -p * 1ll * crd;

            int32_t r = godown(0, 0, MAXC, do_sell);

            auto res = get(0, 0, MAXC, r, MAXC);
            LASSERT(res.b <= do_sell);
            cur += res.sums;
            do_sell -= res.b;

            if (do_sell != 0) {
#ifdef DO_CHECK
                auto res2 = get(0, 0, MAXC, r - 1, r);
                LASSERT(do_sell <= res2.b);
#endif
                cur += do_sell * (r - 1);
            }

            best = max(best, cur);
        }
    }
    cout << best << "\n";
    return 0;
}