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


//#define REDIRECT_IN
//#define REDIRECT_OUT

#ifdef REDIRECT_IN
#include <fstream.h>
#else
#ifdef REDIRECT_OUT
#include <fstream.h>
#endif
#endif


typedef long tim;

#define TIM_MINUS_INFTY 0x80000000l
#define TIM_PLUS_INFTY 0x7FFF0000l
#define V_PLUS_INFTY    0x40000000l

#define IDX_NAN 0xFF00

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));
}

inline int operator < (const Meet &m1, const Meet &m2)
{
return Meet_cmp(m1,m2)<0;
}

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];
idx 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_N2(void)
{

for(idx i=1; i<=N; i++)
 {
 choice[i]=IDX_NAN;
 Est local_best=Est(0,0), local_curr=local_best;
 for(idx k=1;k<i;k++)
  if(meets[k].b<meets[i].a)
   {
   local_curr = est[k];
   if(local_best<local_curr)
    {
    local_best=local_curr;
    choice[i]=k;
    }
   }
 est[i]=Est(meets[i])+local_best;

 }
}

void WriteRes(ostream &out)
{
idx best_last=IDX_NAN;
Est best_est(0,0);
for(idx i=1;i<=N;i++)
 if(best_est<est[i])
  best_est=est[best_last=i];
out << est[best_last].v << ' ' << est[best_last].t << endl;
/*

Restoring path -- NON completed

// 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] ? N : choice[N].prev; k; k = choice[k].prev)
 out_arr[meets[k].ori_num-1]='1';
out << out_arr << endl;
*/
}



int main(void)
{
#ifdef REDIRECT_IN
 {
 ifstream fin("chief3.dat");
 ReadData(fin);
 }
#else
ReadData(cin);
#endif

/*
{
for(int i=N-1;i;i--)
 for(int j=1;j<=i;j++)
  if(meets[j+1]<meets[j])
   {
   Meet temp=meets[j+1];
   meets[j+1]=meets[j];
   meets[j]=temp;
   }
}
*/

qsort(meets+1,N,sizeof(Meet),&meet_cmp_);


SolveDP_N2();
#ifdef REDIRECT_OUT
 {
 ofstream fout("chief3.sol");
 WriteRes(fout);
 fout.close();
 }
#else
WriteRes(cout);
#endif
return 0;
}