#include <iostream>
#include <vector>
#include <algorithm>
#include <set>
#include <ranges>
using namespace std;
typedef long long ll;
typedef pair<ll,ll> P;
typedef vector<ll> vi;
typedef vector<vi> vvi;
typedef vector<P> vp;
typedef vector<bool> vb;
#define rep(i,n) for(ll i = 0; i < (ll)(n); i++)
#define REP(i,k,n) for(ll i = (ll)(k); i < (ll)(n); i++)
#define all(a) a.begin(), a.end()
template<class T> bool chmin(T&a, T b) {if(a > b) {a = b; return true;} return false;}
template<class T> void out(T a) {cout << a << '\n';}
const ll inf = 1001001001001001001;
struct edge {ll from, to, cost;};
int main() {
cin.tie(0); ios::sync_with_stdio(false);
ll n, m, K; cin >> n >> m >> K; n ++;
vector<edge> edges(m);
rep(i, m) {
cin >> edges[i].from >> edges[i].to >> edges[i].cost;
}
ranges::sort(edges, {}, &edge::to);
{
ll curR = 0, cost = 0, num = 0;
rep(i, m) {
if(curR <= edges[i].from) {
num ++;
curR = edges[i].to;
}
}
if(num <= K) {
cout << 0 << '\n';
return 0;
}
}
ll ok = inf, ng = 0, ans = inf;
vi idx(m), dif(m + 1), val(m + 1);
rep(i, m) idx[i] = lower_bound(all(edges), edges[i].from + 1, [](edge a, ll b){return a.to < b;}) - edges.begin();
while(ok - ng > 1) {
ll md = (ok + ng) / 2;
ll sum = 0;
set<ll> S; S.insert(0);
dif[0] = 0; val[0] = 0;
rep(i, m) {
val[i + 1] = val[*S.begin()] + 1;
dif[i + 1] = dif[*S.begin()] + md - sum;
sum += dif[i + 1];
while(dif[i + 1] <= 0 && S.size()) {
if(dif[i + 1] == 0 && val[*prev(S.end()) < val[i + 1]]) break;
dif[i + 1] += dif[*prev(S.end())];
S.erase(prev(S.end()));
}
S.insert(i + 1);
auto itr = S.lower_bound(idx[i] + 1);
dif[*S.begin()] += edges[i].cost;
dif[*itr] -= edges[i].cost;
while(dif[*itr] <= 0 && itr != S.begin()) {
if(dif[*itr] == 0 && val[*prev(itr)] < val[*itr]) break;
dif[*itr] += dif[*prev(itr)];
S.erase(prev(itr));
}
}
if(val[*S.begin()] <= K) {
ok = md;
ans = dif[*S.begin()] - md * K;
}
else ng = md;
}
out(ans);
}