#include <stdio.h>
#include <stdlib.h>

typedef struct Isporuka {
	int rbr, isporukaOd, isporukaDo, vremeDoKupca;
	int povratakOd, povratakDo, vremeUkupno;
} isporuka;

main() {
	
	int n;
	int i,j;
	isporuka *isporuke;
	int **opt;
	isporuka temp;
	
	scanf("%d", &n);
	isporuke = (isporuka *)malloc((n+1)*sizeof(isporuka));
	for (i=1; i<=n; i++) {
		isporuke[i].rbr=i;
		isporuka *temp = isporuke+i;
		scanf("%d%d%d", &(temp->isporukaOd), &(temp->isporukaDo), &(temp->vremeDoKupca));
		temp->povratakOd = temp->isporukaOd + temp->vremeDoKupca;
		temp->povratakDo = temp->isporukaDo + temp->vremeDoKupca;
		temp->vremeUkupno = temp->vremeDoKupca * 2;	
	}
	/*
	printf("Unete isporuke:\n");
	printf("rbr\tispOd\tispDo\tvremeDo\tpovOd\tpovDo\vremeU\n");
	for (i=1; i<=n; i++) {
		temp = isporuke[i];
		printf("%d\t%d\t%d\t%d\t%d\t%d\t%d\n", temp.rbr, temp.isporukaOd, temp.isporukaDo, temp.vremeDoKupca, temp.povratakOd, temp.povratakDo, temp.vremeUkupno);
	}
	*/
	
	int sati = 24, pocetak = 6;
	opt = (int **)malloc((n+1)*sizeof(int *));
	for (i=0; i<=n; i++) {
		opt[i]=(int *)malloc((sati+1)*sizeof(int));
	}
	
	for (i=0; i<=n; i++)
		for (j=0; j<=sati; j++)
			opt[i][j]=0;
	
	for (i=1; i<=n-1; i++)
		for (j=i+1; j<=n; j++)
			if (isporuke[i].povratakDo > isporuke[j].povratakDo) {
				temp = isporuke[i];
				isporuke[i] = isporuke[j];
				isporuke[j] = temp;
			}
			else if (isporuke[i].povratakDo == isporuke[j].povratakDo) {
				if (isporuke[i].povratakOd > isporuke[j].povratakOd) {
					temp = isporuke[i];
					isporuke[i] = isporuke[j];
					isporuke[j] = temp;
				}
			}
	
	
	/*
	printf("Sortirane isporuke:\n");
	printf("rbr\tpovOd\tpovDo\tvremeU\n");
	for (i=1; i<=n; i++) {
		temp = isporuke[i];
		printf("%d\t%d\t%d\t%d\n", temp.rbr, temp.povratakOd, temp.povratakDo, temp.vremeUkupno);
	}
	*/
	
	// Po isporukama	
	for (i=1; i<=n; i++) {
		// Trazimo prvog prethodnog sa manjom vrednoscu za povratakOd
		int pret = -1, brojac = i-1;
		while (pret==-1 && brojac>0) {
			if (isporuke[brojac].povratakOd > isporuke[i].povratakOd) {
				pret = brojac;
			}
			brojac--;
		}
		/*
		if (pret!=-1)
			printf("Prethodnik od %d je %d\n", i, pret);
		*/
		// Po satima
		for (j=pocetak+1; j<=sati; j++) {
			// Prvo da upisemo prethodni optimum, pa da vidimo da li mozemo da ga poboljsamo
			// Tu osim optimuma iznad posmatramo i optimum sleva
			// Jer je mozda dodat neki prethodnik
			opt[i][j] = opt[i-1][j]>=opt[i][j-1] ? opt[i-1][j] : opt[i][j-1];
			// I nadalje cemo samo da proveravamo da li mozemo da poboljsamo trenutni optimum
			
			// Da li uopste ima dovoljno vremena za isporuku, ili bi morao da pocne pre 6h?
			if (j - isporuke[i].vremeUkupno >= pocetak)
				// Da li se isporuka vrsi u trazenom intervalu
				if (isporuke[i].povratakOd<=j && j<=isporuke[i].povratakDo) {
					// Da li dodavanjem isporuke povecavamo optimum
					// Proveravamo i optimum sleva, a ne samo iznad. Razlog je sto smo mozda sleva dodali prethodnika
					//if (opt[i-1][j-isporuke[i].vremeUkupno] + 1 > opt[i-1][j])
					if (opt[i-1][j-isporuke[i].vremeUkupno] + 1 > opt[i][j]) {
						opt[i][j] = opt[i-1][j-isporuke[i].vremeUkupno] + 1;
					}
					// Ako dodavanjem isporuke ne povecavamo optimum, prepisujemo prethodni optimum
					//else 
						//opt[i][j] = opt[i-1][j];
					// Da li imamo prethodnika sa manjim povratakOd
					if (pret!=-1)
						// Da li se isporuka vrsi u intervalu prethodnika
						if (isporuke[pret].povratakOd<=j && j<=isporuke[pret].povratakDo)
							// Da li prethodnik moze da se doda na trenutnu isporuku
							if (j-isporuke[pret].vremeUkupno >= isporuke[i].povratakOd)
								// A trenutni jos uvek ne moze da se doda na prethodni
								if (j-isporuke[i].vremeUkupno < isporuke[pret].povratakOd)
									// Da li dodavanjem prethodne isporuke na trenutnu povecavamo optimum
									if (opt[i][j-isporuke[pret].vremeUkupno] + 1 > opt[i][j])
										opt[i][j] = opt[i][j-isporuke[pret].vremeUkupno] + 1;
				}
				// Ako smo pre intervala, prepisujemo optimum iz prethodnog reda, trenutna isporuka jos nije dodata
				//else if (isporuke[i].povratakOd>j) {
					//opt[i][j] = opt[i-1][j];
				//}
				// Ako smo posle intervala, trenutna isporuka je vec dodata
				// Uzimamo sta je vece, optimum sleva sa trenutnom isporukom
				//else if (opt[i][j-1] > opt[i-1][j])
					//opt[i][j] = opt[i][j-1];
				// ili optimum iznad bez trenutne isporuke
				//else
					//opt[i][j] = opt[i-1][j];
			// Ako isporuka ne moze da stane u ranac, prepisi prethodni optimum
			//else
				//opt[i][j] = opt[i-1][j];
		}
	}
				
	
	
	printf("Matrica optimuma:\n   ");
	for (j=pocetak; j<=sati; j++)
		printf("%3d", j);
	printf("\n");
	for (j=pocetak; j<=sati; j++)
		printf("---");
	printf("---\n");
	for (i=0; i<=n; i++) {
		printf("%2d|",i);
		for (j=pocetak; j<=sati; j++) {
			printf("%3d", opt[i][j]);
		}
		printf("\n");
	}
	
	
	printf("%d\n", opt[n][sati]);
	i=n; j=sati;
	while(opt[i][j]!=0) {
		if (opt[i][j]==opt[i-1][j]) {
			i--;
		}
		else if (isporuke[i].povratakDo < j)
			j = isporuke[i].povratakDo;
		else {
			printf("%d\n",isporuke[i].rbr);
			j -= isporuke[i].vremeUkupno;
			i--;
		}
		
	}
	
}













