/**
 * @author khokharnikunj8
 */

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

using namespace std;

template<typename T>
void read(T &t) {
    t = 0;
    char ch = getchar();
    int f = 1;
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    do {
        (t *= 10) += ch - '0';
        ch = getchar();
    } while ('0' <= ch && ch <= '9');
    t *= f;
}
struct ele {
    int x, val;
    friend bool operator < (const ele &a, const ele &b) {
        return a.x < b.x;
    }
} attack[100005 << 1], defense[100005 << 1];

struct pp {
    int x, y, z;
    friend bool operator < (const pp &a, const pp &b) {
        return a.x < b.x;
    }
} monster[100005 << 1];

int tempDefense[1000001];

struct SegmentTree {
public:
    long long val[1000005 << 2];
    int tag[1000005 << 2];

    void pu(int u) {
        val[u] = max(val[u << 1], val[(u << 1 | 1)]);
    }

    void pushdown(int u) {
        if (tag[u]) {
            val[u << 1] += tag[u], tag[u << 1] += tag[u];
            val[(u << 1 | 1)] += tag[u], tag[(u << 1 | 1)] += tag[u];
            tag[u] = 0;
        }
    }

    void build(int u, int l, int r) {
        if (l == r) {
            if (!tempDefense[l]) {
                val[u] = -1e18;
            } else {
                val[u] = -tempDefense[l];
            }
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build((u << 1 | 1), mid + 1, r);
        pu(u);
    }

    void update(int u, int l, int r, int ql, int qr, int x) {
        if (l > r || ql > qr) {
            return;
        }
        if (ql <= l && r <= qr) {
            tag[u] += x, val[u] += x;
            return;
        }
        pushdown(u);
        int mid = l + r >> 1;
        if (ql <= mid) update(u << 1, l, mid, ql, qr, x);
        if (qr > mid) update((u << 1 | 1), mid + 1, r, ql, qr, x);
        pu(u);
    }
};

int main() {
    int n, m, p;
    read(n);
    read(m);
    read(p);
    for (int i = 0; i < n; i++) read(attack[i].x), read(attack[i].val);
    for (int i = 0; i < m; i++) read(defense[i].x), read(defense[i].val);
    for (int i = 0; i < p; i++)
        read(monster[i].x), read(monster[i].y), read(monster[i].z);
    sort(attack, attack + n);
    sort(defense, defense + m);
    sort(monster, monster + p);
    for (int i = 0; i < m; i++) {
        if (!tempDefense[defense[i].x] || defense[i].val < tempDefense[defense[i].x]) {
            tempDefense[defense[i].x] = defense[i].val;
        }
    }
    SegmentTree smt;
    smt.build(1, 1, 1000000);
    int pointerC = 0;
    long long ans = LLONG_MIN;
    for (int i = 0; i < n; i++) {
        while (pointerC < p && monster[pointerC].x < attack[i].x) {
            smt.update(1, 1, 1000000, monster[pointerC].y + 1, 1000000,
                       monster[pointerC].z);
            pointerC++;
        }
        ans = max(ans, smt.val[1] - attack[i].val);
    }
    printf("%lld\n", ans);
    return 0;
}


/**
 * @author khokharnikunj8
 */

#pragma GCC optimize(2)
#pragma GCC optimize(3)
#include <bits/stdc++.h>

using namespace std;

template<typename T>
void read(T &t) {
    t = 0;
    char ch = getchar();
    int f = 1;
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    do {
        (t *= 10) += ch - '0';
        ch = getchar();
    } while ('0' <= ch && ch <= '9');
    t *= f;
}
struct ele {
    int x, val;
    friend bool operator < (const ele &a, const ele &b) {
        return a.x < b.x;
    }
} attack[100005 << 1], defense[100005 << 1];

struct pp {
    int x, y, z;
    friend bool operator < (const pp &a, const pp &b) {
        return a.x < b.x;
    }
} monster[100005 << 1];

int tempDefense[1000001];

struct SegmentTree {
public:
    long long val[1000005 << 2];
    int tag[1000005 << 2];

    void pu(int u) {
        val[u] = max(val[u << 1], val[(u << 1 | 1)]);
    }

    void pushdown(int u) {
        if (tag[u]) {
            val[u << 1] += tag[u], tag[u << 1] += tag[u];
            val[(u << 1 | 1)] += tag[u], tag[(u << 1 | 1)] += tag[u];
            tag[u] = 0;
        }
    }

    void build(int u, int l, int r) {
        if (l == r) {
            if (!tempDefense[l]) {
                val[u] = -1e18;
            } else {
                val[u] = -tempDefense[l];
            }
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build((u << 1 | 1), mid + 1, r);
        pu(u);
    }

    void update(int u, int l, int r, int ql, int qr, int x) {
        if (l > r || ql > qr) {
            return;
        }
        if (ql <= l && r <= qr) {
            tag[u] += x, val[u] += x;
            return;
        }
        pushdown(u);
        int mid = l + r >> 1;
        if (ql <= mid) update(u << 1, l, mid, ql, qr, x);
        if (qr > mid) update((u << 1 | 1), mid + 1, r, ql, qr, x);
        pu(u);
    }
};

int main() {
    int n, m, p;
    read(n);
    read(m);
    read(p);
    for (int i = 0; i < n; i++) read(attack[i].x), read(attack[i].val);
    for (int i = 0; i < m; i++) read(defense[i].x), read(defense[i].val);
    for (int i = 0; i < p; i++)
        read(monster[i].x), read(monster[i].y), read(monster[i].z);
    sort(attack, attack + n);
    sort(defense, defense + m);
    sort(monster, monster + p);
    for (int i = 0; i < m; i++) {
        if (!tempDefense[defense[i].x] || defense[i].val < tempDefense[defense[i].x]) {
            tempDefense[defense[i].x] = defense[i].val;
        }
    }
    SegmentTree smt;
    smt.build(1, 1, 1000000);
    int pointerC = 0;
    long long ans = LLONG_MIN;
    for (int i = 0; i < n; i++) {
        while (pointerC < p && monster[pointerC].x < attack[i].x) {
            smt.update(1, 1, 1000000, monster[pointerC].y + 1, 1000000,
                       monster[pointerC].z);
            pointerC++;
        }
        ans = max(ans, smt.val[1] - attack[i].val);
    }
    printf("%lld\n", ans);
    return 0;
}


/**
 * @author khokharnikunj8
 */

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

using namespace std;

const int N = 1000005;
int t[N << 1];
int d[N];
const int h = sizeof(int) * 8 - __builtin_clz(N);

inline void apply(int p, int value) {
    t[p] += value;
    if (p < N) d[p] += value;
}

inline void build(int p) {
    while (p > 1) p >>= 1, t[p] = max(t[p << 1], t[p << 1 | 1]) + d[p];
}

inline void push(int p) {
    for (int s = h; s > 0; --s) {
        int i = p >> s;
        if (d[i] != 0) {
            apply(i << 1, d[i]);
            apply(i << 1 | 1, d[i]);
            d[i] = 0;
        }
    }
}

inline void inc(int l, int r, int value) {
    l += N, r += N;
    int l0 = l, r0 = r;
    for (; l < r; l >>= 1, r >>= 1) {
        if (l & 1) apply(l++, value);
        if (r & 1) apply(--r, value);
    }
    build(l0);
    build(r0 - 1);
}

inline int query(int l, int r) {
    l += N, r += N;
    push(l);
    push(r - 1);
    int res = -2e9;
    for (; l < r; l >>= 1, r >>= 1) {
        if (l & 1) res = max(res, t[l++]);
        if (r & 1) res = max(t[--r], res);
    }
    return res;
}

class CWorldOfDarkraftBattleForAzathoth {
public:

    void solve(std::istream &in, std::ostream &out) {
        int n, m, p;
        in >> n >> m >> p;
        vector<pair<int, int>> attack(n, {-1, -1});
        vector<pair<int, int>> defense(m, {-1, -1});
        vector<pair<int, pair<int, int>>> monster(p, {-1, {-1, -1}});
        for (int i = 0; i < n; i++) in >> attack[i].first >> attack[i].second;
        for (int i = 0; i < m; i++) in >> defense[i].first >> defense[i].second;
        for (int i = 0; i < p; i++) in >> monster[i].first >> monster[i].second.first >> monster[i].second.second;
        sort(attack.begin(), attack.end());
        sort(defense.begin(), defense.end());
        sort(monster.begin(), monster.end());
        vector<int> tempDefense(1000005, 2e9);
        for (int i = 0; i < m; i++) {
            if (defense[i].second < tempDefense[defense[i].first]) {
                tempDefense[defense[i].first] = defense[i].second;
            }
        }
        for (int i = 0; i < 1000005; i++) inc(i, i + 1, -tempDefense[i]);
        int pointerC = 0;
        int ans = INT32_MIN;
        for (int i = 0; i < n; i++) {
            while (pointerC < p && monster[pointerC].first < attack[i].first) {
                inc(monster[pointerC].second.first + 1, 1000000 + 1,
                    monster[pointerC].second.second);
                pointerC++;
            }
            ans = max(ans, query(0, 1000001) - attack[i].second);
        }
        out << ans << "\n";
    }

};

int main() {
    CWorldOfDarkraftBattleForAzathoth solver;
    std::ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    std::istream &in(std::cin);
    std::ostream &out(std::cout);
    solver.solve(in, out);
    return 0;
}


/**
 * @author khokharnikunj8
 */

#pragma comment(linker, "/stack:200000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")

#include <bits/stdc++.h>

using namespace std;

template<typename T>
void read(T &t) {
    t = 0;
    char ch = getchar();
    int f = 1;
    while (ch < '0' || ch > '9') {
        if (ch == '-') f = -1;
        ch = getchar();
    }
    do {
        (t *= 10) += ch - '0';
        ch = getchar();
    } while ('0' <= ch && ch <= '9');
    t *= f;
}

pair<int, int> attack[100005 << 1];
pair<int, int> defense[100005 << 1];
pair<int, pair<int, int>> monster[100005 << 1];
int tempDefense[1000001];

struct SegmentTree {
public:
    long long val[1000005 << 2];
    int tag[1000005 << 2];

    void pu(int u) {
        val[u] = max(val[u << 1], val[(u << 1 | 1)]);
    }

    void pushdown(int u) {
        if (tag[u]) {
            val[u << 1] += tag[u], tag[u << 1] += tag[u];
            val[(u << 1 | 1)] += tag[u], tag[(u << 1 | 1)] += tag[u];
            tag[u] = 0;
        }
    }

    void build(int u, int l, int r) {
        if (l == r) {
            if (!tempDefense[l]) {
                val[u] = -1e18;
            } else {
                val[u] = -tempDefense[l];
            }
            return;
        }
        int mid = l + r >> 1;
        build(u << 1, l, mid);
        build((u << 1 | 1), mid + 1, r);
        pu(u);
    }

    void update(int u, int l, int r, int ql, int qr, int x) {
        if (l > r || ql > qr) {
            return;
        }
        if (ql <= l && r <= qr) {
            tag[u] += x, val[u] += x;
            return;
        }
        pushdown(u);
        int mid = l + r >> 1;
        if (ql <= mid) update(u << 1, l, mid, ql, qr, x);
        if (qr > mid) update((u << 1 | 1), mid + 1, r, ql, qr, x);
        pu(u);
    }
};

int main() {
    int n, m, p;
    read(n);
    read(m);
    read(p);
    for (int i = 0; i < n; i++) read(attack[i].first), read(attack[i].second);
    for (int i = 0; i < m; i++) read(defense[i].first), read(defense[i].second);
    for (int i = 0; i < p; i++)
        read(monster[i].first), read(monster[i].second.first), read(monster[i].second.second);
    sort(attack, attack + n);
    sort(defense, defense + m);
    sort(monster, monster + p);
    for (int i = 0; i < m; i++) {
        if (!tempDefense[defense[i].first] || defense[i].second < tempDefense[defense[i].first]) {
            tempDefense[defense[i].first] = defense[i].second;
        }
    }
    SegmentTree smt;
    smt.build(1, 1, 1000000);
    int pointerC = 0;
    long long ans = LLONG_MIN;
    for (int i = 0; i < n; i++) {
        while (pointerC < p && monster[pointerC].first < attack[i].first) {
            smt.update(1, 1, 1000000, monster[pointerC].second.first + 1, 1000000,
                       monster[pointerC].second.second);
            pointerC++;
        }
        ans = max(ans, smt.val[1] - attack[i].second);
    }
    printf("%lld\n", ans);
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define inf 1000000000
#define inf_ull 1000000000000000000
#define ll long long
#define ull unsigned long long

// these to_string headers are taken from tourist on codeforces

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
    return '"' + s + '"';
}

string to_string(const char* s) {
    return to_string((string) s);
}

string to_string(bool b) {
    return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
    bool first = true;
    string res = "{";
    for (int i = 0; i < static_cast<int>(v.size()); i++) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}

// #define DEBUG

#ifdef DEBUG
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
ifstream fin("input.in");
#else
#define debug(...)
#define fin cin
#endif

template<typename T, T update_func(T, T), T query_func(T, T), T update_identity, T query_identity>
struct segtree {

    int length, true_size;
    vector<T> tree, updates;
    vector<bool> insertflag;

    segtree(int s) {
        true_size = s;
        length = pow(2, ceil(log2(s)));
        tree = vector<T>(2*length, query_identity);
        updates = vector<T>(2*length, update_identity);
        insertflag = vector<bool>(2*length, 0);
    }

    segtree(vector<T>& v) : segtree(v.size()) {
        for (int i = 0; i < v.size(); i++)
            tree[length+i] = v[i];
        for (int i = length-1; i > 0; i--)
            tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void propogate(int i) {
        T val = updates[i];
        if (insertflag[i]) {
            if (i < length) {
                updates[2*i] = val;
                updates[2*i+1] = val;
                insertflag[2*i] = insertflag[2*i+1] = 1;
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = val;
            insertflag[i] = 0;
        } else {
            if (i < length) {
                updates[2*i] = update_func(updates[2*i], val);
                updates[2*i+1] = update_func(updates[2*i+1], val);
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = update_func(tree[i], val);
        }
        updates[i] = update_identity;
    }

    T get_r(int j, int i, int lower, int upper) {
        propogate(i);
        if (lower == upper)
            return tree[i];
        int mid = (lower+upper)/2;
        if (j > mid)
            return get_r(j, 2*i+1, mid+1, upper);
        return get_r(j, 2*i, lower, mid);
    }

    void update_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper)
            updates[i] = update_func(updates[i], val);
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        update_r(a, b, val, 2*i, lower, mid);
        update_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void set_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper) {
            updates[i] = val;
            insertflag[i] = 1;
        }
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        set_r(a, b, val, 2*i, lower, mid);
        set_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    T range_r(int a, int b, int i, int lower, int upper) {
        propogate(i);
        if (b < lower || a > upper)
            return query_identity;
        if (a <= lower && b >= upper)
            return tree[i];
        int mid = (lower+upper)/2;
        return query_func(range_r(a, b, 2*i, lower, mid), range_r(a, b, 2*i+1, mid+1, upper));
    }

    struct iterator {
        T* ptr;
        iterator(T* p): ptr(p) {}
        iterator operator++() { ++ptr; return *this; }
        bool operator!=(const iterator& other) const { return ptr != other.ptr; }
        const T& operator*() const { return *ptr; }
    };
    iterator begin() { // don't call this directly, it's just for the foreach loop
        flush();
        return iterator(&tree[length]);
    }
    iterator end() { return iterator(&tree[length+true_size-1]+1); }

    inline int size() { return true_size; }

    // perform all updates so that tree[length .. 2*length-1] holds true data
    inline void flush() {
        for (int i = 0; i < 2*length; i++)
            propogate(i);
    }

    // gets value at index i
    inline T get(int i) { return get_r(i, 1, 0, length-1); }
    inline T operator[](int i) { return get(i); }

    // sets every element x in [a..b] to F(x, val)
    inline void update(int a, int b, T val) { update_r(a, b, val, 1, 0, length-1); }

    // sets every element in [a..b] to val
    inline void set(int a, int b, T val) { set_r(a, b, val, 1, 0, length-1); }

    // computes F over the range [a..b]
    inline T query(int a, int b) { return range_r(a, b, 1, 0, length-1); }
};

// segtree<type, update_func, query_func, update_identity, query_identity>

template<typename T>
int bs_index(const vector<T>& A, T x) {

    int a = 0, b = A.size()-1;
    while (a <= b) {
        int m = (a+b)/2;
        if (x > A[m])
            a = m+1;
        else
            b = m-1;
    }
    return a;
}

int sum(int a, int b) { return a+b; }
int _max(int a, int b) { return max(a, b); }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N, M, P;
    fin >> N >> M >> P;
    vector<array<int, 4>> data(P);
    vector<array<int, 2>> weapon(N), armor(M);
    for (auto& x : weapon)
        fin >> x[0] >> x[1];
    for (auto& x : armor)
        fin >> x[0] >> x[1];
    for (auto& x : data) {
        x[1] = 1;
        fin >> x[0] >> x[2] >> x[3];
    }

    sort(weapon.begin(), weapon.end());
    for (auto&x : armor)
        data.push_back({x[0], 0, 0, x[1]});

    segtree<int, sum, _max, 0, -inf> S(N);
    for (int i = 0; i < N; i++)
        S.set(i, i, -weapon[i][1]);

    // debug(S);

    int out = 0;
    sort(data.begin(), data.end());
    for (auto& x : data) {
        int a = x[0], t = x[1], w = x[2], c = x[3];
        if (t == 1) {
            S.update(bs_index(weapon, {w+1, -inf}), N-1, c);
        } else {
            out = max(out, S.query(0, N-1) - c);
        }
    }

    cout << out << "\n";
}


#include <bits/stdc++.h>
using namespace std;

#define inf 1000000000
#define inf_ull 1000000000000000000
#define ll long long
#define ull unsigned long long

// these to_string headers are taken from tourist on codeforces

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
    return '"' + s + '"';
}

string to_string(const char* s) {
    return to_string((string) s);
}

string to_string(bool b) {
    return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
    bool first = true;
    string res = "{";
    for (int i = 0; i < static_cast<int>(v.size()); i++) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}

// #define DEBUG

#ifdef DEBUG
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
ifstream fin("input.in");
#else
#define debug(...)
#define fin cin
#endif

template<typename T, T update_func(T, T), T query_func(T, T), T update_identity, T query_identity>
struct segtree {

    int length, true_size;
    vector<T> tree, updates;
    vector<bool> insertflag;

    segtree(int s) {
        true_size = s;
        length = pow(2, ceil(log2(s)));
        tree = vector<T>(2*length, query_identity);
        updates = vector<T>(2*length, update_identity);
        insertflag = vector<bool>(2*length, 0);
    }

    segtree(vector<T>& v) : segtree(v.size()) {
        for (int i = 0; i < v.size(); i++)
            tree[length+i] = v[i];
        for (int i = length-1; i > 0; i--)
            tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void propogate(int i) {
        T val = updates[i];
        if (insertflag[i]) {
            if (i < length) {
                updates[2*i] = val;
                updates[2*i+1] = val;
                insertflag[2*i] = insertflag[2*i+1] = 1;
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = val;
            insertflag[i] = 0;
        } else {
            if (i < length) {
                updates[2*i] = update_func(updates[2*i], val);
                updates[2*i+1] = update_func(updates[2*i+1], val);
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = update_func(tree[i], val);
        }
        updates[i] = update_identity;
    }

    T get_r(int j, int i, int lower, int upper) {
        propogate(i);
        if (lower == upper)
            return tree[i];
        int mid = (lower+upper)/2;
        if (j > mid)
            return get_r(j, 2*i+1, mid+1, upper);
        return get_r(j, 2*i, lower, mid);
    }

    void update_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper)
            updates[i] = update_func(updates[i], val);
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        update_r(a, b, val, 2*i, lower, mid);
        update_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void set_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper) {
            updates[i] = val;
            insertflag[i] = 1;
        }
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        set_r(a, b, val, 2*i, lower, mid);
        set_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    T range_r(int a, int b, int i, int lower, int upper) {
        propogate(i);
        if (b < lower || a > upper)
            return query_identity;
        if (a <= lower && b >= upper)
            return tree[i];
        int mid = (lower+upper)/2;
        return query_func(range_r(a, b, 2*i, lower, mid), range_r(a, b, 2*i+1, mid+1, upper));
    }

    struct iterator {
        T* ptr;
        iterator(T* p): ptr(p) {}
        iterator operator++() { ++ptr; return *this; }
        bool operator!=(const iterator& other) const { return ptr != other.ptr; }
        const T& operator*() const { return *ptr; }
    };
    iterator begin() { // don't call this directly, it's just for the foreach loop
        flush();
        return iterator(&tree[length]);
    }
    iterator end() { return iterator(&tree[length+true_size-1]+1); }

    inline int size() { return true_size; }

    // perform all updates so that tree[length .. 2*length-1] holds true data
    inline void flush() {
        for (int i = 0; i < 2*length; i++)
            propogate(i);
    }

    // gets value at index i
    inline T get(int i) { return get_r(i, 1, 0, length-1); }
    inline T operator[](int i) { return get(i); }

    // sets every element x in [a..b] to F(x, val)
    inline void update(int a, int b, T val) { update_r(a, b, val, 1, 0, length-1); }

    // sets every element in [a..b] to val
    inline void set(int a, int b, T val) { set_r(a, b, val, 1, 0, length-1); }

    // computes F over the range [a..b]
    inline T query(int a, int b) { return range_r(a, b, 1, 0, length-1); }
};

// segtree<type, update_func, query_func, update_identity, query_identity>

template<typename T>
int bs_index(const vector<T>& A, T x) {

    int a = 0, b = A.size()-1;
    while (a <= b) {
        int m = (a+b)/2;
        if (x > A[m])
            a = m+1;
        else
            b = m-1;
    }
    return a;
}

int sum(int a, int b) { return a+b; }
int _max(int a, int b) { return max(a, b); }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N, M, P;
    fin >> N >> M >> P;
    vector<array<int, 4>> data(P);
    vector<array<int, 2>> weapon(N), armor(M);
    for (auto& x : weapon)
        fin >> x[0] >> x[1];
    for (auto& x : armor)
        fin >> x[0] >> x[1];
    for (auto& x : data) {
        x[1] = 1;
        fin >> x[0] >> x[2] >> x[3];
    }

    sort(weapon.begin(), weapon.end());
    for (auto&x : armor)
        data.push_back({x[0], 0, 0, x[1]});

    segtree<int, sum, _max, 0, -inf> S(N);
    for (int i = 0; i < N; i++)
        S.set(i, i, -weapon[i][1]);

    // debug(S);

    int out = -inf;
    sort(data.begin(), data.end());
    for (auto& x : data) {
        int a = x[0], t = x[1], w = x[2], c = x[3];
        if (t == 1) {
            S.update(bs_index(weapon, {w+1, -inf}), N-1, c);
        } else {
            out = max(out, S.query(0, N-1) - c);
        }
    }

    cout << out << "\n";
}


#include <bits/stdc++.h>
using namespace std;

#define inf 1000000000
#define inf_ull 1000000000000000000
#define ll long long
#define ull unsigned long long

// these to_string headers are taken from tourist on codeforces

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
    return '"' + s + '"';
}

string to_string(const char* s) {
    return to_string((string) s);
}

string to_string(bool b) {
    return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
    bool first = true;
    string res = "{";
    for (int i = 0; i < static_cast<int>(v.size()); i++) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}

// #define DEBUG

#ifdef DEBUG
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
ifstream fin("input.in");
#else
#define debug(...)
#define fin cin
#endif

template<typename T, T update_func(T, T), T query_func(T, T), T update_identity, T query_identity>
struct segtree {

    int length, true_size;
    vector<T> tree, updates;
    vector<bool> insertflag;

    segtree(int s) {
        true_size = s;
        length = pow(2, ceil(log2(s)));
        tree = vector<T>(2*length, query_identity);
        updates = vector<T>(2*length, update_identity);
        insertflag = vector<bool>(2*length, 0);
    }

    segtree(vector<T>& v) : segtree(v.size()) {
        for (int i = 0; i < v.size(); i++)
            tree[length+i] = v[i];
        for (int i = length-1; i > 0; i--)
            tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void propogate(int i) {
        T val = updates[i];
        if (insertflag[i]) {
            if (i < length) {
                updates[2*i] = val;
                updates[2*i+1] = val;
                insertflag[2*i] = insertflag[2*i+1] = 1;
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = val;
            insertflag[i] = 0;
        } else {
            if (i < length) {
                updates[2*i] = update_func(updates[2*i], val);
                updates[2*i+1] = update_func(updates[2*i+1], val);
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = update_func(tree[i], val);
        }
        updates[i] = update_identity;
    }

    T get_r(int j, int i, int lower, int upper) {
        propogate(i);
        if (lower == upper)
            return tree[i];
        int mid = (lower+upper)/2;
        if (j > mid)
            return get_r(j, 2*i+1, mid+1, upper);
        return get_r(j, 2*i, lower, mid);
    }

    void update_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper)
            updates[i] = update_func(updates[i], val);
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        update_r(a, b, val, 2*i, lower, mid);
        update_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void set_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper) {
            updates[i] = val;
            insertflag[i] = 1;
        }
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        set_r(a, b, val, 2*i, lower, mid);
        set_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    T range_r(int a, int b, int i, int lower, int upper) {
        propogate(i);
        if (b < lower || a > upper)
            return query_identity;
        if (a <= lower && b >= upper)
            return tree[i];
        int mid = (lower+upper)/2;
        return query_func(range_r(a, b, 2*i, lower, mid), range_r(a, b, 2*i+1, mid+1, upper));
    }

    struct iterator {
        T* ptr;
        iterator(T* p): ptr(p) {}
        iterator operator++() { ++ptr; return *this; }
        bool operator!=(const iterator& other) const { return ptr != other.ptr; }
        const T& operator*() const { return *ptr; }
    };
    iterator begin() { // don't call this directly, it's just for the foreach loop
        flush();
        return iterator(&tree[length]);
    }
    iterator end() { return iterator(&tree[length+true_size-1]+1); }

    inline int size() { return true_size; }

    // perform all updates so that tree[length .. 2*length-1] holds true data
    inline void flush() {
        for (int i = 0; i < 2*length; i++)
            propogate(i);
    }

    // gets value at index i
    inline T get(int i) { return get_r(i, 1, 0, length-1); }
    inline T operator[](int i) { return get(i); }

    // sets every element x in [a..b] to F(x, val)
    inline void update(int a, int b, T val) { update_r(a, b, val, 1, 0, length-1); }

    // sets every element in [a..b] to val
    inline void set(int a, int b, T val) { set_r(a, b, val, 1, 0, length-1); }

    // computes F over the range [a..b]
    inline T query(int a, int b) { return range_r(a, b, 1, 0, length-1); }
};

// segtree<type, update_func, query_func, update_identity, query_identity>

template<typename T>
int bs_index(const vector<T>& A, T x) {

    int a = 0, b = A.size()-1;
    while (a <= b) {
        int m = (a+b)/2;
        if (x > A[m])
            a = m+1;
        else
            b = m-1;
    }
    return a;
}

int sum(int a, int b) { return a+b; }
int _max(int a, int b) { return max(a, b); }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    int N, M, P;
    fin >> N >> M >> P;
    vector<array<int, 4>> data(P);
    vector<array<int, 2>> weapon(N), armor(M);
    for (auto& x : weapon)
        fin >> x[0] >> x[1];
    for (auto& x : armor)
        fin >> x[0] >> x[1];
    for (auto& x : data) {
        x[1] = 1;
        fin >> x[2] >> x[0] >> x[3];
    }

    sort(weapon.begin(), weapon.end());
    for (auto&x : armor)
        data.push_back({x[0], 0, 0, x[1]});

    segtree<int, sum, _max, 0, -inf> S(N);
    for (int i = 0; i < N; i++)
        S.set(i, i, -weapon[i][1]);

    debug(S);

    int out = -inf;
    sort(data.begin(), data.end());
    for (auto& x : data) {
        int a = x[0], t = x[1], w = x[2], c = x[3];
        debug(x);
        if (t == 1) {
            S.update(bs_index(weapon, {w+1, -inf}), N-1, c);
            debug(S);
        } else {
            out = max(out, S.query(0, N-1) - c);
        }
    }

    cout << out << "\n";
}


#include <bits/stdc++.h>
using namespace std;

#define inf 1000000000
#define inf_ull 1000000000000000000
#define ll long long
#define ull unsigned long long

// these to_string headers are taken from tourist on codeforces

template <typename A, typename B>
string to_string(pair<A, B> p);

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p);

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p);

string to_string(const string& s) {
    return '"' + s + '"';
}

string to_string(const char* s) {
    return to_string((string) s);
}

string to_string(bool b) {
    return (b ? "true" : "false");
}

string to_string(vector<bool> v) {
    bool first = true;
    string res = "{";
    for (int i = 0; i < static_cast<int>(v.size()); i++) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(v[i]);
    }
    res += "}";
    return res;
}

template <typename A>
string to_string(A v) {
    bool first = true;
    string res = "{";
    for (const auto &x : v) {
        if (!first) {
            res += ", ";
        }
        first = false;
        res += to_string(x);
    }
    res += "}";
    return res;
}

template <typename A, typename B>
string to_string(pair<A, B> p) {
    return "(" + to_string(p.first) + ", " + to_string(p.second) + ")";
}

template <typename A, typename B, typename C>
string to_string(tuple<A, B, C> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ")";
}

template <typename A, typename B, typename C, typename D>
string to_string(tuple<A, B, C, D> p) {
    return "(" + to_string(get<0>(p)) + ", " + to_string(get<1>(p)) + ", " + to_string(get<2>(p)) + ", " + to_string(get<3>(p)) + ")";
}

void debug_out() { cerr << endl; }

template <typename Head, typename... Tail>
void debug_out(Head H, Tail... T) {
    cerr << " " << to_string(H);
    debug_out(T...);
}

// #define DEBUG

#ifdef DEBUG
#define debug(...) cerr << "[" << #__VA_ARGS__ << "]:", debug_out(__VA_ARGS__)
ifstream fin("input.in");
#else
#define debug(...)
#define fin cin
#endif

template<typename T, T update_func(T, T), T query_func(T, T), T update_identity, T query_identity>
struct segtree {

    int length, true_size;
    vector<T> tree, updates;
    vector<bool> insertflag;

    segtree(int s) {
        true_size = s;
        length = pow(2, ceil(log2(s)));
        tree = vector<T>(2*length, query_identity);
        updates = vector<T>(2*length, update_identity);
        insertflag = vector<bool>(2*length, 0);
    }

    segtree(vector<T>& v) : segtree(v.size()) {
        for (int i = 0; i < v.size(); i++)
            tree[length+i] = v[i];
        for (int i = length-1; i > 0; i--)
            tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void propogate(int i) {
        T val = updates[i];
        if (insertflag[i]) {
            if (i < length) {
                updates[2*i] = val;
                updates[2*i+1] = val;
                insertflag[2*i] = insertflag[2*i+1] = 1;
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = val;
            insertflag[i] = 0;
        } else {
            if (i < length) {
                updates[2*i] = update_func(updates[2*i], val);
                updates[2*i+1] = update_func(updates[2*i+1], val);
                // // generalized multiplication in logn time -- UNCOMMENT
                // for (int m = length; m > i; m /= 2)
                //  val = query_func(val, val);
            }
            tree[i] = update_func(tree[i], val);
        }
        updates[i] = update_identity;
    }

    T get_r(int j, int i, int lower, int upper) {
        propogate(i);
        if (lower == upper)
            return tree[i];
        int mid = (lower+upper)/2;
        if (j > mid)
            return get_r(j, 2*i+1, mid+1, upper);
        return get_r(j, 2*i, lower, mid);
    }

    void update_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper)
            updates[i] = update_func(updates[i], val);
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        update_r(a, b, val, 2*i, lower, mid);
        update_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    void set_r(int a, int b, T val, int i, int lower, int upper) {
        if (a <= lower && b >= upper) {
            updates[i] = val;
            insertflag[i] = 1;
        }
        propogate(i);
        if (b < lower || a > upper || (a <= lower && b >= upper))
            return;
        int mid = (lower+upper)/2;
        set_r(a, b, val, 2*i, lower, mid);
        set_r(a, b, val, 2*i+1, mid+1, upper);
        tree[i] = query_func(tree[2*i], tree[2*i+1]);
    }

    T range_r(int a, int b, int i, int lower, int upper) {
        propogate(i);
        if (b < lower || a > upper)
            return query_identity;
        if (a <= lower && b >= upper)
            return tree[i];
        int mid = (lower+upper)/2;
        return query_func(range_r(a, b, 2*i, lower, mid), range_r(a, b, 2*i+1, mid+1, upper));
    }

    struct iterator {
        T* ptr;
        iterator(T* p): ptr(p) {}
        iterator operator++() { ++ptr; return *this; }
        bool operator!=(const iterator& other) const { return ptr != other.ptr; }
        const T& operator*() const { return *ptr; }
    };
    iterator begin() { // don't call this directly, it's just for the foreach loop
        flush();
        return iterator(&tree[length]);
    }
    iterator end() { return iterator(&tree[length+true_size-1]+1); }

    inline int size() { return true_size; }

    // perform all updates so that tree[length .. 2*length-1] holds true data
    inline void flush() {
        for (int i = 0; i < 2*length; i++)
            propogate(i);
    }

    // gets value at index i
    inline T get(int i) { return get_r(i, 1, 0, length-1); }
    inline T operator[](int i) { return get(i); }

    // sets every element x in [a..b] to F(x, val)
    inline void update(int a, int b, T val) { update_r(a, b, val, 1, 0, length-1); }

    // sets every element in [a..b] to val
    inline void set(int a, int b, T val) { set_r(a, b, val, 1, 0, length-1); }

    // computes F over the range [a..b]
    inline T query(int a, int b) { return range_r(a, b, 1, 0, length-1); }
};

// segtree<type, update_func, query_func, update_identity, query_identity>

template<typename T>
int bs_index(const vector<T>& A, T x) {

    int a = 0, b = A.size()-1;
    while (a <= b) {
        int m = (a+b)/2;
        if (x > A[m])
            a = m+1;
        else
            b = m-1;
    }
    return a;
}

ll sum(ll a, ll b) { return a+b; }
ll _max(ll a, ll b) { return max(a, b); }

int main() {
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    ll N, M, P;
    fin >> N >> M >> P;
    vector<array<ll, 4>> data(P);
    vector<array<ll, 2>> weapon(N), armor(M);
    for (auto& x : weapon)
        fin >> x[0] >> x[1];
    for (auto& x : armor)
        fin >> x[0] >> x[1];
    for (auto& x : data) {
        x[1] = 1;
        fin >> x[2] >> x[0] >> x[3];
    }

    sort(weapon.begin(), weapon.end());
    for (auto&x : armor)
        data.push_back({x[0], 0, 0, x[1]});

    segtree<ll, sum, _max, 0, -inf> S(N);
    for (int i = 0; i < N; i++)
        S.set(i, i, -weapon[i][1]);

    debug(S);

    ll out = -inf_ull;
    sort(data.begin(), data.end());
    for (auto& x : data) {
        ll a = x[0], t = x[1], w = x[2], c = x[3];
        debug(x);
        if (t == 1) {
            S.update(bs_index(weapon, {w+1, -inf}), N-1, c);
            debug(S);
        } else {
            out = max(out, S.query(0, N-1) - c);
        }
    }

    cout << out << "\n";
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = 2e5 + 5;

vector < ll > t (4 * N), lazy(4 * N);

void build (vector < pair < int, int > > &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = -a[tl].second;
  } else {
    int tm = (tr - tl) / 2 + tl;
    build (a, 2 * v, tl, tm);
    build (a, 2 * v + 1, tm + 1, tr);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

void push (int v) {
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  t[2 * v] += lazy[v];
  t[2 * v + 1] += lazy[v];
  lazy[v] = 0;
}

void update (int v, int tl, int tr, int l, int r, int delta) {
  if (l > r) return;
  if (tl == l && tr == r) {
    t[v] += delta;
    lazy[v] += delta;
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    update (2 * v, tl, tm, l, min (r, tm), delta);
    update (2 * v + 1, tm + 1, tr, max (l, tm + 1), r, delta);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

ll getmax (int v, int tl, int tr, int l, int r) {
  if (l > r) return LLONG_MAX;
  if (tl == l && tr == r) {
    return t[v];
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    return max (getmax (2 * v, tl, tm, l, min (r, tm)), getmax (2 * v + 1, tm + 1, tr, max (l, tm + 1), r));
  }
}

int main () {
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  int n, m, p;
  cin >> n >> m >> p;
  vector < pair < int, int > > a(n), b(m);
  vector < pair < pair < int, int >, int > > monster(p);
  for (auto &i : a) cin >> i.first >> i.second;
  for (auto &i : b) cin >> i.first >> i.second;
  for (auto &i : monster) cin >> i.first.first >> i.first.second >> i.second;

  sort (a.begin(), a.end());
  sort (b.begin(), b.end());
  sort (monster.begin(), monster.end());

  build (b, 1, 0, m - 1);

  ll profit = LLONG_MIN;
  for (int i = 0; i < p; i++) {
    int pos = lower_bound (b.begin(), b.end(), make_pair (monster[i].first.second + 1, -1)) - b.begin();
    update (1, 0, m - 1, pos, m - 1, monster[i].second);
    pos = lower_bound (a.begin(), a.end(), make_pair (monster[i].first.first + 1, - 1)) - a.begin();
    profit = max (profit, -a[pos].second + getmax (1, 0, m - 1, 0, m - 1));
  }

  cout << profit << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = 2e5 + 5;

vector < ll > t (4 * N), lazy(4 * N);

void build (vector < pair < int, int > > &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = -a[tl].second;
  } else {
    int tm = (tr - tl) / 2 + tl;
    build (a, 2 * v, tl, tm);
    build (a, 2 * v + 1, tm + 1, tr);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

void push (int v) {
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  t[2 * v] += lazy[v];
  t[2 * v + 1] += lazy[v];
  lazy[v] = 0;
}

void update (int v, int tl, int tr, int l, int r, int delta) {
  if (l > r) return;
  if (tl == l && tr == r) {
    t[v] += delta;
    lazy[v] += delta;
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    update (2 * v, tl, tm, l, min (r, tm), delta);
    update (2 * v + 1, tm + 1, tr, max (l, tm + 1), r, delta);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

ll getmax (int v, int tl, int tr, int l, int r) {
  if (l > r) return LLONG_MAX;
  if (tl == l && tr == r) {
    return t[v];
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    return max (getmax (2 * v, tl, tm, l, min (r, tm)), getmax (2 * v + 1, tm + 1, tr, max (l, tm + 1), r));
  }
}

int main () {
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  int n, m, p;
  cin >> n >> m >> p;
  vector < pair < int, int > > a(n), b(m);
  vector < pair < pair < int, int >, int > > monster(p);
  for (auto &i : a) cin >> i.first >> i.second;
  for (auto &i : b) cin >> i.first >> i.second;
  for (auto &i : monster) cin >> i.first.first >> i.first.second >> i.second;

  sort (a.begin(), a.end());
  sort (b.begin(), b.end());
  sort (monster.begin(), monster.end());

  build (b, 1, 0, m - 1);

  ll profit = LLONG_MIN;
  for (int i = 0; i < p; i++) {
    int pos = lower_bound (b.begin(), b.end(), make_pair (monster[i].first.second + 1, -1)) - b.begin();
    update (1, 0, m - 1, pos, m - 1, monster[i].second);
    pos = lower_bound (a.begin(), a.end(), make_pair (monster[i].first.first + 1, - 1)) - a.begin();
    profit = max (profit, (ll)-a[pos].second + getmax (1, 0, m - 1, 0, m - 1));
  }

  cout << profit << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = 2e5 + 5;

vector < ll > t (4 * N), lazy(4 * N);

void build (vector < pair < int, int > > &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = -a[tl].second;
  } else {
    int tm = (tr - tl) / 2 + tl;
    build (a, 2 * v, tl, tm);
    build (a, 2 * v + 1, tm + 1, tr);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

void push (int v) {
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  t[2 * v] += lazy[v];
  t[2 * v + 1] += lazy[v];
  lazy[v] = 0;
}

void update (int v, int tl, int tr, int l, int r, int delta) {
  if (l > r) return;
  if (tl == l && tr == r) {
    t[v] += delta;
    lazy[v] += delta;
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    update (2 * v, tl, tm, l, min (r, tm), delta);
    update (2 * v + 1, tm + 1, tr, max (l, tm + 1), r, delta);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

ll getmax (int v, int tl, int tr, int l, int r) {
  if (l > r) return LLONG_MAX;
  if (tl == l && tr == r) {
    return t[v];
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    return max (getmax (2 * v, tl, tm, l, min (r, tm)), getmax (2 * v + 1, tm + 1, tr, max (l, tm + 1), r));
  }
}

int main () {
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  int n, m, p;
  cin >> n >> m >> p;
  vector < pair < int, int > > a(n), b(m);
  vector < pair < pair < int, int >, int > > monster(p);
  for (auto &i : a) cin >> i.first >> i.second;
  for (auto &i : b) cin >> i.first >> i.second;
  for (auto &i : monster) cin >> i.first.first >> i.first.second >> i.second;

  sort (a.begin(), a.end());
  sort (b.begin(), b.end());
  sort (monster.begin(), monster.end());

  build (b, 1, 0, m - 1);

  ll profit = -a[0].second - b[0].second;
  for (int i = 0, j = 0; i < n; i++) {
    while (j < p && monster[j].first.first < a[i].first) {
      int pos = lower_bound (b.begin(), b.end(), make_pair (monster[j].first.second + 1, -1)) - b.begin();
      update (1, 0, m - 1, pos, m - 1, monster[j].second);
      j++;
    }
    profit = max (profit, (ll)-a[i].second + getmax (1, 0, m - 1, 0, m - 1));
  }

  cout << profit << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = 2e5 + 5;

vector < ll > t (4 * N), lazy(4 * N);

void build (vector < pair < int, int > > &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = -a[tl].second;
  } else {
    int tm = (tr - tl) / 2 + tl;
    build (a, 2 * v, tl, tm);
    build (a, 2 * v + 1, tm + 1, tr);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

void push (int v) {
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  t[2 * v] += lazy[v];
  t[2 * v + 1] += lazy[v];
  lazy[v] = 0;
}

void update (int v, int tl, int tr, int l, int r, int delta) {
  if (l > r) return;
  if (tl == l && tr == r) {
    t[v] += delta;
    lazy[v] += delta;
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    update (2 * v, tl, tm, l, min (r, tm), delta);
    update (2 * v + 1, tm + 1, tr, max (l, tm + 1), r, delta);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

ll getmax (int v, int tl, int tr, int l, int r) {
  if (l > r) return LLONG_MAX;
  if (tl == l && tr == r) {
    return t[v];
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    return max (getmax (2 * v, tl, tm, l, min (r, tm)), getmax (2 * v + 1, tm + 1, tr, max (l, tm + 1), r));
  }
}

int main () {
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  int n, m, p;
  cin >> n >> m >> p;
  vector < pair < int, int > > a(n), b(m);
  vector < pair < pair < int, int >, int > > monster(p);
  for (auto &i : a) cin >> i.first >> i.second;
  for (auto &i : b) cin >> i.first >> i.second;
  for (auto &i : monster) cin >> i.first.first >> i.first.second >> i.second;

  sort (a.begin(), a.end());
  sort (b.begin(), b.end());
  sort (monster.begin(), monster.end());

  build (b, 1, 0, m - 1);

  ll profit = -a[0].second - b[0].second;
  for (int i = 0, j = 0; i < n; i++) {
    while (j < m && monster[j].first.first < a[i].first) {
      int pos = lower_bound (b.begin(), b.end(), make_pair (monster[j].first.second + 1, -1)) - b.begin();
      if (pos != m) update (1, 0, m - 1, pos, m - 1, monster[j].second);
      j++;
    }
    profit = max (profit, (ll)-a[i].second + getmax (1, 0, m - 1, 0, m - 1));
  }

  cout << profit << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = 2e5 + 5;

vector < ll > t (4 * N), lazy(4 * N);

void build (vector < pair < int, int > > &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = -a[tl].second;
  } else {
    int tm = (tr - tl) / 2 + tl;
    build (a, 2 * v, tl, tm);
    build (a, 2 * v + 1, tm + 1, tr);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

void push (int v) {
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  t[2 * v] += lazy[v];
  t[2 * v + 1] += lazy[v];
  lazy[v] = 0;
}

void update (int v, int tl, int tr, int l, int r, int delta) {
  if (l > r) return;
  if (tl == l && tr == r) {
    t[v] += delta;
    lazy[v] += delta;
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    update (2 * v, tl, tm, l, min (r, tm), delta);
    update (2 * v + 1, tm + 1, tr, max (l, tm + 1), r, delta);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

ll getmax (int v, int tl, int tr, int l, int r) {
  if (l > r) return LLONG_MAX;
  if (tl == l && tr == r) {
    return t[v];
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    return max (getmax (2 * v, tl, tm, l, min (r, tm)), getmax (2 * v + 1, tm + 1, tr, max (l, tm + 1), r));
  }
}

int main () {
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  int n, m, p;
  cin >> n >> m >> p;
  vector < pair < int, int > > a(n), b(m);
  vector < pair < pair < int, int >, int > > monster(p);
  for (auto &i : a) cin >> i.first >> i.second;
  for (auto &i : b) cin >> i.first >> i.second;
  for (auto &i : monster) cin >> i.first.first >> i.first.second >> i.second;

  sort (a.begin(), a.end());
  sort (b.begin(), b.end());
  sort (monster.begin(), monster.end());

  build (b, 1, 0, m - 1);

  ll profit = -a[0].second - b[0].second;
  for (int i = 0; i < p; i++) {
    int pos = lower_bound (b.begin(), b.end(), make_pair (monster[i].first.second + 1, -1)) - b.begin();
    if (pos == m) continue;
    update (1, 0, m - 1, pos, m - 1, monster[i].second);
    pos = lower_bound (a.begin(), a.end(), make_pair (monster[i].first.first + 1, - 1)) - a.begin();
    if (pos == n) continue;
    profit = max (profit, (ll)-a[pos].second + getmax (1, 0, m - 1, 0, m - 1));
  }

  cout << profit << '\n';
}


#include<bits/stdc++.h>

using namespace std;

typedef long long int ll;

const int N = 2e5 + 5;

vector < ll > t (4 * N), lazy(4 * N);

void build (vector < pair < int, int > > &a, int v, int tl, int tr) {
  if (tl == tr) {
    t[v] = -a[tl].second;
  } else {
    int tm = (tr - tl) / 2 + tl;
    build (a, 2 * v, tl, tm);
    build (a, 2 * v + 1, tm + 1, tr);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

void push (int v) {
  lazy[2 * v] += lazy[v];
  lazy[2 * v + 1] += lazy[v];
  t[2 * v] += lazy[v];
  t[2 * v + 1] += lazy[v];
  lazy[v] = 0;
}

void update (int v, int tl, int tr, int l, int r, int delta) {
  if (l > r) return;
  if (tl == l && tr == r) {
    t[v] += delta;
    lazy[v] += delta;
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    update (2 * v, tl, tm, l, min (r, tm), delta);
    update (2 * v + 1, tm + 1, tr, max (l, tm + 1), r, delta);
    t[v] = max (t[2 * v], t[2 * v + 1]);
  }
}

ll getmax (int v, int tl, int tr, int l, int r) {
  if (l > r) return LLONG_MAX;
  if (tl == l && tr == r) {
    return t[v];
  } else {
    push (v);
    int tm = (tr - tl) / 2 + tl;
    return max (getmax (2 * v, tl, tm, l, min (r, tm)), getmax (2 * v + 1, tm + 1, tr, max (l, tm + 1), r));
  }
}

int main () {
  ios_base::sync_with_stdio(false);
  cin.tie(0);cout.tie(0);

  int n, m, p;
  cin >> n >> m >> p;
  vector < pair < int, int > > a(n), b(m);
  vector < pair < pair < int, int >, int > > monster(p);
  for (auto &i : a) cin >> i.first >> i.second;
  for (auto &i : b) cin >> i.first >> i.second;
  for (auto &i : monster) cin >> i.first.first >> i.first.second >> i.second;

  sort (a.begin(), a.end());
  sort (b.begin(), b.end());
  sort (monster.begin(), monster.end());

  build (b, 1, 0, m - 1);

  ll profit = LLONG_MIN;
  for (int i = 0; i < p; i++) {
    int pos = lower_bound (b.begin(), b.end(), make_pair (monster[i].first.second + 1, -1)) - b.begin();
    if (pos == m) continue;
    update (1, 0, m - 1, pos, m - 1, monster[i].second);
    pos = lower_bound (a.begin(), a.end(), make_pair (monster[i].first.first + 1, - 1)) - a.begin();
    if (pos == n) continue;
    profit = max (profit, (ll)-a[pos].second + getmax (1, 0, m - 1, 0, m - 1));
  }

  cout << profit << '\n';
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
  //  freopen("cf.inp","r",stdin);
   // freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=a[1].X+b[1].Y;
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y);
    }
    cout<<mx<<endl;
    pii res={30000,0};
//    int x=low_b(a+1,a+n+1,res)-a;cout<<x;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
pii IT[800005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
pii Merge(pii l,pii r)
{
    int x=l.X+r.X;
    int y=max(l.Y,l.X+r.Y);
    return {x,y};
}
void update(int id,int l,int r,int i,int gt)
{
    if (i<l||r<i) return;
    if (l==r)
    {
        IT[id]={IT[id].X+gt,IT[id].Y+gt};
        return;
    }
    int mid=(l+r)>>1;
    update(id*2,l,mid,i,gt);
    update(id*2+1,mid+1,r,i,gt);
    IT[id]=Merge(IT[id*2],IT[id*2+1]);
}
int main()
{
 //   freopen("cf.inp","r",stdin);
 //   freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
//    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
//    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(1,1,m,i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=-(a[1].Y+b[1].Y);
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
//        if (y>m) continue;
        update(1,1,n,y,mons[i].z);
        mx=max(mx,IT[1].Y-a[x].Y);
    }
    cout<<mx<<endl;
//    pii res={8,0};
//    int x=low_b(b+1,b+m+1,res)-b;cout<<x;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
  //freopen("cf.inp","r",stdin);
//    freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
//    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
//    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
//    for (int i=1;i<=m;i++) fw[i]=b[i-1].Y-b[i].Y;
//    for (int i=1;i<=m;i++) cout<<fw[i]<<' ';cout<<endl;
    sort(mons+1,mons+p+1,Sortii);
    int mx=-(a[1].Y+b[1].Y);
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y-b[y].Y);
    }
    cout<<mx<<endl;
//    pii res={30000,0};
//    int x=low_b(a+1,a+n+1,res)-a;cout<<x;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
pii IT[800005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
pii Merge(pii l,pii r)
{
    int x=l.X+r.X;
    int y=max(l.Y,l.X+r.Y);
    return {x,y};
}
void update(int id,int l,int r,int i,int gt)
{
    if (i<l||r<i) return;
    if (l==r)
    {
        IT[id]={IT[id].X+gt,IT[id].Y+gt};
        return;
    }
    int mid=(l+r)>>1;
    update(id*2,l,mid,i,gt);
    update(id*2+1,mid+1,r,i,gt);
    IT[id]=Merge(IT[id*2],IT[id*2+1]);
}
int main()
{
   // freopen("cf.inp","r",stdin);
  //  freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
//    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
//    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(1,1,m,i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=-(a[1].Y+b[1].Y);
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
//        if (y>m) continue;
        update(1,1,m,y,mons[i].z);
        mx=max(mx,IT[1].Y-a[x].Y);
    }
    cout<<mx<<endl;
//    pii res={8,0};
//    int x=low_b(b+1,b+m+1,res)-b;cout<<x;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
  //  freopen("cf.inp","r",stdin);
  //  freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
//    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
//    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=-(a[1].Y+b[1].Y);
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y);
    }
    cout<<mx<<endl;
//    pii res={30000,0};
//    int x=low_b(a+1,a+n+1,res)-a;cout<<x;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
   // freopen("cf.inp","r",stdin);
  //  freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
//    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
//    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=-(a[1].X+b[1].Y);
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y);
    }
    cout<<mx<<endl;
//    pii res={30000,0};
//    int x=low_b(a+1,a+n+1,res)-a;cout<<x;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
 //   freopen("cf.inp","r",stdin);
  //  freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    xuli(b,m);
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=-1e9;
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y);
    }
    cout<<mx;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
   // freopen("cf.inp","r",stdin);
  //  freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    xuli(b,m);
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=0;
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y);
    }
    cout<<mx;
}


#include<bits/stdc++.h>

using namespace std;

#define X first
#define Y second
#define ll long long
#define up_b upper_bound
#define low_b lower_bound
#define pb push_back
typedef pair<int,int> pii;
pii a[200005],b[200005];
struct ii
{
    int x,y,z;
};
int n,m,p;
ii mons[200005];
bool Sortii(ii a,ii b)
{
    if (a.x!=b.x) return a.x<b.x;
    return a.y<b.y;
}
void xuli(pii a[],int &n)
{
    stack<int> st;
    pii tam[200005];
    for (int i=1;i<=n;i++)
    {
        if (a[i].X==a[i-1].X) continue;
        for (;!st.empty()&&a[st.top()].Y>=a[i].Y;st.pop());
        st.push(i);
    }
    n=st.size();
    while (!st.empty())
    {
        tam[st.size()]=a[st.top()];
        st.pop();
    }
    for (int i=1;i<=n;i++) a[i]=tam[i];
}
int fw[200005];
void update(int x,int gt)
{
    while (x<=m)
    {
        fw[x]+=gt;x+=(x&-x);
    }
}
int get(int x)
{
    int ans=0;
    while (x>=1)
    {
        ans+=fw[x];x-=(x&-x);
    }
    return ans;
}
int main()
{
    //freopen("cf.inp","r",stdin);
    //freopen("cf.out","w",stdout);
    ios_base::sync_with_stdio(0);
    cin.tie(0);cout.tie(0);
    cin>>n>>m>>p;
    for (int i=1;i<=n;i++)
    {
        int x,y;cin>>x>>y;
        a[i]={x,y};
    }
    sort(a+1,a+n+1);
    xuli(a,n);
    for (int i=1;i<=m;i++)
    {
        int x,y;cin>>x>>y;
        b[i]={x,y};
    }
    sort(b+1,b+m+1);
    xuli(b,m);
//    for (int i=1;i<=n;i++) cout<<a[i].X<<' '<<a[i].Y<<"\n";cout<<endl;
//    for (int i=1;i<=m;i++) cout<<b[i].X<<' '<<b[i].Y<<"\n";cout<<endl;
    for (int i=1;i<=p;i++)
    {
        int x,y,c;cin>>x>>y>>c;
        mons[i]={x,y,c};
    }
    for (int i=1;i<=m;i++) update(i,b[i-1].Y-b[i].Y);
    sort(mons+1,mons+p+1,Sortii);
    int mx=-1e9;
    for (int i=1;i<=p;i++)
    {
//        cout<<mons[i].x<<' '<<mons[i].y<<' '<<mons[i].z<<endl;
        pii res={mons[i].x+1,0};
        int x=low_b(a+1,a+n+1,res)-a;
        if (x>n) break;
        res={mons[i].y+1,0};
        int y=low_b(b+1,b+m+1,res)-b;
        if (y>m) continue;
        update(y,mons[i].z);
        mx=max(mx,get(y)-a[x].Y);
    }
    cout<<mx;
}


#include <bits/stdc++.h>

using namespace std;

#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define sz(v) (int)v.size()

#define MOO(i, a, b) for(int i=a; i<b; i++)
#define M00(i, a) for(int i=0; i<a; i++)
#define MOOd(i,a,b) for(int i = (b)-1; i >= a; i--)
#define M00d(i,a) for(int i = (a)-1; i>=0; i--)

#define FAST ios::sync_with_stdio(0); cin.tie(0);
#define finish(x) return cout << x << '\n', 0;
#define dbg(x) cerr << ">>> " << #x << " = " << x << "\n";
#define _ << " _ " <<

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef pair<ld,ld> pd;
typedef complex<ld> cd;

struct node {
    ll val;
    int l, r;
    node* left;
    node* right;
    node(int l, int r) {
        this -> val = 0;
        this -> l = l;
        this -> r = r;
        this -> left = nullptr;
        this -> right = nullptr;
    }
};

template<int SZ> struct sumtree{
    node* root;
    sumtree() {
        int ub = 1;
        while(ub < SZ) ub *= 2;
        root = new node(0, ub-1);
    }
    void updN(node* n, int pos, ll val) {
        if(pos < n->l || pos > n->r) return;
        if(n->l == n->r) {
            n->val += val;
            return;
        }

        int mid = (n->l + n->r)/2;
        if(pos > mid) {
            if(n->right == nullptr) n->right = new node(mid+1, n->r);
            updN(n->right, pos, val);
        }
        else {
            if(n->left == nullptr) n->left = new node(n->l, mid);
            updN(n->left, pos, val);
        }

        ll s = 0;
        if(n->right != nullptr) s += n->right->val;
        if(n->left != nullptr) s += n->left->val;

        n->val = s;
    }
    void upd(int pos, ll val) {
        updN(root, pos, val);
    }
    ll queryN(node* n, int i1, int i2) {
        if(i2 < n->l || i1 > n->r) return 0;
        if(n->l == n->r) return n->val;
        if(n->l >= i1 && n->r <= i2) return n->val;

        ll s = 0;
        if(n->left != nullptr) s += queryN(n->left, i1, i2);
        if(n->right != nullptr) s += queryN(n->right, i1, i2);

        return s;
    }
    ll query(int i1, int i2) {
        return queryN(root, i1, i2);
    }
};

const int MAX_N = 200200;
int n, m, p;
pair<ll,ll> att[MAX_N]; // cost, atk
pair<ll,ll> def[MAX_N]; // cost, def
pair<pair<ll,ll>, ll> mons[MAX_N]; // atk, def, cost
bool attValid[MAX_N];
bool defValid[MAX_N];

int main() { FAST
	cin >> n >> m >> p;
	M00(i, n) cin >> att[i].s >> att[i].f;
	sort(att,att+n);
	int curmax = 0;
	M00(i, n) {
		if(att[i].s <= curmax) {
			attValid[i] = false;
		} else {
			attValid[i] = true;
			if(i > 0 && att[i-1].f == att[i].f) attValid[i-1] = false;
			curmax = att[i].s;
		}
	}
	M00(i, m) cin >> def[i].s >> def[i].f;
	sort(def, def+m);
	curmax = 0;
	M00(i, m) {
		if(def[i].s <= curmax) {
			defValid[i] = false;
		} else {
			defValid[i] = true;
			if(i > 0 && def[i-1].f == def[i].f) defValid[i-1] = false;
			curmax = def[i].s;
		}
	}

	M00(i, p) cin >> mons[i].f.f >> mons[i].f.s >> mons[i].s;
	vector<pair<ll,ll>> validAttacks; // atk, cost
	vector<pair<ll,ll>> validDefenses; // def, cost
	M00(i, n) if(attValid[i]) validAttacks.pb(mp(att[i].s, att[i].f));
	M00(i, m) if(defValid[i]) validDefenses.pb(mp(def[i].s, def[i].f));
	//for(auto ll: validAttacks) dbg(ll.f _ ll.s);
	//for(auto kk: validDefenses) dbg(kk.f _ kk.s);

	sumtree<2000000> st;
	sort(mons, mons+p);
	set<int> seenAtt;
	ll res = -validAttacks[0].s - validDefenses[0].s;
	M00(i, p) {
		ll curAtt = mons[i].f.f;
		if(!seenAtt.count(curAtt)) {
			seenAtt.insert(curAtt);
			for(int j = i; j < p; j++) {
				if(mons[j].f.f == curAtt) {
					st.upd(mons[j].f.s, mons[j].s);
				} else {
					break;
				}
			}
		}
		ll curDef = mons[i].f.s;
		ll profit = 0;
		auto it1 = upper_bound(all(validDefenses), mp(curAtt,1LL<<40));
		auto it2 = upper_bound(all(validAttacks), mp(curDef,1LL<<40));
		if(it1 == validDefenses.end() || it2 == validAttacks.end()) continue;
		profit -= (*it1).s;
		profit -= (*it2).s;
		profit += st.query(0, curDef);
		//dbg(curAtt _ (*it1).f _ (*it1).s);
		//dbg(curDef _ (*it2).f _ (*it2).s);
		//dbg(profit);
		res = max(res, profit);
	}
	finish(res);
}


#include <bits/stdc++.h>

using namespace std;

#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define sz(v) (int)v.size()

#define MOO(i, a, b) for(int i=a; i<b; i++)
#define M00(i, a) for(int i=0; i<a; i++)
#define MOOd(i,a,b) for(int i = (b)-1; i >= a; i--)
#define M00d(i,a) for(int i = (a)-1; i>=0; i--)

#define FAST ios::sync_with_stdio(0); cin.tie(0);
#define finish(x) return cout << x << '\n', 0;
#define dbg(x) cerr << ">>> " << #x << " = " << x << "\n";
#define _ << " _ " <<

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef pair<ld,ld> pd;
typedef complex<ld> cd;

struct node {
    ll val;
    ll lazy;
    int l, r;
    node* left;
    node* right;
    node(int l, int r) {
        this -> val = -1e16;
        this -> lazy = 0;
        this -> l = l;
        this -> r = r;
        this -> left = nullptr;
        this -> right = nullptr;
    }
};

template<int SZ> struct lazymaxtree {
	const ll initVal = -1e16;
    node* root;
    lazymaxtree() {
        int ub = 1;
        while(ub < SZ) ub *= 2;
        root = new node(0, ub-1);
        root -> val = initVal;
        root -> lazy = 0;
    }
    void propagate(node* n) {
        if(n->l != n->r) {
            int mid = ((n->l) + (n->r))/2;
            if(n->left == nullptr) {
                n->left = new node(n->l, mid);
                n->left->val = initVal;
                n->left->lazy = 0;
            }
            if(n->right == nullptr) {
                n->right = new node(mid+1, n->r);
                n->right->val = initVal;
                n->right->lazy = 0;
            }
        }
        if(n->lazy != initVal) {
            n->val += n->lazy;
            if(n->l != n->r) {
                n->left->lazy += n->lazy;
                n->right->lazy += n->lazy;
            }
            n->lazy = 0;
        }
    }
    void updN(node* n, int i1, int i2, ll val) {
        propagate(n);
        if(i2 < n->l || i1 > n->r) return;
        if(n->l == n->r) {
            n->val += val;
            return;
        }
        if(i1 <= n->l && i2 >= n->r) {
            n->val += val;
            n->left->lazy += val;
            n->right->lazy += val;
            return;
        }

        updN(n->left, i1, i2, val);
        updN(n->right, i1, i2, val);
        n->val = max(n->left->val, n->right->val);
    }
    void upd(int i1, int i2, ll val) {
        updN(root, i1, i2, val);
    }
    ll queryN(node* n, int i1, int i2) {
        propagate(n);
        if(i2 < n->l || i1 > n->r) return -1e16;
        if(n->l == n->r) {
            return n->val;
        }
        if(i1 <= n->l && i2 >= n->r) {
            return n->val;
        }

        return max(queryN(n->left, i1, i2), queryN(n->right, i1, i2));
    }
    ll query(int i1, int i2) {
        return queryN(root, i1, i2);
    }
};

const int MAX_N = 200200;
int n, m, p;
pair<ll,ll> att[MAX_N]; // cost, atk
pair<ll,ll> def[MAX_N]; // cost, def
pair<pair<ll,ll>, ll> mons[MAX_N]; // atk, def, cost
bool defValid[MAX_N];
bool attValid[MAX_N];

int main() { FAST
	cin >> n >> m >> p;
	M00(i, n) cin >> att[i].s >> att[i].f;
	sort(att,att+n);
	int curmax = 0;
	M00(i, n) {
		if(att[i].s <= curmax) {
			attValid[i] = false;
		} else {
			attValid[i] = true;
			if(i > 0 && att[i-1].f == att[i].f) attValid[i-1] = false;
			curmax = att[i].s;
		}
	}
	M00(i, m) cin >> def[i].s >> def[i].f;
	sort(def, def+m);
	curmax = 0;
	M00(i, m) {
		if(def[i].s <= curmax) {
			defValid[i] = false;
		} else {
			defValid[i] = true;
			if(i > 0 && def[i-1].f == def[i].f) defValid[i-1] = false;
			curmax = def[i].s;
		}
	}
	vector<pair<ll,ll>> validAttacks; // atk, cost
	vector<pair<ll,ll>> validDefenses; // def, cost
	M00(i, n) if(attValid[i]) validAttacks.pb(mp(att[i].s, att[i].f));
	M00(i, m) if(defValid[i]) validDefenses.pb(mp(def[i].s, def[i].f));

	M00(i, p) cin >> mons[i].f.s >> mons[i].f.f >> mons[i].s;

	const int MX = 2000000;
	lazymaxtree<MX> mt;
	sort(mons, mons+p);
	M00(i, n) {
		ll val = mt.query(att[i].s, att[i].s);
		if(-att[i].f > val) {
			mt.upd(att[i].s, att[i].s, -val);
			mt.upd(att[i].s, att[i].s, -att[i].f);
		}
	}
	ll res = -validAttacks[0].s-validDefenses[0].s;
	M00(i, p) {
		mt.upd(mons[i].f.s+1, MX-1, mons[i].s);
		auto it = upper_bound(all(validDefenses), mp(mons[i].f.f, 1LL<<40));
		if(it == validDefenses.end()) break;
		res = max(res, mt.query(0, MX-1) - (*it).s);
	}
	finish(res);
}


#include <bits/stdc++.h>

using namespace std;

#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define sz(v) (int)v.size()

#define MOO(i, a, b) for(int i=a; i<b; i++)
#define M00(i, a) for(int i=0; i<a; i++)
#define MOOd(i,a,b) for(int i = (b)-1; i >= a; i--)
#define M00d(i,a) for(int i = (a)-1; i>=0; i--)

#define FAST ios::sync_with_stdio(0); cin.tie(0);
#define finish(x) return cout << x << '\n', 0;
#define dbg(x) cerr << ">>> " << #x << " = " << x << "\n";
#define _ << " _ " <<

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef pair<ld,ld> pd;
typedef complex<ld> cd;

struct node {
    ll val;
    int l, r;
    node* left;
    node* right;
    node(int l, int r) {
        this -> val = 0;
        this -> l = l;
        this -> r = r;
        this -> left = nullptr;
        this -> right = nullptr;
    }
};

template<int SZ> struct sumtree{
    node* root;
    sumtree() {
        int ub = 1;
        while(ub < SZ) ub *= 2;
        root = new node(0, ub-1);
    }
    void updN(node* n, int pos, ll val) {
        if(pos < n->l || pos > n->r) return;
        if(n->l == n->r) {
            n->val += val;
            return;
        }

        int mid = (n->l + n->r)/2;
        if(pos > mid) {
            if(n->right == nullptr) n->right = new node(mid+1, n->r);
            updN(n->right, pos, val);
        }
        else {
            if(n->left == nullptr) n->left = new node(n->l, mid);
            updN(n->left, pos, val);
        }

        ll s = 0;
        if(n->right != nullptr) s += n->right->val;
        if(n->left != nullptr) s += n->left->val;

        n->val = s;
    }
    void upd(int pos, ll val) {
        updN(root, pos, val);
    }
    ll queryN(node* n, int i1, int i2) {
        if(i2 < n->l || i1 > n->r) return 0;
        if(n->l == n->r) return n->val;
        if(n->l >= i1 && n->r <= i2) return n->val;

        ll s = 0;
        if(n->left != nullptr) s += queryN(n->left, i1, i2);
        if(n->right != nullptr) s += queryN(n->right, i1, i2);

        return s;
    }
    ll query(int i1, int i2) {
        return queryN(root, i1, i2);
    }
};

const int MAX_N = 200200;
int n, m, p;
pair<ll,ll> att[MAX_N]; // cost, atk
pair<ll,ll> def[MAX_N]; // cost, def
pair<pair<ll,ll>, ll> mons[MAX_N]; // atk, def, cost
bool attValid[MAX_N];
bool defValid[MAX_N];

int main() { FAST
	cin >> n >> m >> p;
	M00(i, n) cin >> att[i].s >> att[i].f;
	sort(att,att+n);
	int curmax = 0;
	M00(i, n) {
		if(att[i].s <= curmax) {
			attValid[i] = false;
		} else {
			attValid[i] = true;
			if(i > 0 && att[i-1].f == att[i].f) attValid[i-1] = false;
			curmax = att[i].s;
		}
	}
	M00(i, m) cin >> def[i].s >> def[i].f;
	sort(def, def+m);
	curmax = 0;
	M00(i, m) {
		if(def[i].s <= curmax) {
			defValid[i] = false;
		} else {
			defValid[i] = true;
			if(i > 0 && def[i-1].f == def[i].f) defValid[i-1] = false;
			curmax = def[i].s;
		}
	}

	M00(i, p) cin >> mons[i].f.s >> mons[i].f.f >> mons[i].s;
	vector<pair<ll,ll>> validAttacks; // atk, cost
	vector<pair<ll,ll>> validDefenses; // def, cost
	M00(i, n) if(attValid[i]) validAttacks.pb(mp(att[i].s, att[i].f));
	M00(i, m) if(defValid[i]) validDefenses.pb(mp(def[i].s, def[i].f));

	sumtree<2000000> st;
	sort(mons, mons+p);
	set<int> seenAtt;
	ll res = -1e18;
	M00(i, p) {
		ll curAtt = mons[i].f.f;
		if(!seenAtt.count(curAtt)) {
			seenAtt.insert(curAtt);
			for(int j = i; j < p; j++) {
				if(mons[j].f.f == curAtt) {
					st.upd(mons[j].f.s, mons[j].s);
				} else {
					break;
				}
			}
		}
		ll curDef = mons[i].f.s;
		ll profit = 0;
		auto it1 = upper_bound(all(validDefenses), mp(curAtt,-1LL));
		auto it2 = upper_bound(all(validAttacks), mp(curDef,-1LL));
		if(it1 == validDefenses.end() || it2 == validAttacks.end()) continue;
		profit -= (*it1).s;
		profit -= (*it2).s;
		profit += st.query(0, curDef);
		res = max(res, profit);
	}
	finish(res);
}


#include <bits/stdc++.h>

using namespace std;

#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define sz(v) (int)v.size()

#define MOO(i, a, b) for(int i=a; i<b; i++)
#define M00(i, a) for(int i=0; i<a; i++)
#define MOOd(i,a,b) for(int i = (b)-1; i >= a; i--)
#define M00d(i,a) for(int i = (a)-1; i>=0; i--)

#define FAST ios::sync_with_stdio(0); cin.tie(0);
#define finish(x) return cout << x << '\n', 0;
#define dbg(x) cerr << ">>> " << #x << " = " << x << "\n";
#define _ << " _ " <<

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef pair<ld,ld> pd;
typedef complex<ld> cd;

struct node {
    ll val;
    int l, r;
    node* left;
    node* right;
    node(int l, int r) {
        this -> val = 0;
        this -> l = l;
        this -> r = r;
        this -> left = nullptr;
        this -> right = nullptr;
    }
};

template<int SZ> struct sumtree{
    node* root;
    sumtree() {
        int ub = 1;
        while(ub < SZ) ub *= 2;
        root = new node(0, ub-1);
    }
    void updN(node* n, int pos, ll val) {
        if(pos < n->l || pos > n->r) return;
        if(n->l == n->r) {
            n->val += val;
            return;
        }

        int mid = (n->l + n->r)/2;
        if(pos > mid) {
            if(n->right == nullptr) n->right = new node(mid+1, n->r);
            updN(n->right, pos, val);
        }
        else {
            if(n->left == nullptr) n->left = new node(n->l, mid);
            updN(n->left, pos, val);
        }

        ll s = 0;
        if(n->right != nullptr) s += n->right->val;
        if(n->left != nullptr) s += n->left->val;

        n->val = s;
    }
    void upd(int pos, ll val) {
        updN(root, pos, val);
    }
    ll queryN(node* n, int i1, int i2) {
        if(i2 < n->l || i1 > n->r) return 0;
        if(n->l == n->r) return n->val;
        if(n->l >= i1 && n->r <= i2) return n->val;

        ll s = 0;
        if(n->left != nullptr) s += queryN(n->left, i1, i2);
        if(n->right != nullptr) s += queryN(n->right, i1, i2);

        return s;
    }
    ll query(int i1, int i2) {
        return queryN(root, i1, i2);
    }
};

const int MAX_N = 200200;
int n, m, p;
pair<ll,ll> att[MAX_N]; // cost, atk
pair<ll,ll> def[MAX_N]; // cost, def
pair<pair<ll,ll>, ll> mons[MAX_N]; // atk, def, cost
bool attValid[MAX_N];
bool defValid[MAX_N];

int main() { FAST
	cin >> n >> m >> p;
	M00(i, n) cin >> att[i].s >> att[i].f;
	sort(att,att+n);
	int curmax = 0;
	M00(i, n) {
		if(att[i].s <= curmax) {
			attValid[i] = false;
		} else {
			attValid[i] = true;
			curmax = att[i].s;
		}
	}
	M00(i, m) cin >> def[i].s >> def[i].f;
	sort(def, def+m);
	curmax = 0;
	M00(i, m) {
		if(def[i].s <= curmax) {
			defValid[i] = false;
		} else {
			defValid[i] = true;
			curmax = def[i].s;
		}
	}

	M00(i, p) cin >> mons[i].f.s >> mons[i].f.f >> mons[i].s;
	vector<pair<ll,ll>> validAttacks; // atk, cost
	vector<pair<ll,ll>> validDefenses; // def, cost
	M00(i, n) if(attValid[i]) validAttacks.pb(mp(att[i].s, att[i].f));
	M00(i, m) if(defValid[i]) validDefenses.pb(mp(def[i].s, def[i].f));

	sumtree<2000000> st;
	sort(mons, mons+p);
	set<int> seenAtt;
	ll res = -1e18;
	M00(i, p) {
		ll curAtt = mons[i].f.f;
		if(!seenAtt.count(curAtt)) {
			seenAtt.insert(curAtt);
			for(int j = i; j < p; j++) {
				if(mons[j].f.f == curAtt) {
					st.upd(mons[j].f.s, mons[j].s);
				} else {
					break;
				}
			}
		}
		ll curDef = mons[i].f.s;
		ll profit = 0;
		auto it1 = upper_bound(all(validDefenses), mp(curAtt,-1LL));
		auto it2 = upper_bound(all(validAttacks), mp(curDef,-1LL));
		if(it1 == validDefenses.end() || it2 == validAttacks.end()) continue;
		profit -= (*it1).s;
		profit -= (*it2).s;
		profit += st.query(0, curDef);
		res = max(res, profit);
	}
	finish(res);
}


#include <bits/stdc++.h>

using namespace std;

#define f first
#define s second
#define pb push_back
#define mp make_pair
#define all(v) v.begin(), v.end()
#define sz(v) (int)v.size()

#define MOO(i, a, b) for(int i=a; i<b; i++)
#define M00(i, a) for(int i=0; i<a; i++)
#define MOOd(i,a,b) for(int i = (b)-1; i >= a; i--)
#define M00d(i,a) for(int i = (a)-1; i>=0; i--)

#define FAST ios::sync_with_stdio(0); cin.tie(0);
#define finish(x) return cout << x << '\n', 0;
#define dbg(x) cerr << ">>> " << #x << " = " << x << "\n";
#define _ << " _ " <<

typedef long long ll;
typedef long double ld;
typedef vector<int> vi;
typedef pair<int,int> pi;
typedef pair<ld,ld> pd;
typedef complex<ld> cd;

struct node {
    ll val;
    ll lazy;
    int l, r;
    node* left;
    node* right;
    node(int l, int r) {
        this -> val = -1e16;
        this -> lazy = 0;
        this -> l = l;
        this -> r = r;
        this -> left = nullptr;
        this -> right = nullptr;
    }
};

template<int SZ> struct lazymaxtree {
	const ll initVal = -1e16;
    node* root;
    lazymaxtree() {
        int ub = 1;
        while(ub < SZ) ub *= 2;
        root = new node(0, ub-1);
        root -> val = initVal;
        root -> lazy = initVal;
    }
    void propagate(node* n) {
        if(n->l != n->r) {
            int mid = ((n->l) + (n->r))/2;
            if(n->left == nullptr) {
                n->left = new node(n->l, mid);
                n->left->val = initVal;
                n->left->lazy = initVal;
            }
            if(n->right == nullptr) {
                n->right = new node(mid+1, n->r);
                n->right->val = initVal;
                n->right->lazy = initVal;
            }
        }
        if(n->lazy != initVal) {
            n->val += n->lazy;
            if(n->l != n->r) {
                n->left->lazy += n->lazy;
                n->right->lazy += n->lazy;
            }
            n->lazy = initVal;
        }
    }
    void updN(node* n, int i1, int i2, ll val) {
        propagate(n);
        if(i2 < n->l || i1 > n->r) return;
        if(n->l == n->r) {
            n->val += val;
            return;
        }
        if(i1 <= n->l && i2 >= n->r) {
            n->val += val;
            n->left->lazy += val;
            n->right->lazy += val;
            return;
        }

        updN(n->left, i1, i2, val);
        updN(n->right, i1, i2, val);
        n->val = max(n->left->val, n->right->val);
    }
    void upd(int i1, int i2, ll val) {
        updN(root, i1, i2, val);
    }
    ll queryN(node* n, int i1, int i2) {
        propagate(n);
        if(i2 < n->l || i1 > n->r) return -1e16;
        if(n->l == n->r) {
            return n->val;
        }
        if(i1 <= n->l && i2 >= n->r) {
            return n->val;
        }

        return max(queryN(n->left, i1, i2), queryN(n->right, i1, i2));
    }
    ll query(int i1, int i2) {
        return queryN(root, i1, i2);
    }
};

const int MAX_N = 200200;
int n, m, p;
pair<ll,ll> att[MAX_N]; // cost, atk
pair<ll,ll> def[MAX_N]; // cost, def
pair<pair<ll,ll>, ll> mons[MAX_N]; // atk, def, cost
bool defValid[MAX_N];

int main() { FAST
	cin >> n >> m >> p;
	M00(i, n) cin >> att[i].s >> att[i].f;
	sort(att,att+n);
	M00(i, m) cin >> def[i].s >> def[i].f;
	sort(def, def+m);
	sort(def, def+m);
	int curmax = 0;
	M00(i, m) {
		if(def[i].s <= curmax) {
			defValid[i] = false;
		} else {
			defValid[i] = true;
			if(i > 0 && def[i-1].f == def[i].f) defValid[i-1] = false;
			curmax = def[i].s;
		}
	}
	vector<pair<ll,ll>> validDefenses; // def, cost
	M00(i, m) if(defValid[i]) validDefenses.pb(mp(def[i].s, def[i].f));

	M00(i, p) cin >> mons[i].f.s >> mons[i].f.f >> mons[i].s;

	const int MX = 2000000;
	lazymaxtree<MX> mt;
	sort(mons, mons+p);
	M00(i, n) {
		mt.upd(att[i].s, att[i].s, 1e16);
		mt.upd(att[i].s, att[i].s, -att[i].f);
	}
	ll res = mt.query(0, MX-1);
	M00(i, p) {
		mt.upd(mons[i].f.s+1, MX-1, mons[i].s);
		auto it = upper_bound(all(validDefenses), mp(mons[i].f.f, 1LL<<40));
		if(it == validDefenses.end()) break;
		res = max(res, mt.query(0, MX-1) - (*it).s);
	}
	finish(res);
}