#include <iostream>
#include <cstdio>
#include <vector>
#include <algorithm>
#include <set>
#include <string>
#pragma comment(linker, "/stack:268435456")
#define cs(x) (int)x.size()
#define ll long long
#define ld long double
#define mp make_pair

using namespace std;

struct node {
	ll canuse;
	ll cost;
	int rightnotzero;
	node() {
		canuse = 0;
		cost = 0;
		rightnotzero = -1;
	}
};

node merge(const node & a, const node & b) {
	node result;
	result.canuse = a.canuse + b.canuse;
	result.cost = a.cost + b.cost;
	result.rightnotzero = max(a.rightnotzero, b.rightnotzero);
	return result;
}

struct segmenttree {
	vector<node> tree;
	int n;

	void set(int v, int curl, int curr, int x, node toset) {
		if (curl == curr) {
			tree[v] = toset;
			return;
		}
		int m = (curl + curr) / 2;
		if (m >= x)
			set(v * 2, curl, m, x, toset);
		else
			set(v * 2 + 1, m + 1, curr, x, toset);
		tree[v] = merge(tree[v * 2], tree[v * 2 + 1]);
	}

	void set(int i, node toset) {
		set(1, 0, n - 1, i, toset);
	}

	void init(int n) {
		this->n = n;
		int k = 1;
		while (k < n)
			k *= 2;
		k *= 2;
		tree.resize(k);
	}
};

segmenttree tree;
vector<pair<pair<ll, ll>, ll> > rawtrade;
ll calc(ll fishamount) {
	if (tree.tree[1].canuse <= fishamount)
		return tree.tree[1].cost;
	int right = -1;
	ll ans = 0;
	int cur = 1;
	int curl = 0, curr = tree.n-1;
	while (1) {
		if (tree.tree[cur].canuse <= fishamount) {
			fishamount = 0;
			ans += tree.tree[cur].cost;
			break;
		}
		if (curl == curr) {
			right = max(right, tree.tree[cur].rightnotzero);
			break;
		}
		int m = (curl + curr) / 2;
		if (tree.tree[cur * 2 + 1].canuse >= fishamount) {
			right = max(right, tree.tree[cur * 2].rightnotzero);
			curl = m + 1;
			cur = cur * 2 + 1;
			continue;
		}
		else {
			fishamount -= tree.tree[cur * 2 + 1].canuse;
			ans += tree.tree[cur * 2 + 1].cost;
			curr = m;
			cur = cur * 2;
			continue;
		}
	}
	if (right != -1) {
		ans += fishamount * rawtrade[right].first.first;
	}
	return ans;
}

int main() {
	iostream::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	freopen("fisher.in", "r", stdin);
	freopen("fisher.out", "w", stdout);
	int n, m;
	cin >> n >> m;
	tree.init(m);
	ll p;
	cin >> p;
	vector<pair<ll, ll> > arr;
	arr.reserve(n + m);
	vector<ll> fish(n);
	for (int i = 0; i < n; i++) {
		int a, b;
		cin >> a >> b;
		arr.push_back(mp(a, i));
		fish[i] = b;
	}
	vector<pair<ll, ll> > trade(m);
	rawtrade.resize(m);
	vector<ll> use(m);
	for (int i = 0; i < m; i++) {
		int x, a, b;
		cin >> x >> a >> b;
		rawtrade[i] = mp(mp(b,a), x);
	}
	sort(rawtrade.begin(), rawtrade.end());
	for (int i = 0; i < m; i++) {
		arr.push_back(mp(rawtrade[i].second, i + n));
		trade[i] = mp(rawtrade[i].first.second, rawtrade[i].first.first);
	}
	ll curans = 0;
	ll curmoney = 0;
	ll totalfish = 0;
	ll cost = 0;
	ll lastdist = 0;
	sort(arr.begin(), arr.end());
	for (auto ev : arr) {
		cost -= (ev.first - lastdist)*p;
		lastdist = ev.first;
		if (ev.second >= n) {
			auto base = trade[ev.second - n];
			node toset;
			toset.canuse = base.first;
			toset.rightnotzero = ev.second - n;
			toset.cost = base.first * base.second;
			tree.set(ev.second - n, toset);
		}
		else {
			auto f = fish[ev.second];
			totalfish += f;
		}
		curans = max(curans, cost + calc(totalfish));
	}
	cout << curans << endl;
	return 0;
}