#include<bits/stdc++.h>
#define inf 0x7fffffff
#define bigMax 10000
#define ll long long
#define pb push_back
#define dir4 dx[5]={-1,0,1,0},dy[5]={0,1,0,-1}
#define rep(i,l,x) for(int i=l;i<x;i++)
#define repn(i,l,x) for(int i=l;i<=x;i++)
using namespace std;
char gc(){char _ch=getchar();if(_ch=='\n'||_ch==' ') _ch=getchar();return _ch;}
inline int read(){int _res=0,_ch,_flag=0;if((_ch=getchar())=='\n') _ch=getchar();if(_ch=='-') _flag=1;else if(_ch>='0'&&_ch<='9') _res=_ch-'0';while((_ch=getchar())>='0'&&_ch<='9')_res=_res*10+_ch-'0';_flag?-_res:_res;}
namespace calcu{const ll mo=1e9+7;struct martrix{ll h,w,v[105][105]={};inline ll read(ll _h,ll _w){h=_h,w=_w;for(ll i=1;i<=_h;i++){for(ll j=1;j<=_w;j++){scanf("%lld",&v[i][j]);}}}inline void print(ll _h,ll _w){for(ll i=1;i<=_h;i++){for(ll j=1;j<=_w;j++){printf("%lld ",v[i][j]);}putchar('\n');}}};martrix operator*(martrix _fir, martrix _sec){martrix _res;_res.h=_fir.h,_res.w=_sec.w;if(_fir.w!=_sec.h) return _res;repn(i,1,_res.h){repn(j,1,_res.w){repn(k,1,_fir.w){_res.v[i][j]=(_res.v[i][j]+_fir.v[i][k]*_sec.v[k][j])%mo;}}}return _res;}template<typename T>T quickpow(T _a,ll _b){T _sum=_a;_b--;while(_b){if(_b&1) _sum=(_sum*_a);_a=(_a*_a);_b>>=1;}return _sum;}}inline void write(int _x){if(_x<0){putchar('-');_x=-_x;}if(_x>9) write(_x/10);putchar(_x%10+'0');}
int gcd(int _fnum,int _snum){if(_snum!=0) return gcd(_snum,_fnum%_snum);else return _fnum;}
ll Lgcd(ll _fnum,ll _snum){if(_snum!=0) return Lgcd(_snum,_fnum%_snum);else return _fnum;}
int lcm(int _fnum,int _snum){return _fnum*_snum/gcd(_fnum,_snum);}
ll Llcm(ll _fnum,ll _snum){return _fnum*_snum/Lgcd(_fnum,_snum);}
float getDis(float _sx, float _sy, float _ex, float _ey){return sqrt((_sx-_ex)*(_sx-_ex)+(_sy-_ey)*(_sy-_ey));}
bool checkOverlap(int sx1,int sy1,int ex1,int ey1,int sx2,int sy2,int ex2,int ey2){if(!(sx1<=ex1))swap(sx1,ex1);if(!(sx2<=ex2)) swap(sx2,ex2);if(!(sy1<=ey1)) swap(sy1,ey1);if(!(sy2<=ey2)) swap(sy2,ey2);return !((sx1>ex2)||(ex1<sx2)||(sy1>ey2)||(ey1<sy2));}
ll quickpow(ll _a,ll _b,ll _modu){ ll _sum=1;while(_b){if(_b&1) _sum=(_sum*_a)%_modu;_a=(_a*_a)%_modu;_b>>=1;}return _sum;}
int cf_t;
typedef pair<int,int> P;
struct node{
int head,len;
};
inline bool operator<(node f,node s){
return f.head < s.head;
}
multiset<node> stor;
inline void ccomb(node x){
set<node>::iterator p;
p = stor.lower_bound(x);
if(p==stor.end()){
stor.insert(x);
return;
}
node st;
if(x.head + x.len == (*p).head - 1 ){
st.head = x.head, st.len = x.len+1+(*p).len;
stor.erase(p);
stor.insert(st);
}else{
stor.insert(x);
}
}
inline void comb(node x){
set<node>::iterator p;
p = stor.lower_bound(x);
if(p==stor.begin()){
ccomb(x);
return;
}
p=prev(p);
node st;
if((*p).head + (*p).len == x.head - 1 ){
st.head = (*p).head, st.len = (*p).len+1+x.len;
stor.erase(p);
ccomb(st);
}else{
ccomb(x);
}
}
int N;
struct cnode{
int T,M,P,head,len;
};
queue<cnode> wq;
bool operator<(cnode f,cnode s){
if(f.T+f.P != s.T+s.P)
return f.T+f.P < s.T+s.P;
else return f.head<s.head;
}
multiset<cnode> rev;
bool delwq(int T){
if(wq.empty())return false;
int M,P;bool ok=false;
set<node>::iterator p;
bool good = false;
M= wq.front().M,P= wq.front().P;
p = stor.begin();
node sp;
while(p != stor.end()){
if( ((*p).len + 1) >= M ){
sp = *p;
stor.erase(p);
ok = true;
rev.insert((cnode){T,M,P,(sp).head,M-1});
if((sp).len-M>=0){
stor.insert((node){(sp).head+M,(sp).len-M});
}
break;
}
p = next(p);
}
if(ok){
wq.pop();
return true;
}
return false;
}
void solve(){
cin >> N;
stor.insert((node){1,N-1});
int T,M,P,ansa=0,ansb=0;
set<node>::iterator p;
set<cnode>::iterator cp;
while(true){
cin >> T >> M >> P; P--;
if(T==0&&M==0&&P==-1) break;
cp = rev.begin();
if(!rev.empty())
while( (*cp).T + (*cp).P + 1 <= T ){int termi;cnode cst;
termi=(*cp).T + (*cp).P+1;
cst = *cp;rev.erase(cp);
comb((node){(cst).head,(cst).len});
if(rev.empty()){
}else{
if((*rev.begin()).T + (*rev.begin()).P + 1==termi){
cp=rev.begin();
continue;
return;
}
}
if(!wq.empty())
while(delwq(termi)){
}
if(rev.empty()) break;
cp=rev.begin();
}
p = stor.begin();
node sp;bool ok=false;
while(p != stor.end()){
if( ((*p).len + 1) >= M ){
sp = *p;
stor.erase(p);
ok = true;
rev.insert((cnode){T,M,P,(sp).head,M-1});
if((sp).len-M>=0){
stor.insert((node){(sp).head+M,(sp).len-M});
}
break;
}
p = next(p);
}
if(ok==false){
ansb++;
wq.push((cnode){T,M,P,0,0});
}
while(delwq(T)){
}
}
int termi;
T=2000000000;
cp = rev.begin();
cnode cst;
if(!rev.empty())
while( (*cp).T + (*cp).P < T ){
termi=(*cp).T + (*cp).P+1;
cst = *cp;rev.erase(cp);
comb((node){(cst).head,(cst).len});
if(!wq.empty())
while(delwq(termi)){
}
if(rev.empty()) break;
cp=rev.begin();
}
cout << termi <<endl<< ansb<<endl;
}
int main(){
cf_t=1;
while(cf_t--) solve();
return 0;
}