#include <bits/stdc++.h>
using namespace std;
using ll = long long;
ll smallest_power_of_two(const ll x) {
  ll power2 = x - 1;
  power2 |= power2 >> 1;
  power2 |= power2 >> 2;
  power2 |= power2 >> 4;
  power2 |= power2 >> 8;
  power2 |= power2 >> 16;
  return power2 + 1;
}
class SegmentTree {
  vector<ll> result, lazy;
  ll N;
  void process_lazy(ll node, ll node_min, ll node_max) {
    if (lazy[node] != 0) {
      result[node] += lazy[node];
      if (node_min != node_max) {
        lazy[node * 2] += lazy[node];
        lazy[node * 2 + 1] += lazy[node];
      }
      lazy[node] = 0;
    }
  }
  void range_update(ll from, ll to, ll dx, ll node, ll node_min, ll node_max) {
    process_lazy(node, node_min, node_max);
    if (to < node_min || node_max < from) {
      return;
    } else if (from <= node_min && node_max <= to) {
      result[node] += dx;
      if (node_min != node_max) {
        lazy[node * 2] += dx;
        lazy[node * 2 + 1] += dx;
      }
    } else {
      ll d = (node_min + node_max) / 2;
      range_update(from, to, dx, node * 2, node_min, d);
      range_update(from, to, dx, node * 2 + 1, d + 1, node_max);
      result[node] = max(result[node * 2], result[node * 2 + 1]);
    }
  }
  ll range_query(ll from, ll to, ll node, ll node_min, ll node_max) {
    process_lazy(node, node_min, node_max);
    if (to < node_min || node_max < from) {
      return -(1LL << 60);
    } else if (from <= node_min && node_max <= to) {
      return result[node];
    } else {
      ll d = (node_min + node_max) / 2;
      return max(range_query(from, to, node * 2, node_min, d),
                 range_query(from, to, node * 2 + 1, d + 1, node_max));
    }
  }

 public:
  SegmentTree(ll N) : N(N) {
    ll size = 2 * smallest_power_of_two(N);
    result = lazy = vector<ll>(size, 0);
  }
  void range_update(ll from, ll to, ll change) {
    range_update(from, to, change, 1, 0, N - 1);
  }
  ll range_query(ll from, ll to) { return range_query(from, to, 1, 0, N - 1); }
};
int main() {
  ios_base::sync_with_stdio(false);
  cin.tie(NULL);
  ll n, m, p;
  cin >> n >> m >> p;
  vector<pair<ll, ll>> data_a(n), data_d(m);
  for (ll i = 0; i < n; i++) cin >> data_a[i].first >> data_a[i].second;
  for (ll i = 0; i < m; i++) cin >> data_d[i].first >> data_d[i].second;
  for (auto& p : data_a) p.second *= -1;
  for (auto& p : data_d) p.second *= -1;
  sort(data_a.begin(), data_a.end());
  sort(data_d.begin(), data_d.end());
  vector<pair<ll, ll>> attack, defense;
  for (int i = data_a.size() - 1; i >= 0; i--)
    if (attack.empty() || (data_a[i].second > attack.back().second))
      attack.push_back(data_a[i]);
  for (int i = data_d.size() - 1; i >= 0; i--)
    if (defense.empty() || (data_d[i].second > defense.back().second))
      defense.push_back(data_d[i]);
  reverse(attack.begin(), attack.end());
  reverse(defense.begin(), defense.end());
  vector<tuple<ll, ll, ll>> monster(p);
  for (ll i = 0; i < p; i++)
    cin >> get<0>(monster[i]) >> get<1>(monster[i]) >> get<2>(monster[i]);
  sort(monster.begin(), monster.end());
  SegmentTree tree(defense.size());
  for (ll i = 0; i < defense.size(); i++)
    tree.range_update(i, i, defense[i].second);
  ll result = attack.front().second + defense.front().second;
  for (auto mon : monster) {
    auto it1 =
        upper_bound(attack.begin(), attack.end(), pair<ll, ll>{get<0>(mon), 0});
    if (it1 == attack.end()) break;
    auto it2 = upper_bound(defense.begin(), defense.end(),
                           pair<ll, ll>{get<1>(mon), 0});
    tree.range_update(it2 - defense.begin(), defense.size() - 1, get<2>(mon));
    result = max(result, it1->second + tree.range_query(0, defense.size() - 1));
  }
  cout << result << endl;
}
