#include <iostream.h>
#include <search.h>


typedef long tim;

#define TIM_MINUS_INFTY 0x80000000l
#define V_PLUS_INFTY    0x40000000l

typedef unsigned idx;


#ifdef _DOS
typedef int bool;
#define true 1
#define false 0

const idx MAXN=500;
#else
const idx MAXN=50000;
#endif

struct Meet
{
tim a,b;
long v;
idx ori_num;
};

inline int Meet_cmp(const Meet &m1, const Meet &m2)
{
if(m1.b>m2.b)
 return +1;
if(m1.b<m2.b)
 return -1;
return 0;
}

int meet_cmp_(const void *v1, const void *v2)
{
return Meet_cmp(*((Meet*)v1),*((Meet*)v2));
}

struct Est
{
long v;
tim t;
Est(void) : v(0), t(0) { };
Est(long v_, tim t_) : v(v_), t(t_) { };
Est(const Meet &m) : v(m.v), t(m.b-m.a) { };
};

inline Est operator + (const Est &e1, const Est &e2)
{
return Est(e1.v+e2.v, e1.t+e2.t);
};

inline int Est_cmp(const Est &e1, const Est &e2)
{
if(e1.v>e2.v)
 return +0x80;
if(e1.v<e2.v)
 return -0x80;
if(e1.t<e2.t)
 return +1;
if(e1.t>e2.t)
 return -1;
return 0;
};

inline int operator < (const Est &e1, const Est &e2)
{
return Est_cmp(e1,e2)<0;
}

int est_cmp_(const void *v1, const void *v2)
{
return Est_cmp(*((Est*)v1),*((Est*)v2));
}

struct Choice
{
bool selected;
idx prev;
Choice(void) : selected(false), prev(0) { };
Choice(bool s, idx p) : selected(s), prev(p) { };
};


idx N;

Meet meets[MAXN+1];
Est est[MAXN+1];
Choice choice[MAXN+1];
char out_arr[MAXN+1];

void ReadData(istream &in)
{
in >> N;
for(idx i=1;i<=N;i++)
 {
 in >> meets[i].a >> meets[i].b >> meets[i].v;
 meets[i].ori_num = i;
 }
}

idx my_bsearch(idx i)
{
tim the_a = meets[i].a;
if(the_a < meets[1].b)
 return 0;
idx l=1,r=i-1,m;
while(l<=r)
 {
 m=(idx)(((long)l+(long)r)/2);
 if(meets[m].b >= the_a)
  r=m-1;
 else
  l=m+1;
 }
 while(meets[m+1].b<the_a)
  m++;
 while(meets[m].b>=the_a)
  m--;
 return m;
}

void SolveDP(void)
{
choice[0]=Choice(true,0);
est[0]=Est(0,0);

for(idx i=1; i<=N; i++)
 {
 idx k=my_bsearch(i);
 Est est_incl = est[k] + Est(meets[i]), est_excl = est[i-1];
 if(est_excl<est_incl)
  {
  est[i]=est_incl;
  choice[i] = Choice(true, choice[k].selected ? k : choice[k].prev);
  }
 else
  {
  est[i]=est_excl;
  choice[i] = Choice(false, choice[i-1].selected ? i-1 : choice[i-1].prev);
  }
 }
}

void WriteRes(ostream &out)
{
out << est[N].v << ' ' << est[N].t << endl;
/*
// memset(out_arr,'0',N);
for(idx i=0; i<N; i++)
 out_arr[i]='0';
out_arr[N]='\0';
for(idx k = choice[N].selected ? N : choice[N].prev; k; k = choice[k].prev)
 out_arr[meets[k].ori_num-1]='1';
out << out_arr << endl;
*/
}



int main(void)
{
ReadData(cin);
qsort(meets+1,N,sizeof(Meet),&meet_cmp_);
SolveDP();
WriteRes(cout);
return 0;
}