#include <bits/stdc++.h>
#pragma GCC optimize("O3")
#pragma GCC target("sse4")
using namespace std;
template <class T>
bool ckmin(T& a, const T& b) {
  return b < a ? a = b, 1 : 0;
}
template <class T>
bool ckmax(T& a, const T& b) {
  return a < b ? a = b, 1 : 0;
}
mt19937 rng(chrono::steady_clock::now().time_since_epoch().count());
const int MOD = 1000000007;
const char nl = '\n';
const int MX = 100001;
const long long identity = 2e9;
const long long SZ = 131072 * 4;
long long sum[2 * SZ], lazy[2 * SZ];
long long combine(long long A, long long B) { return min(A, B); }
long long combineUpd(long long A, long long B) { return A + B; }
void push(int index, long long L, long long R) {
  sum[index] = combineUpd(sum[index], lazy[index]);
  if (L != R)
    lazy[2 * index] = combineUpd(lazy[2 * index], lazy[index]),
             lazy[2 * index + 1] = combineUpd(lazy[2 * index + 1], lazy[index]);
  lazy[index] = 0;
}
void pull(int index) {
  sum[index] = combine(sum[2 * index], sum[2 * index + 1]);
}
long long query(int lo, int hi, int index = 1, long long L = 0,
                long long R = SZ - 1) {
  push(index, L, R);
  if (lo > R || L > hi) return identity;
  if (lo <= L && R <= hi) return sum[index];
  int M = (L + R) / 2;
  return combine(query(lo, hi, 2 * index, L, M),
                 query(lo, hi, 2 * index + 1, M + 1, R));
}
void update(int lo, int hi, long long increase, int index = 1, long long L = 0,
            long long R = SZ - 1) {
  push(index, L, R);
  if (hi < L || R < lo) return;
  if (lo <= L && R <= hi) {
    lazy[index] = increase;
    push(index, L, R);
    return;
  }
  int M = (L + R) / 2;
  update(lo, hi, increase, 2 * index, L, M);
  update(lo, hi, increase, 2 * index + 1, M + 1, R);
  pull(index);
}
struct F {
  int T;
  long long cap;
  long long cost;
  int pos;
};
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  int T;
  cin >> T;
  for (int i = 0; i < (2 * SZ); i++) sum[i] = 0, lazy[i] = 0;
  while (T--) {
    int N, M, C, I;
    cin >> N >> M >> C >> I;
    vector<F> friends;
    friends.push_back({0, I, 0, 0});
    friends.push_back({M, 0, (long long)1e9, 0});
    for (int i = 0; i < (N); i++) {
      int X, Y, Z;
      cin >> X >> Y >> Z;
      friends.push_back({X, Y, Z, 0});
    }
    multiset<pair<long long, long long> > S;
    sort(friends.begin(), friends.end(),
         [](const F& a, const F& b) -> bool { return a.T < b.T; });
    N = (int)(friends).size();
    long long cs = 0, ans = 0;
    for (int i = 0; i < (N); i++) {
      cs += friends[i].cap;
      S.insert({friends[i].cost, friends[i].cap});
      while (cs > C) {
        long long curCnt = S.rbegin()->second;
        long long curCost = S.rbegin()->first;
        if (curCnt > cs - C) {
          S.erase(S.find(*S.rbegin()));
          curCnt -= cs - C;
          cs = C;
          S.insert({curCost, curCnt});
        } else {
          cs -= curCnt;
          S.erase(S.find(*S.rbegin()));
        }
      }
      long long need = 0;
      if (i < N - 1) need = friends[i + 1].T - friends[i].T;
      while (need > 0) {
        if (cs == 0) {
          cout << -1 << nl;
          goto done;
        }
        long long curCnt = S.begin()->second;
        long long curCost = S.begin()->first;
        if (curCnt > need) {
          S.erase(S.begin());
          curCnt -= need;
          ans += need * curCost;
          cs -= need;
          need = 0;
          S.insert({curCost, curCnt});
        } else {
          need -= curCnt;
          cs -= curCnt;
          ans += curCnt * curCost;
          S.erase(S.begin());
        }
      }
    }
    cout << ans << nl;
  done:;
  }
  return 0;
}
