#include <bits/stdc++.h>
using namespace std;
struct station_t {
  long long a, b, c;
};
struct solver_t {
  vector<station_t> st;
  int total_ns, total_nt, k;
  solver_t(const vector<station_t> &_stations, int _nt, int _k)
      : st(_stations), total_ns(st.size()), total_nt(_nt), k(_k) {}
  struct dp1_t {
    long long ntrain;
    long long total_people;
  };
  struct dp2_t {
    long long ntrain;
    long long people_last;
  };
  vector<vector<array<dp1_t, 2>>> dp1_memo;
  vector<vector<array<dp2_t, 2>>> dp2_memo;
  dp1_t solve_dp1(int ns, int nt, bool use_a) {
    dp1_t &res = dp1_memo[ns][nt][use_a];
    if (res.ntrain != -1LL) return res;
    if (ns == 0) return res = {0LL, 0LL};
    station_t &last_st = st[ns - 1];
    if (nt == 0) {
      dp1_t sub_res = solve_dp1(ns - 1, 0, use_a);
      return res = {sub_res.ntrain,
                    sub_res.total_people + (use_a ? last_st.a : last_st.b)};
    }
    res = {LLONG_MAX, -1LL};
    {
      long long final_value =
          (use_a ? last_st.a : last_st.b) + (long long)nt * last_st.b;
      if (final_value <= last_st.c) {
        dp1_t sub_res = solve_dp1(ns - 1, nt, use_a);
        if (sub_res.ntrain != LLONG_MAX) {
          dp1_t cand = {sub_res.ntrain, sub_res.total_people + final_value};
          if (cand.ntrain < res.ntrain) res = cand;
        }
      }
    }
    for (int t = 0; t < nt; ++t) {
      dp2_t upper_res = solve_dp2(ns, t + 1, use_a);
      if (upper_res.ntrain == LLONG_MAX) continue;
      dp1_t lower_res = solve_dp1(ns - 1, nt - 1 - t, false);
      if (lower_res.ntrain == LLONG_MAX) continue;
      long long temp_value =
          upper_res.people_last + (long long)(nt - 1 - t) * last_st.b;
      long long exceeds = max(temp_value - last_st.c, 0LL);
      long long extra_train = (exceeds + (k - 1)) / k;
      long long max_extra_train = (upper_res.people_last - last_st.b) / k;
      if (extra_train > max_extra_train) continue;
      temp_value -= extra_train * k;
      assert(temp_value >= last_st.b);
      dp1_t cand = {upper_res.ntrain + lower_res.ntrain + extra_train,
                    lower_res.total_people + temp_value};
      if (cand.ntrain < res.ntrain) res = cand;
    }
    return res;
  }
  dp2_t solve_dp2(int ns, int nt, bool use_a) {
    assert(ns > 0 && nt > 0);
    dp2_t &res = dp2_memo[ns][nt][use_a];
    if (res.ntrain != -1LL) return res;
    res = {LLONG_MAX, -1LL};
    station_t &last_st = st[ns - 1];
    {
      dp1_t sub_res = solve_dp1(ns - 1, nt - 1, use_a);
      if (sub_res.ntrain != LLONG_MAX) {
        long long temp_value =
            (use_a ? last_st.a : last_st.b) + (long long)(nt - 1) * last_st.b;
        if (temp_value <= last_st.c) {
          long long extra_train = (sub_res.total_people + k - 1) / k;
          long long residual = extra_train * k - sub_res.total_people;
          if (temp_value >= residual) {
            temp_value -= residual;
            long long exceeding =
                max((temp_value + last_st.b) - last_st.c, 0LL);
            long long extra_train_2 = (exceeding + k - 1) / k;
            temp_value -= extra_train_2 * k;
            if (temp_value >= 0) {
              temp_value += last_st.b;
              assert(temp_value <= last_st.c);
              dp2_t cand = {sub_res.ntrain + extra_train + extra_train_2,
                            temp_value};
              if (cand.ntrain < res.ntrain) res = cand;
            }
          }
        }
      }
    }
    for (int t = 0; t < nt - 1; ++t) {
      dp2_t upper_res = solve_dp2(ns, t + 1, use_a);
      if (upper_res.ntrain == LLONG_MAX) continue;
      dp1_t mid_res = solve_dp1(ns - 1, nt - t - 2, false);
      if (mid_res.ntrain == LLONG_MAX) continue;
      assert(upper_res.people_last >= last_st.b);
      long long max_extra_train_1 = (upper_res.people_last - last_st.b) / k;
      long long temp_value =
          upper_res.people_last + (long long)(nt - t - 2) * last_st.b;
      long long exceeding_1 = max(temp_value - last_st.c, 0LL);
      long long extra_train_1 = (exceeding_1 + k - 1) / k;
      if (extra_train_1 > max_extra_train_1) continue;
      temp_value -= extra_train_1 * k;
      long long extra_train_2 = (mid_res.total_people + k - 1) / k;
      long long residual = extra_train_2 * k - mid_res.total_people;
      if (temp_value < residual) continue;
      temp_value -= residual;
      long long exceeding_3 = max((temp_value + last_st.b) - last_st.c, 0LL);
      long long extra_train_3 = (exceeding_3 + k - 1) / k;
      temp_value -= extra_train_3 * k;
      if (temp_value < 0) continue;
      temp_value += last_st.b;
      assert(temp_value <= last_st.c);
      dp2_t cand = {upper_res.ntrain + mid_res.ntrain + extra_train_1 +
                        extra_train_2 + extra_train_3,
                    temp_value};
      if (cand.ntrain < res.ntrain) res = cand;
    }
    return res;
  }
  long long solve() {
    dp1_memo.assign(
        total_ns + 1,
        vector<array<dp1_t, 2>>(total_nt + 1,
                                array<dp1_t, 2>{{{-1LL, -1LL}, {-1LL, -1LL}}}));
    dp2_memo.assign(
        total_ns + 1,
        vector<array<dp2_t, 2>>(total_nt + 1,
                                array<dp2_t, 2>{{{-1LL, -1LL}, {-1LL, -1LL}}}));
    return solve_dp1(total_ns, total_nt, true).ntrain;
  }
};
int main() {
  int ns, nt, k;
  scanf("%d %d %d", &ns, &nt, &k);
  vector<station_t> stations(ns);
  for (int i = 0; i < ns; ++i)
    scanf("%lld %lld %lld", &stations[i].a, &stations[i].b, &stations[i].c);
  stations.push_back({(long long)(k - 1) * nt, 0LL, (long long)(k - 1) * nt});
  ns = stations.size();
  solver_t solver(stations, nt, k);
  printf("%lld\n", solver.solve());
  return 0;
}
