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

#define REP(i,n) for(ll i=0;i<(n);i++)
#define ALL(v) v.begin,v.end()
using ll=long long;


struct RangeMaxQuery {
  using type = ll;
  static type id() { return -1e17; }
  static type op(const type &lhs, const type &rhs) { return max(lhs, rhs); }
};

template<typename M>
class SegmentTree {
  using T = typename M::type;
  int n;
  vector<T> node;

public:
  SegmentTree(const vector<T> &v) {
    n = 1;
    while (n < int(v.size())) n *= 2;
    node.resize(2 * n, M::id());

    for (int i = 0; i < (int) v.size(); i++) node[i + n] = v[i];
    for (int i = n - 1; i >= 0; i--) {
      node[i] = M::op(node[2 * i], node[2 * i + 1]);
    }
  }

  SegmentTree(int _n) {
    n = 1;
    while (n < _n) n *= 2;
    node.resize(2 * n, M::id());
  }

  // seg[x] = val
  void update(int x, T val) {
    x += n;
    node[x] = val;
    while (x >>= 1) {
      node[x] = M::op(node[2 * x], node[2 * x + 1]);
    }
  }

  // seg[x] = oop(seg[x], val)
  void operation(int x, T val) {
    x += n;
    node[x] = M::op(node[x], val);
    while (x >>= 1) {
      node[x] = M::op(node[2 * x], node[2 * x + 1]);
    }
  }

  // [l, r)
  T query(int l, int r) {
    l += n;
    r += n;
    T retl = M::id(), retr = M::id();
    while (l < r) {
      if (l & 1) retl = M::op(retl, node[l++]);
      if (r & 1) retr = M::op(node[--r], retr);
      l >>= 1;
      r >>= 1;
    }
    return M::op(retl, retr);
  }
};


struct CLR{
  int c,l,r;
};

map<int,ll> compress(vector<int> vs){
  sort(vs.begin(),vs.end());
  vs.erase(unique(vs.begin(),vs.end()),vs.end());
  map<int,ll> res;
  for(int i=0;i<vs.size();i++){
    res[vs[i]]=i;
  }
  return res;
}

using RMQ=SegmentTree<RangeMaxQuery>;

const ll INF=1e17;
int main(){
  ll n;
  int m;
  ll x,y;
  cin>>n>>m>>x>>y;

  vector<CLR> clr(m);
  for(int i=0;i<m;i++){
    cin>>clr[i].c>>clr[i].l>>clr[i].r;
    clr[i].c--;
    clr[i].l--;
  }

  auto cmp=[&](CLR lhs,CLR rhs){
    return lhs.l<rhs.l;
  };
  
  sort(clr.begin(),clr.end(),cmp);

  map<int,ll> mp;
  {
    vector<int> vs;
    vs.push_back(0);
    for(int i=0;i<m;i++){
      vs.push_back(clr[i].l);
      vs.push_back(clr[i].r);
    }
    mp=compress(vs);
  }

  vector<RMQ> simple;
  for(int i=0;i<3;i++) simple.emplace_back(mp.size());
  for(int i=0;i<3;i++) simple[i].update(0,0);
  
  vector<RMQ> hennano;
  for(int i=0;i<3;i++) hennano.emplace_back(mp.size());
  for(int i=0;i<3;i++) hennano[i].update(0,0);
  
  vector<RMQ> onnaji;
  for(int i=0;i<3;i++) onnaji.emplace_back(mp.size());
  for(int i=0;i<3;i++) onnaji[i].update(0,0);

  ll res=-INF;
  for(auto& e:clr){
    ll score=-INF;
    for(int i=0;i<3;i++){
     ll v1=hennano[i].query(mp[e.l],mp[e.r]+1)+e.l*(y+2*x)+x*(e.r-e.l);
     ll v0=simple[i].query(0,mp[e.l]+1)+x*(e.r-e.l);
     score=max({score,v0,v1});
    }
    ll v=onnaji[e.c].query(mp[e.l],mp[e.r]+1)+e.l*x+x*(e.r-e.l);
    score=max(score,v);
    res=max(res,score);

    if(score>simple[e.c].query(mp[e.r],mp[e.r]+1)){
      simple[e.c].update(mp[e.r],score);
      hennano[e.c].update(mp[e.r],score-e.r*(2*x+y));
      onnaji[e.c].update(mp[e.r],score-e.r*x);
    }
    
  }
  
  cout<<res<<endl;
  
  return 0;
}



Measured memory_bytes: 104000