/*
	Drzavno takmicenje 2008
	Zadatak: poruka
	Autor: Slobodan Mitrovic, Deronje

	Zadatak se moze resiti dinamickim programiranjem. Naime, dp[k][t] cuva najvecu vrednost
	koja se moze dobiti u k-toj traci u momentu t.
	Vremena u kojima dijamanti dodiruju dno ekrana se sortiraju u neopadajucem poretku.
	Nakon toga prolazimo kroz sve momente i za svaku traku u datom momentu racunamo
	najbolju vrednost koja je jednaka
	max(ako smo u momentu t-1 bili u susednoj traci pa se pomerili u k;
			ako smo u momentu t-1 bili u traci k) + 
		vrednost dijamanat koji su dotakli dno ekrana u k-toj traci u momentu t
		
	NAPOMENA: Primetimo da se stanje u momentu t racuna samo preko stanja
						u momentu t-1, shodno tome, ne moramo cuvati stanja kroz sve momente
						nego samo za prethodni momenat cime se smanjuje memorijska slozenost.
*/

#include <iostream>
#include <cstdio>

using namespace std;

struct mytype{
	int l, t;
	long long c;
	mytype(){
	}
		
	friend bool operator <(const mytype &a, const mytype &b){
		if (a.t < b.t)
			return true;
		else if (a.t > b.t)
			return false;
		else
			return a.l < b.l;
	}
};

long long dp[50][100000 + 1];

int main(){
	FILE* fin;
	FILE* fout;
	 fin = fopen("let.in", "r");
	fout = fopen("let.out", "w");
	int n, k, T, i;
	fscanf(fin, "%d %d %d", &k, &n, &T);
	mytype d[n];
	for (i = 0; i < n; i++){
		fscanf(fin, "%I64d %d %d", &d[i].c, &d[i].l, &d[i].t);
		d[i].l--;
	}
	sort(d, d + n);
	memset(dp, 128, sizeof(dp));
	dp[0][0] = 0;
	int lidx = 0;
	long long sum;
	long long *cur;
	for (int t = 1; t <= T; t++)
		for (i = 0; i < k; i++){
			sum = 0;
			while (lidx < n && d[lidx].t == t && d[lidx].l == i)
				sum += d[lidx++].c;
			
			cur = &dp[i][t];
			*cur = dp[i][t - 1] + sum;
			if (i > 0)
				*cur >?= dp[i - 1][t - 1] + sum;
			if (i + 1 < k)
				*cur >?= dp[i + 1][t - 1] + sum;
		}

	sum = 0LL;
	for (i = 0; i < k; i++)
		sum = max(sum, dp[i][T]);

	fprintf(fout, "%I64d\n", sum);
	fclose(fin);
	fclose(fout);
	return 0;
}
