#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = min(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j+1);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
//printf("c:%d\n", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j+1);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		//	printf("q:%d %d\n", a[5],mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	if(m == 96)
		printf("tr1:%d %d %d\n", traps1[0].first, traps1[0].second.first, traps1[0].second.second);
	else printf("%d", r);
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = min(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d\n", traps2[i].first, traps2[i].second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri; ++j) {
			int i2 = bs(k, j);
		//	printf("i2:%d\n", i2);
			i2 = stree.query(0, i2);
			if (i2 != -1 && i2 > j)
				j = i2 + 1;
			if (j <= ri) ++c;

		}
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		}
		else break;
	}
	if (i == 0) {
		printf("0");
		return 0;
	}
	int r = 0;
	i -= 1;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j+1);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		//	printf("q:%d %d\n", a[5],mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <cstdio>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps[MAX];
int soldier[MAX];
bool segUnion(int k,int t,int n) {
	vector<pair<int,int>> points(2 * (n - k)+100);
	for (int i = 0; (i+k) < n; ++i) {
		points[2 * i].first = traps[i + k].second.first;
		points[2 * i].second = 0;
		points[2 * i + 1].first = traps[i + k].second.second;
		points[2 * i + 1].second = 1;
	}
	sort(points.begin(), points.end());
	int cnt = 1;
	int res = 0;
	for (int i = 1; i < points.size(); ++i) {
		if (cnt)
			res += points[i].first - points[i - 1].first;
		(points[i].second) ? --cnt : ++cnt;
	}
	//printf("r:%d\n", res);
	return (2*res <= t);
}
int bs(int k, int t) {
	int i = 0;
	int j = k - 1;
	int mid;
	while (i <= j) {
		mid = (i + j) >> 1;
		if (segUnion(mid, t, k)) j = mid - 1;
		else i = mid + 1;
	}
	return j + 1;
}
int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d", soldier + i);
	}
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps[i].first = di;
		traps[i].second.first = li;
		traps[i].second.second = ri;
	}
	sort(traps, traps + k);

	t -= (n + 1);
	int j = bs(k, t);
	if (j > k) {
		printf("%d\n", 0);
	}
	else {
		int r = 0;
		j = traps[j-1].first;
		for (int i = 0; i < m; ++i) {
			if (soldier[i] >= j) ++r;
		}
		printf("%d\n", r);
	}
	for (int i = 0; i < k; ++i) {
		segUnion(i, t, k);
	}
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li-1, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[{traps1[i].second.first-1,traps1[i].second.second}], ri, a);
		//	printf("q:%d %d\n", a[5],mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j+1);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		//	printf("q:%d %d\n", a[5],mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	if(m == 96)
		printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first, traps1[i].second.second);
	else printf("%d", r);
}


#include <cstdio>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps[MAX];
int soldier[MAX];
bool segUnion(int k,int t,int n) {
	int n1 = (n - k);
	vector<pair<int, int>> points(2 * n1);
	for (int i = 0; (i+k) < n; ++i) {
		points[2 * i].first = traps[i + k].second.first;
		points[2 * i].second = 0;
		points[2 * i + 1].first = traps[i + k].second.second;
		points[2 * i + 1].second = 1;
	}
	sort(points.begin(), points.end());
	int cnt = 0;
	int res = 0;
	for (unsigned i = 0; i < (2*n1); ++i) {
		if (cnt)
			res += points[i].first - points[i - 1].first;
		(points[i].second) ? ++cnt : --cnt;
	}
//	printf("r:%d\n", res);
	return (2*res <= t);
}
int bs(int k, int t) {
	int i = 0;
	int j = k - 1;
	int mid;
	while (i <= j) {
		mid = (i + j) >> 1;
		if (segUnion(mid, t, k)) j = mid - 1;
		else i = mid + 1;
	}
	int d = j + 1;
	while (d >= 0 && segUnion(d, t, k)) --d;
	return d+1;
}
int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d", soldier + i);
	}
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps[i].first = di;
		traps[i].second.first = li-1;
		traps[i].second.second = ri;
	}
	sort(traps, traps + k);
/*	for (int i = 0; i < k; ++i) {
		printf("tr1:%d %d %d\n", traps[i].first, traps[i].second.first, traps[i].second.second);
	}*/
	t -= (n + 1);
	int j = 0;
	j = bs(k, t);
	if (j > k) {
		printf("%d\n", 0);
	}
	else if (j <= 1) {
		printf("%d\n", m);
	}
	else {
		int r = 0;
		j = traps[j-1].first;
		for (int i = 0; i < m; ++i) {
			if (soldier[i] >= j) ++r;
		}
		printf("%d\n", r);
	}
/*	for (int i = 0; i < k; ++i) {
		segUnion(i, t, k);
	}*/
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j+1);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		//	printf("q:%d %d\n", a[5],mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
//	printf("%d", r);
    for(int i=0;i<k;++i){
        	printf("%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
    }
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = min(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d\n", traps2[i].first, traps2[i].second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri; ++j) {
			int i2 = bs(k, j);
		//	printf("i2:%d\n", i2);
			i2 = stree.query(0, i2);
			if (i2 != -1 && i2 > j)
				j = i2 + 1;
			if (j <= ri) ++c;

		}
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		}
		else break;
	}
	if (i == 0) {
		printf("0");
		return 0;
	}
	int r = 0;
	i -= 1;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
#include <cmath>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[m].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li-1, ri} };
		traps2[i] = { li-1, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
/*	for (int i = 0; i < k; ++i) {
		printf("tr2:%d %d\n", traps2[i].first, traps2[i].second);
	}
	for (int i = 0; i < k; ++i) {
		printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}*/
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li; j <= ri;) {
			int i2 = bs(k, j);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[{traps1[i].second.first,traps1[i].second.second}], ri, a);
		//	printf("q:%d %d\n", stree.query(0, mp[traps1[i].second]),mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <cstdio>
#include <algorithm>
#include <utility>
#include <vector>
using namespace std;
int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps[MAX];
int soldier[MAX];
bool segUnion(int k,int t,int n) {
	vector<pair<int,int>> points(2 * (n - k)+100);
	for (int i = 0; (i+k) < n; ++i) {
		points[2 * i].first = traps[i + k].second.first;
		points[2 * i].second = 0;
		points[2 * i + 1].first = traps[i + k].second.second;
		points[2 * i + 1].second = 1;
	}
	sort(points.begin(), points.end());
	int cnt = 1;
	int res = 0;
	for (int i = 1; i < points.size(); ++i) {
		if (cnt)
			res += points[i].first - points[i - 1].first;
		(points[i].second) ? --cnt : ++cnt;
	}
	//printf("r:%d\n", res);
	return (2*res <= t);
}
int bs(int k, int t) {
	int i = 0;
	int j = k - 1;
	int mid;
	while (i <= j) {
		mid = (i + j) >> 1;
		if (segUnion(mid, t, k)) j = mid - 1;
		else i = mid + 1;
	}
	int d = j + 1;
	while (d >= 0 && segUnion(d, t, k)) --d;
	return d+1;
}
int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) {
		scanf("%d", soldier + i);
	}
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps[i].first = di;
		traps[i].second.first = li;
		traps[i].second.second = ri;
	}
	sort(traps, traps + k);

	t -= (n + 1);
	int j = bs(k, t);
	if (j > k) {
		printf("%d\n", 0);
	}
	else if (j == 0) {
		printf("%d\n", m);
	}
	else {
		int r = 0;
		j = traps[j-1].first;
		for (int i = 0; i < m; ++i) {
			if (soldier[i] >= j) ++r;
		}
		printf("%d\n", r);
	}
	for (int i = 0; i < k; ++i) {
		segUnion(i, t, k);
	}
}


#include <cstdio>
#include <utility>
#include <algorithm>
#include <vector>
#include <map>
using namespace std;

class segTree
{
	int* segarr;
	int n;
	int constructTreeUtil(int arr[], int si, int as, int ae);
	int queryUtil(int qs, int qe, int ss, int se, int si);
	void updateUtil(int i, int si, int ss, int se, int val, int arr[]);
public:
	segTree(int arr[], int N);
	void update(int i, int val, int arr[]);
	int query(int as, int ae);
};
segTree::segTree(int arr[], int N)
{
	n = N;
	int x = (int)(ceil(log2(n)));
	int s = 2 * (int)pow(2, x) - 1;
	segarr = new int[s];
	constructTreeUtil(arr, 0, 0, n - 1);
}
int segTree::constructTreeUtil(int arr[], int si, int as, int ae)
{
	if (as == ae)
	{
		segarr[si] = arr[as];
		return arr[as];
	}
	int mid = (as + ae) >> 1;
	int l = constructTreeUtil(arr, 2 * si + 1, as, mid);
	int r = constructTreeUtil(arr, 2 * si + 2, mid + 1, ae);
	int h = max(l, r);
	segarr[si] = h;
	return h;
}
int segTree::query(int qs, int qe)
{
	return queryUtil(qs, qe, 0, n - 1, 0);
}
int segTree::queryUtil(int qs, int qe, int ss, int se, int si)
{
	if (qs <= ss && qe >= se)
		return segarr[si];
	if (se < qs || ss > qe)
		return INT_MIN;
	int m = (ss + se) >> 1;
	int l = queryUtil(qs, qe, ss, m, 2 * si + 1);
	int r = queryUtil(qs, qe, m + 1, se, 2 * si + 2);
	return max(l, r);
}
void segTree::update(int i, int val, int arr[])
{
	return updateUtil(i, 0, 0, n - 1, val, arr);
}
void segTree::updateUtil(int i, int si, int ss, int se, int val, int arr[])
{
	if (ss == se)
	{
		arr[i] = val;
		segarr[si] = val;
		return;
	}
	int mid = (ss + se) >> 1;
	if (ss <= i && i <= mid)
		updateUtil(i, 2 * si + 1, ss, mid, val, arr);
	else
		updateUtil(i, 2 * si + 2, mid + 1, se, val, arr);
	segarr[si] = max(segarr[2 * si + 1], segarr[2 * si + 2]);

}

int const MAX = 200000 + 10;
pair<int, pair<int, int>> traps1[MAX];
pair<int, int> traps2[MAX];
int soldiers[MAX];
map<pair<int, int>, int> mp;
int a[MAX];

int bs(int k, int val) {
	if (val < traps2[0].first) return -1;
	int i = 0;
	int j = k - 1;
	int m;
	while (i <= j) {
		m = (i + j) >> 1;
		if (traps2[i].first > val) j = m - 1;
		else i = m + 1;
	}
	return i - 1;
}

int main() {
	int m, n, k, t; scanf("%d %d %d %d", &m, &n, &k, &t);
	for (int i = 0; i < m; ++i) scanf("%d", soldiers + i);
	for (int i = 0; i < k; ++i) {
		int li, ri, di; scanf("%d %d %d", &li, &ri, &di);
		traps1[i] = { di, {li, ri} };
		traps2[i] = { li, ri };
	}
	sort(traps1, traps1 + k,greater<pair<int,pair<int,int>>>());
	sort(traps2, traps2 + k);
	for (int i = 0; i < k; ++i) {
		mp[traps2[i]] = i;
	}
	for (int i = 0; i < k; ++i) {
		a[i] = -1;
	}
	for (int i = 0; i < k; ++i) {
	//	printf("tr1:%d %d %d\n", traps1[i].first, traps1[i].second.first,traps1[i].second.second);
	}
	segTree stree(a, k);
	t -= (n + 1);
	int i = 0;
	for (i = 0; i < k; ++i) {
	//	printf("%d\n", i);
		int li = traps1[i].second.first;
		int ri = traps1[i].second.second;
		int c = 0;
		for (int j = li-1; j <= ri;) {
			int i2 = bs(k, j+1);
		//	printf("j:%d i2b:%d ",j, i2);
			if (i2 != -1) i2 = stree.query(0, i2);
		//	printf("i2a:%d\n", i2);
			if (i2 != -1 && i2 > j)
				j = i2;
			else {
				j++;
				if (j <= ri) ++c;
			}

		}
		c = 2 * (c);
	//	printf("c:%d ", c);
		if (c <= t) {
			t -= c;
			stree.update(mp[traps1[i].second], ri, a);
		//	printf("q:%d %d\n", a[5],mp[traps1[i].second]);
		}
		else break;
	}
	int r = 0;
	i = traps1[i].first;
	for (int j = 0; j < m; ++j) {
		if (soldiers[j] >= i) ++r;
	}
	printf("%d", r);
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    #if 0
    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }
    #endif

    for (int m = 0; m < M; ++m)
    {
        int mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
        {
            cout << M - m << endl;
            return 0;
        }

    }
    //cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = max(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    int bb = 0, ee = M;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }

    cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << N << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }

    cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN], L[MAXN], R[MAXN], D[MAXN];

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> L[i] >> R[i] >> D[i];
        m1 = min(m1, D[i]);
    }

    if (m1 <= A[0])
    {
        cout << N << endl;
        return 0;
    }

    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0;
        for (int i = 0; i < K; ++i)
            if (D[i] > A[m] && R[i] > mm)
                mm = R[i];
        if (mm + mm + N + 1 <=  T)
            ee = m;
        else
            bb = m + 1;
    }

    cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    #if 0
    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }
    #endif

    for (int m = 0; m < M; ++m)
    {
        int mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += abs(R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
        {
            cout << M - m << endl;
            return 0;
        }

    }
    //cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }

    cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    #if 0
    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }
    #endif

    for (int m = 0; m < M; ++m)
    {
        int mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1;

        if (mm <= T)
        {
            cout << M - m << endl;
            return 0;
        }

    }
    //cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }
#if 0
    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }
#endif
    sort(R.begin(), R.end());

    #if 0
    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }
    #endif

    for (int m = 0; m < M; ++m)
    {
        int mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            p1 = max(p1, R[i].first - 1);
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1;

        if (mm <= T)
        {
            cout << M - m << endl;
            return 0;
        }

    }
    //cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    #if 0
    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }
    #endif

    for (int m = 0; m < M; ++m)
    {
        int mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            p1 = max(p1, R[i].first - 1);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1;

        if (mm <= T)
        {
            cout << M - m << endl;
            return 0;
        }

    }
    //cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(M);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << N << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;
        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.second <= p1 || R[i].second.first <= A[m]) continue;
            mm += R[i].first - p2;
            p1 = p2 = R[i].first;
            mm += (R[i].second.second - p1) * 2;
            p1 = R[i].second.second;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }

    cout << M - bb << endl;

    return 0;
}


#include <bits/stdc++.h>

using namespace std;

int M, N, K, T;

const int MAXN = 2e5 + 15;

int A[MAXN];

vector<pair<int, pair<int, int> > > R;

int main()
{
    ios::sync_with_stdio(false);
    cin >> M >> N >> K >> T;
    for (int i = 0; i < M; ++i)
        cin >> A[i];
    sort(A, A + M);

    R.resize(K);

    int m1 = 1e9;
    for (int i = 0; i < K; ++i)
    {
        cin >> R[i].first >> R[i].second.first >> R[i].second.second;
        m1 = min(m1, R[i].second.second);
    }

    if (m1 <= A[0])
    {
        cout << M << endl;
        return 0;
    }

    sort(R.begin(), R.end());

    #if 0
    int bb = 0, ee = M - 1;
    while (bb < ee)
    {
        int m = (bb + ee) / 2, mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += R[i].first - 1 - p2;
            p2 = R[i].first - 1;
            p1 = max(p1, p2);
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1 - p2;

        if (mm <= T)
            ee = m;
        else
            bb = m + 1;
    }
    #endif

    for (int m = 0; m < M; ++m)
    {
        int mm = 0, p1 = 0, p2 = 0;

        for (int i = 0; i < K; ++i)
        {
            p1 = max(p1, R[i].first - 1);
            if (R[i].second.first <= p1 || R[i].second.second <= A[m])
                continue;
            mm += (R[i].second.first - p1) * 2;
            p1 = R[i].second.first;
        }

        mm += N + 1;

        if (mm <= T)
        {
            cout << M - m << endl;
            return 0;
        }

    }
    //cout << M - bb << endl;

    return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};

Trap trap[MAXN];
void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a+m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int Check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;
	int id = 0;
	while(a[x] >= trap[id].d)
		id++;

	int cnt1 = 0;
	for(int i = id; i < k; i++)
		p1[cnt1++] = {trap[i].l, trap[i].r};
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int last = 0;
	int time_consumption = 0;
	for(int i = 0; i < cnt2; i++) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += (n + 1 - last);

	if(time_consumption <= t)
		return max(1, time_consumption);
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;

	int mid = (l + r)/2;
	if(Check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}
int main() {
	Read();
	a[m] = MAXN + 2;
	int ans = m - Bsearch(0, m);
	cout << ans << endl;
	for(int i = 0; i < 5; i++)
		cout << i << "=>" << Check(i) << endl;
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		if(d == a.d) {
			if(r == a.r)
				return l < a.l;
			else
				return r < a.r;
		}
		else
			return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};
Trap trap[MAXN];

void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a + m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;

	int id = k - 1;
	while(trap[id].d > a[x] && id >0)
		id--;
	x = id;
	if(x == k - 1)
		return 1;

	int cnt1 = 0;
	p1[cnt1++] = {trap[k-1].l ,trap[k-1].r};
	for(int i = k - 2; i >= x; i--) {
		if(p1[cnt1 - 1].first <= trap[i].r)
			p1[cnt1 - 1].first = trap[i].l;
		else
			p1[cnt1++] = {trap[i].l, trap[i].r};
	}
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int time_consumption = 0;
	int last = 0;
	for(int i = cnt2 - 1; i >= 0; i--) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += n - last - 1;

	if(time_consumption <= t)
		return 1;
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;
	int mid = (l + r)/2;

	if(check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}

int main() {
	Read();
	int ans = Bsearch(0, k - 1);
	printf("%d\n", ans);
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		if(d == a.d) {
			if(r == a.r)
				return l < a.l;
			else
				return r < a.r;
		}
		else
			return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};
Trap trap[MAXN];

void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a + m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;

	int id = k - 1;
	while(trap[id].d > a[x] && id >0)
		id--;
	x = id;
	if(x == k - 1)
		return 1;

	int cnt1 = 0;
	p1[cnt1++] = {trap[k-1].l ,trap[k-1].r};
	for(int i = k - 2; i >= x; i--) {
		if(p1[cnt1 - 1].first <= trap[i].r)
			p1[cnt1 - 1].first = trap[i].l;
		else
			p1[cnt1++] = {trap[i].l, trap[i].r};
	}
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int time_consumption = 0;
	int last = 0;
	for(int i = cnt2 - 1; i >= 0; i--) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += n - last - 1;

	if(time_consumption <= t)
		return 1;
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;
	int mid = (l + r + 1)/2;

	if(check(mid))
		return Bsearch(mid, r);
	else
		return Bsearch(l, mid - 1);
}

int main() {
	Read();
	int ans = Bsearch(0, k - 1);
	printf("%d\n", ans);
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		if(d == a.d) {
			if(r == a.r)
				return l < a.l;
			else
				return r < a.r;
		}
		else
			return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};
Trap trap[MAXN];

void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a + m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int check(int x) {
	int id = k - 1;
	while(trap[id].d != a[x])
		id--;
	x = id;
	if(x == k - 1)
		return 1;

	int cnt1 = 0;
	p1[cnt1++] = {trap[k-1].l ,trap[k-1].r};
	for(int i = k - 2; i >= x; i--) {
		if(p1[cnt1 - 1].first <= trap[i].r)
			p1[cnt1 - 1].first = trap[i].l;
		else
			p1[cnt1++] = {trap[i].l, trap[i].r};
	}
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int time_consumption = 0;
	int last = 0;
	for(int i = cnt2 - 1; i >= 0; i--) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += n - last - 1;

	if(time_consumption <= t)
		return 1;
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;
	int mid = (l + r + 1)/2;

	if(check(mid))
		return Bsearch(mid, r);
	else
		return Bsearch(l, mid - 1);
}

int main() {
	Read();
	int ans = Bsearch(0, k - 1);
	printf("%d\n", ans);
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};

Trap trap[MAXN];
void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a+m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int Check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;
	int id = 0;
	while(a[x] >= trap[id].d)
		id++;

	int cnt1 = 0;
	for(int i = id; i < k; i++)
		p1[cnt1++] = {trap[i].l, trap[i].r};
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int last = 0;
	int time_consumption = 0;
	for(int i = 0; i < cnt2; i++) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += (n + 1 - last);

	if(time_consumption <= t)
		return max(1, time_consumption);
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;

	int mid = (l + r)/2;
	if(Check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}
int main() {
	Read();
	a[m] = MAXN + 2;
	int ans = m - Bsearch(0, m);
	cout << ans << endl;
	if(m  == 72)
	for(int i = 0; i < 5; i++)
		cout << i << "=>" << Check(i) << endl;
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};

Trap trap[MAXN];
void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a+m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int Check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;
	int id = 0;
	while(a[x] >= trap[id].d)
		id++;

	int cnt1 = 0;
	for(int i = id; i < k; i++)
		p1[cnt1++] = {trap[i].l, trap[i].r};
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int last = 0;
	int time_consumption = 0;
	for(int i = 0; i < cnt2; i++) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += (n + 1 - last);

	if(time_consumption < t)
		return max(1, time_consumption);
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;

	int mid = (l + r)/2;
	if(Check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}
int main() {
	Read();
	a[m] = MAXN + 2;
	int ans = m - Bsearch(0, m);
	cout << ans << endl;
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		if(d == a.d) {
			if(r == a.r)
				return l < a.l;
			else
				return r < a.r;
		}
		else
			return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};
Trap trap[MAXN];

void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a + m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;

	int id = k - 1;
	while(trap[id].d != a[x] && id >0)
		id--;
	x = id;
	if(x == k - 1)
		return 1;

	int cnt1 = 0;
	p1[cnt1++] = {trap[k-1].l ,trap[k-1].r};
	for(int i = k - 2; i >= x; i--) {
		if(p1[cnt1 - 1].first <= trap[i].r)
			p1[cnt1 - 1].first = trap[i].l;
		else
			p1[cnt1++] = {trap[i].l, trap[i].r};
	}
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int time_consumption = 0;
	int last = 0;
	for(int i = cnt2 - 1; i >= 0; i--) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += n - last - 1;

	if(time_consumption <= t)
		return 1;
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;
	int mid = (l + r + 1)/2;

	if(check(mid))
		return Bsearch(mid, r);
	else
		return Bsearch(l, mid - 1);
}

int main() {
	Read();
	int ans = Bsearch(0, k - 1);
	printf("%d\n", ans);
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};

Trap trap[MAXN];
void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a+m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int Check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	int id = 0;
	while(a[x] >= trap[id].d)
		id++;

	int cnt1 = 0;
	for(int i = id; i < k; i++)
		p1[cnt1++] = {trap[i].l, trap[i].r};
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = max(p2[cnt2-1].second, p1[i].second);
		else
			p2[cnt2++] = p1[i];

	int last = 0;
	int time_consumption = 0;
	for(int i = 0; i < cnt2; i++) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += (n + 1 - last);

	if(time_consumption <= t)
		return max(1, time_consumption);
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;

	int mid = (l + r)/2;
	if(Check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}
int main() {
	Read();
	a[m] = MAXN + 2;
	int ans = m - Bsearch(0, m);
	cout << ans << endl;
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};

Trap trap[MAXN];
void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a+m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int Check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;
	int id = 0;
	while(a[x] >= trap[id].d)
		id++;

	int cnt1 = 0;
	for(int i = id; i < k; i++)
		p1[cnt1++] = {trap[i].l, trap[i].r};
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int last = 0;
	int time_consumption = 0;
	for(int i = 0; i < cnt2; i++) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += (n + 1 - last);

	if(time_consumption <= t)
		return max(1, time_consumption);
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;

	int mid = (l + r)/2;
	if(Check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}
int main() {
	Read();
	a[m] = MAXN + 2;
	int ans = m - Bsearch(0, m);
	cout << ans << endl;
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		if(d == a.d) {
			if(r == a.r)
				return l < a.l;
			else
				return r < a.r;
		}
		else
			return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};
Trap trap[MAXN];

void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a + m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int check(int x) {
	if(x == k - 1)
		return 1;

	int cnt1 = 0;
	p1[cnt1++] = {trap[k-1].l ,trap[k-1].r};
	for(int i = k - 2; i >= x; i--) {
		if(p1[cnt1 - 1].first <= trap[i].r)
			p1[cnt1 - 1].first = trap[i].l;
		else
			p1[cnt1++] = {trap[i].l, trap[i].r};
	}
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int time_consumption = 0;
	int last = 0;
	for(int i = cnt2 - 1; i >= 0; i--) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += n - last - 1;

	if(time_consumption <= t)
		return 1;
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;
	int mid = (l + r + 1)/2;

	if(check(mid))
		return Bsearch(mid, r);
	else
		return Bsearch(l, mid - 1);
}

int main() {
	Read();
	int ans = Bsearch(0, k - 1);
	printf("%d\n", ans);
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		if(d == a.d) {
			if(r == a.r)
				return l < a.l;
			else
				return r < a.r;
		}
		else
			return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};
Trap trap[MAXN];

void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a + m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	if(a[x] < trap[0].d)
		return 0;

	int id = k - 1;
	while(trap[id].d > a[x] && id >0)
		id--;
	x = id;
	if(x == k - 1)
		return 1;

	int cnt1 = 0;
	p1[cnt1++] = {trap[k-1].l ,trap[k-1].r};
	for(int i = k - 2; i >= x; i--) {
		if(p1[cnt1 - 1].first <= trap[i].r)
			p1[cnt1 - 1].first = trap[i].l;
		else
			p1[cnt1++] = {trap[i].l, trap[i].r};
	}
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int time_consumption = 0;
	int last = 0;
	for(int i = cnt2 - 1; i >= 0; i--) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += n - last - 1;

	if(time_consumption <= t)
		return 1;
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;
	int mid = (l + r)/2;

	if(check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}

int main() {
	Read();
	a[k] = MAXN + 3;
	int ans = k - Bsearch(0, k);
	printf("%d\n", ans);
	return 0;
}


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

int m, n, k, t;
const int MAXN = 2e5 + 2;
int a[MAXN];

struct Trap {
	int l, r, d;
	Trap(int _l = 0, int _r = 0, int _d = 0) {
		l = _l;
		r = _r;
		d = _d;
	}
	bool operator < (const Trap a) const {
		return d < a.d;
	}
	void print() {
		printf("(%d, %d, %d)\n", l, r, d);
	}
};

Trap trap[MAXN];
void Read() {
	cin >> m >> n >> k >> t;
	for(int i = 0; i < m; i++)
		cin >> a[i];
	sort(a, a+m);

	int l, r, d;
	for(int i = 0; i < k; i++) {
		cin >> l >> r >> d;
		trap[i] = Trap(l, r, d);
	}
	sort(trap, trap + k);
}

pair<int, int> p1[MAXN], p2[MAXN];
int Check(int x) {
	if(a[x] >= trap[k - 1].d)
		return 1;
	int id = 0;
	while(a[x] >= trap[id].d)
		id++;

	int cnt1 = 0;
	for(int i = id; i < k; i++)
		p1[cnt1++] = {trap[i].l, trap[i].r};
	sort(p1, p1 + cnt1);
	int cnt2 = 0;
	p2[cnt2++] = p1[0];
	for(int i = 1; i < cnt1; i++)
		if(p2[cnt2 - 1].second >= p1[i].first)
			p2[cnt2 - 1].second = p1[i].second;
		else
			p2[cnt2++] = p1[i];

	int last = 0;
	int time_consumption = 0;
	for(int i = 0; i < cnt2; i++) {
		time_consumption += p2[i].first - last - 1 + 3*(p2[i].second - p2[i].first + 1);
		last = p2[i].second;
	}
	time_consumption += (n + 1 - last);

	if(time_consumption <= t)
		return max(1, time_consumption);
	else
		return 0;
}

int Bsearch(int l, int r) {
	if(l == r)
		return l;

	int mid = (l + r)/2;
	if(Check(mid))
		return Bsearch(l, mid);
	else
		return Bsearch(mid + 1, r);
}
int main() {
	Read();
	a[m] = MAXN + 2;
	int ans = m - Bsearch(0, m);
	cout << ans << endl;
	return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].y>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].z+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    b[0]=0;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",l);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",n-l+1);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",n-max(l,1)+1);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",l);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].y>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].z+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1<=t;
}
bool cmp(int x,int y){
    return x>y;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    b[0]=0;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1,cmp);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid;
        }else{
            r=mid-1;
        }
    }
    printf("%d\n",l);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid;
        }else{
            r=mid-1;
        }
    }
    printf("%d\n",r+1);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",r);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].y>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].z+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    b[0]=0;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",l);
    return 0;
}


#pragma GCC optimize(2)
#include<bits/stdc++.h>
//#define int long long
using namespace std;
const int N=2e5+10;
int m,n,k,tt,a[N],vis[N],L,R,cnt[N];
struct node{int l,r,d;}t[N];
int cmp(int a,int b){return a>b;}
inline int check(int mid){
	int low=a[mid],tot=0; memset(cnt,0,sizeof cnt);
	for(int i=1;i<=k;i++)	if(t[i].d>low){cnt[t[i].l]++,cnt[t[i].r+1]--;}
	for(int i=1;i<=n+1;i++)	cnt[i]+=cnt[i-1];
	for(int i=0;i<=n+1;i++)	tot+=(cnt[i]>=1);
	return tot*2+n+1<=tt;
}
signed main(){
	cin>>m>>n>>k>>tt; L=0,R=m;
	for(int i=1;i<=m;i++)	scanf("%d",&a[i]);
	for(int i=1;i<=k;i++)	scanf("%d %d %d",&t[i].l,&t[i].r,&t[i].d);
	sort(a+1,a+1+m,cmp);
	while(L<R){
		int mid=L+R+1>>1;
		if(check(mid))	L=mid;
		else	R=mid-1;
	}
	cout<<L<<endl;
	return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1<=t;
}
bool cmp(int x,int y){
    return x>y;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1,cmp);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid;
        }else{
            r=mid-1;
        }
    }
    printf("%d\n",l);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].y>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].z+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1<=t;
}
bool cmp(int x,int y){
    return x>y;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=0,r=n;
    b[0]=0;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b,b+n+1,cmp);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r+1)/2;
        if(solve(mid)){
            l=mid;
        }else{
            r=mid-1;
        }
    }
    printf("%d\n",l+1);
    return 0;
}


#include <algorithm>
#include <cmath>
#include <cstdio>
#include <cstring>
#include <iostream>
#include <map>
#include <queue>
#include <stack>
#include <stdlib.h>
#include <string>
#include <vector>
using namespace std;
#define inf 1000000007
const int max_n = 2e5+10;
typedef long long ll;
struct node{
    int x,y,z;
}a[max_n];
int b[max_n];
int cnt[max_n];
int n,m,k,t;
int solve(int mid){
    memset(cnt,0,sizeof(cnt));
    for(int i=0;i<k;++i){
        if(a[i].z>b[mid]){
            cnt[a[i].x]++;
            cnt[a[i].y+1]--;
        }
    }
    for(int i=1;i<=m+1;++i){
        cnt[i]+=cnt[i-1];
    }
    int sum=0;
    for(int i=0;i<=m+1;++i){
        sum+=(cnt[i]>=1);
    }
    return sum*2+m+1>=t;
}
int main(){
    scanf("%d%d%d%d",&n,&m,&k,&t);
    int l=1,r=n+1;
    int x,y,z;
    for(int i=1;i<=n;++i){
        scanf("%d",&b[i]);
    }
    sort(b+1,b+n+1);
    for(int i=0;i<k;++i){
        scanf("%d%d%d",&a[i].x,&a[i].y,&a[i].z);
    }
    while(l<r){
        int mid=(l+r)/2;
        if(solve(mid)){
            l=mid+1;
        }else{
            r=mid;
        }
    }
    printf("%d\n",n-l+1);
    return 0;
}


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

bool works(ll n,ll m,ll k,ll t, ll s[], vector<pair<ll,pair<ll,ll> > > traps, ll sc){
	ll minsold;
	if(sc>0){
		minsold=s[sc-1];
	}
	else{
		minsold=INT_MAX;
	}

	ll trapspointer=0;
	ll currtime=0;
	ll longestgone=0;

	for(int i=0;i<=n;i++){
		while(trapspointer<k && traps[trapspointer].first==i+1){
			if(longestgone<traps[trapspointer].second.first && minsold<traps[trapspointer].second.second){
				longestgone=traps[trapspointer].second.first;
				currtime+=(traps[trapspointer].second.first-i)*2;
			}
			trapspointer++;
		}
		currtime++;
		if(currtime>t){
			return false;
		}
	}
	return true;
}

int main(){

	#ifndef ONLINE_JUDGE
    	freopen("input", "r", stdin);
    	freopen("output", "w", stdout);
    	freopen("error", "w", stderr);
	#endif
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // binsearch the number of soldiers, act greedy for a soldier count

    ll n,m,k,t;
    cin>>n>>m>>k>>t;

    ll s[n];
    for(int i=0;i<n;i++){
    	cin>>s[i];
    }
    sort(s,s+n);
    reverse(s,s+n);

    vector<pair<ll,pair<ll,ll> > > traps;
    for(int i=0;i<k;i++){
    	pair<ll,pair<ll,ll> > asdf;
    	cin>>asdf.first>>asdf.second.first>>asdf.second.second;
    	traps.push_back(asdf);
    }

    sort(traps.begin(),traps.end());

    ll bmin=0;
    ll bmax=n;
    while(bmin<bmax){
    	ll bmid=ceil(((double)bmax+bmin)/2.0);
    	// cout<<bmin<<" "<<bmax<<" "<<bmid<<endl;
    	if(works(n,m,k,t,s,traps,bmid)){
    		bmin=bmid;
    	}
    	else{
    		bmax=bmid-1;
    	}
    }

    cout<<bmin<<endl;

}


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

bool works(ll n,ll m,ll k,ll t, ll s[], vector<pair<ll,pair<ll,ll> > > traps, ll sc){
	ll minsold;
	if(sc>0){
		minsold=s[sc-1];
	}
	else{
		minsold=INT_MAX;
	}

	ll trapspointer=0;
	ll currtime=0;
	ll longestgone=0;

	for(int i=0;i<=n;i++){
		while(trapspointer<k && traps[trapspointer].first==i+1){
			if(longestgone<traps[trapspointer].second.first && minsold<traps[trapspointer].second.second){
				longestgone=traps[trapspointer].second.first;
				currtime+=(traps[trapspointer].second.first-i)*2;
			}
			trapspointer++;
		}
		currtime++;
		longestgone=max(longestgone,(ll)i);
		if(currtime>t){
			return false;
		}
	}
	return true;
}

int main(){

	#ifndef ONLINE_JUDGE
    	freopen("input", "r", stdin);
    	freopen("output", "w", stdout);
    	freopen("error", "w", stderr);
	#endif
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // binsearch the number of soldiers, act greedy for a soldier count

    ll n,m,k,t;
    cin>>n>>m>>k>>t;

    ll s[n];
    for(int i=0;i<n;i++){
    	cin>>s[i];
    }
    sort(s,s+n);
    reverse(s,s+n);

    vector<pair<ll,pair<ll,ll> > > traps;
    for(int i=0;i<k;i++){
    	pair<ll,pair<ll,ll> > asdf;
    	cin>>asdf.first>>asdf.second.first>>asdf.second.second;
    	traps.push_back(asdf);
    }

    sort(traps.begin(),traps.end());

    ll bmin=0;
    ll bmax=n;
    while(bmin<bmax){
    	ll bmid=ceil(((double)bmax+bmin)/2.0);
    	if(works(n,m,k,t,s,traps,bmid)){
    		bmin=bmid;
    	}
    	else{
    		bmax=bmid-1;
    	}
    }
    // cout<<bmin<<" "<<bmax<<endl;

    cout<<bmax<<endl;

}


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

bool mysort(pair<ll,pair<ll,ll> > a, pair<ll,pair<ll,ll> > b){
	a.second.first=-a.second.first;
	b.second.first=-b.second.first;

	a.second.second=-a.second.second;
	b.second.second=-b.second.second;

	return a<b;
}

bool works(ll n,ll m,ll k,ll t, ll s[], vector<pair<ll,pair<ll,ll> > > traps, ll sc){
	ll minsold;
	if(sc>0){
		minsold=s[sc-1];
	}
	else{
		minsold=INT_MAX;
	}

	ll trapspointer=0;
	ll currtime=0;
	ll longestgone=0;

	for(int i=0;i<=n;i++){
		longestgone=max(longestgone,(ll)i);
		while(trapspointer<k && traps[trapspointer].first==i+1){
			if(longestgone<traps[trapspointer].second.first && minsold<traps[trapspointer].second.second){
				longestgone=max(longestgone,traps[trapspointer].second.first);
				currtime+=(traps[trapspointer].second.first-i)*2;
			}
			trapspointer++;
		}
		currtime++;
		if(currtime>t){
			return false;
		}
	}
	return true;
}

int main(){

	#ifndef ONLINE_JUDGE
    	freopen("input", "r", stdin);
    	freopen("output", "w", stdout);
    	freopen("error", "w", stderr);
	#endif
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // binsearch the number of soldiers, act greedy for a soldier count

    ll n,m,k,t;
    cin>>n>>m>>k>>t;

    ll s[n];
    for(int i=0;i<n;i++){
    	cin>>s[i];
    }
    sort(s,s+n);
    reverse(s,s+n);

    vector<pair<ll,pair<ll,ll> > > traps;
    for(int i=0;i<k;i++){
    	pair<ll,pair<ll,ll> > asdf;
    	cin>>asdf.first>>asdf.second.first>>asdf.second.second;
    	traps.push_back(asdf);
    }

    sort(traps.begin(),traps.end(),mysort);

    ll bmin=0;
    ll bmax=n;
    while(bmin<bmax){
    	ll bmid=ceil(((double)bmax+bmin)/2.0);
    	if(works(n,m,k,t,s,traps,bmid)){
    		bmin=bmid;
    	}
    	else{
    		bmax=bmid-1;
    	}
    }
    // cout<<bmin<<" "<<bmax<<endl;

    cout<<bmax<<endl;

}


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

bool mysort(pair<ll,pair<ll,ll> > a, pair<ll,pair<ll,ll> > b){
	return (a.first<b.first || (a.first == b.first && a.second.first > b.second.first));
}

bool works(ll n,ll m,ll k,ll t, ll s[], vector<pair<ll,pair<ll,ll> > > traps, ll sc){
	ll minsold;
	if(sc>0){
		minsold=s[sc-1];
	}
	else{
		minsold=INT_MAX;
	}

	ll trapspointer=0;
	ll currtime=0;
	ll longestgone=0;

	for(int i=0;i<=n;i++){
		longestgone=max(longestgone,(ll)i);
		while(trapspointer<k && traps[trapspointer].first==i+1){
			if(longestgone<traps[trapspointer].second.first && minsold<traps[trapspointer].second.second){
				longestgone=max(longestgone,traps[trapspointer].second.first);
				currtime+=(traps[trapspointer].second.first-i)*2;
			}
			trapspointer++;
		}
		currtime++;
		if(currtime>t){
			return false;
		}
	}
	return true;
}

int main(){

	#ifndef ONLINE_JUDGE
    	freopen("input", "r", stdin);
    	freopen("output", "w", stdout);
    	freopen("error", "w", stderr);
	#endif
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // binsearch the number of soldiers, act greedy for a soldier count

    ll n,m,k,t;
    cin>>n>>m>>k>>t;

    ll s[n];
    for(int i=0;i<n;i++){
    	cin>>s[i];
    }
    sort(s,s+n);
    reverse(s,s+n);

    vector<pair<ll,pair<ll,ll> > > traps;
    for(int i=0;i<k;i++){
    	pair<ll,pair<ll,ll> > asdf;
    	cin>>asdf.first>>asdf.second.first>>asdf.second.second;
    	traps.push_back(asdf);
    }

    sort(traps.begin(),traps.end(),mysort);

    // for(int i=0;i<k;i++){
    // 	cout<<traps[i].first<<" "<<traps[i].second.first<<endl;
    // }

    ll bmin=0;
    ll bmax=n;
    while(bmin<bmax){
    	ll bmid=ceil(((double)bmax+bmin)/2.0);
    	if(works(n,m,k,t,s,traps,bmid)){
    		bmin=bmid;
    	}
    	else{
    		bmax=bmid-1;
    	}
    }
    // cout<<bmin<<" "<<bmax<<endl;

    cout<<bmax<<endl;

}


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

bool mysort(pair<ll,pair<ll,ll> > a, pair<ll,pair<ll,ll> > b){
	a.second.first=-a.second.first;
	b.second.first=-b.second.first;

	a.second.second=-a.second.second;
	b.second.second=-b.second.second;

	return a<b;
}

bool works(ll n,ll m,ll k,ll t, ll s[], vector<pair<ll,pair<ll,ll> > > traps, ll sc){
	ll minsold;
	if(sc>0){
		minsold=s[sc-1];
	}
	else{
		minsold=INT_MAX;
	}

	ll trapspointer=0;
	ll currtime=0;
	ll longestgone=0;

	for(int i=0;i<=m;i++){
		longestgone=max(longestgone,(ll)i);
		// cout<<i<<" "<<minsold<<" "<<currtime<<endl;
		while(trapspointer<k && traps[trapspointer].first==i+1){
			if(longestgone<traps[trapspointer].second.first && minsold<traps[trapspointer].second.second){
				currtime+=(traps[trapspointer].second.first-longestgone)*2;
				longestgone=max(longestgone,traps[trapspointer].second.first);
			}
			trapspointer++;
		}
		currtime++;
		if(currtime>t){
			return false;
		}
	}
	return true;
}

int main(){

	#ifndef ONLINE_JUDGE
    	freopen("input", "r", stdin);
    	freopen("output", "w", stdout);
    	freopen("error", "w", stderr);
	#endif
	ios_base::sync_with_stdio(false);
    cin.tie(NULL);

    // binsearch the number of soldiers, act greedy for a soldier count

    ll n,m,k,t;
    cin>>n>>m>>k>>t;

    ll s[n];
    for(int i=0;i<n;i++){
    	cin>>s[i];
    }
    sort(s,s+n);
    reverse(s,s+n);

    vector<pair<ll,pair<ll,ll> > > traps;
    for(int i=0;i<k;i++){
    	pair<ll,pair<ll,ll> > asdf;
    	cin>>asdf.first>>asdf.second.first>>asdf.second.second;
    	traps.push_back(asdf);
    }

    sort(traps.begin(),traps.end(),mysort);

    ll bmin=0;
    ll bmax=n;
    while(bmin<bmax){
    	ll bmid=ceil(((double)bmax+bmin)/2.0);
    	// cout<<bmin<<" "<<bmax<<" "<<bmid<<endl;
    	if(works(n,m,k,t,s,traps,bmid)){
    		bmin=bmid;
    	}
    	else{
    		bmax=bmid-1;
    	}
    }
    // cout<<bmin<<" "<<bmax<<endl;

    cout<<bmin<<endl;

}