#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
using namespace std;
const int N=10010;
typedef long long LL;
const int M=N<<2;
struct tree
{
int l,r;
int cover;
tree(){cover=1;}
}tr[M];
int ans1;
int ans2;
int n,m;
void build(int u,int l,int r)
{
tr[u].l=l;
tr[u].r=r;
if(l==r) return;
int mid=(l+r)>>1;
build(u<<1,l,mid);
build(u<<1|1,mid+1,r);
}
void pushdown(int u,int l,int r,int b)
{
int mid=(tr[u].l+tr[u].r)>>1;
if(tr[u].cover!=1 && tr[u].cover!=-1) tr[u<<1].cover=tr[u<<1|1].cover=tr[u].cover;
if(tr[u].l==l && tr[u].r==r)
{
if(tr[u].cover==-1)
{
if(!b) tr[u].cover=0;
pushdown(u<<1,l,(l+r)>>1,b);
pushdown(u<<1|1,((l+r)>>1)+1,r,b);
return;
}
if(!b)
{
if(tr[u].cover<=1)
{
tr[u].cover=0;
return;
}
if(tr[u].cover==2)
{
tr[u].cover=0;
ans1+=tr[u].r-tr[u].l+1;
ans2-=(tr[u].r-tr[u].l)+1;
return;
}
}
else
{
if(tr[u].cover>=1) return;
if(tr[u].cover==0)
{
tr[u].cover=2;
ans2+=tr[u].r-tr[u].l+1;
return;
}
}
}
else
{
if(r<=mid) pushdown(u<<1,l,r,b);
else
{
if(l>mid) pushdown(u<<1|1,l,r,b);
else
{
pushdown(u<<1,l,mid,b);
pushdown(u<<1|1,mid+1,r,b);
}
}
}
if(tr[u<<1].cover==tr[u<<1|1].cover) tr[u].cover=tr[u<<1].cover;
else tr[u].cover=-1;
}
int main()
{
scanf("%d%d",&n,&m);
build(1,0,n);
while(m--)
{
bool b;
int l,r;
if(l>r) swap(l,r);
cin>>b>>l>>r;
pushdown(1,l,r,b);
}
printf("%d\n%d",ans2,ans1);
return 0;
}