#include <bits/stdc++.h>

using namespace std;

#define For(i,a,b) for (int i = (a), _b = (b); i <= _b; i++)
#define sz(a) ((int)a.size())
#define Rep(i, n) for (int i = 0, _n = (n); i < _n; i++)
const int maxn = 200000 + 123;
long long n, m;
const long long INF = 1e18;
long long x, y;

struct node {
	long long value[maxn * 12];
	int n;
	void build(int ign, int n) {
		this->n = n;
		fill(value, value + (maxn * 12), -INF);
	}
	/*
	node() {}
	node(int new_lo, int new_hi) {
		lo = new_lo;
		hi = new_hi;
		left = nullptr;
		right = nullptr;
		value = -INF;
	}*/
	void update(int cur, int L, int R, int pos, long long new_value) {
		if (L > pos || R < pos) return;
		if (L == R) {
			value[cur] = max(value[cur], new_value);
			return;
		}
		int mid = (L + R) / 2;
		update(cur * 2, L, mid, pos, new_value);
		update(cur * 2 + 1, mid + 1, R, pos, new_value);
		value[cur] = max(value[cur * 2], value[cur * 2 + 1]);
	}
	void update(int pos, long long new_value) {
		update(1, 0, n - 1, pos, new_value); 
	}
	
	long long query(int cur, int L, int R, int l, int r) {
		if (L > r || R < l) return -INF;
		if (l <= L && R <= r) return value[cur];
		int mid = (L + R) / 2;
		return max(query(cur * 2, L, mid, l, r), 
			query(cur * 2 + 1, mid + 1, R, l, r));
	}
	long long query(int L, int R) {
		return query(1, 0, n - 1, L, R);
	}

} treeFirst[3], treeSecond[3], tree;

typedef pair<int,int> pt;
struct segment{
	int color;
	long long u, v;
	
	void read() {
		cin >> color >> u >> v;
		--color;
		++v;
	}
	
	bool operator < (const segment b) const {
		return u < b.u;
	}
} a[maxn];

vector<int> coor;
int nc;
void readData() {
	cin >> n >> m >> x >> y; y += x;
	For(i,1,m) a[i].read();
	
	coor.push_back(n);
	coor.push_back(n + 1);
	coor.push_back(1);
	for(int i = 1; i <= m; i++) {
		coor.push_back(a[i].u);
		coor.push_back(a[i].v);
		coor.push_back(a[i].v - 1);
	}
	sort(coor.begin(), coor.end());
	nc = unique(coor.begin(), coor.end()) - coor.begin();
	coor.resize(nc);
	
}


long long dp[maxn];

void maximize(long long &a, long long b) {
	if (a < b) a = b;
}


int l[maxn], r[maxn];

void process() {
	//cout << n << endl;
	sort(a + 1, a + 1 + m);
	Rep(i, 3) treeFirst[i].build(0, nc - 1);
	Rep(i, 3) treeSecond[i].build(0, nc - 1);
	tree.build(0, nc - 1);
	
	For(i,1,m) dp[i] = -INF;
	For(i,1,m) l[i] = a[i].u, r[i] = a[i].v;

	For(i,1,m) {
		long long mx = 0;
		
		int cL = lower_bound(coor.begin(), coor.end(), a[i].u) 
			- coor.begin();
		int cR = lower_bound(coor.begin(), coor.end(), a[i].v) 
			- coor.begin();
		Rep(c, 3) {
			maximize(mx, tree.query(0, cL));
		}
		mx += (r[i] - l[i]) * x;
		maximize(dp[i], mx);
		//cout << i << ' ' << dp[i] << endl;
		
		
		Rep(c, 3) {
			if (c != a[i].color) {
				maximize(dp[i], treeFirst[c].query(cL, cR - 1) 
						+ r[i] * x + l[i] * y);
			}  else {
				maximize(dp[i], treeSecond[c].query(cL, cR - 1)
						+ r[i] * x);
			}
			//cout << i << ' ' << dp[i] << endl;
		}
		//cout << i << ' ' << dp[i] << endl;
		
		tree.update(cR, dp[i]);
		treeFirst[a[i].color].update(cR, dp[i] - r[i] * (x + y));
		treeSecond[a[i].color].update(cR, dp[i] - r[i] * x);
	}
	
	long long ans = 0;
	For(i,1,m) maximize(ans, dp[i]);
	
	cout << ans << endl;
}

int main(){
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);
	
	//freopen("input.txt", "r", stdin);
	readData();
	process();
	
	return 0;
}



Measured memory_bytes: 144548