#include using namespace std; using ll = long long; template using vt = vector; template using vvt = vector>; template using ttt = tuple; using tii = tuple; using vi = vector; #define rep(i,n) for(int i=0;i<(int)(n);i++) #define pb push_back #define mt make_tuple #define ALL(a) (a).begin(),(a).end() #define FST first #define SEC second #define DEB cerr<<"!"<0){if((n&1)==1)r=r*x%m;x=x*x%m;n>>=1;}return r%m;} inline ll lcm(ll d1, ll d2){return d1 / __gcd(d1, d2) * d2;} /*Coding Space*/ // ペアの全探索は a.begin(), a.begin() + n/2, a.end() として a[i],a[i+n/2](i = 0..n/2) // This Segtree written by @qcw_pro(Retirement Maximum member). template // M: monoid, O: operator monoid struct SegTree { using MM = function ; using MO = function ; using OO = function ; using OI = function ; const int n, h; // n: array size, h: height of tree const M m_id; // identity element of monoid const O o_id; // identity element of operator monoid MM mm; MO mo; OO oo; OI oi; vector m; // monoid array vector o; // operator monoid array SegTree(int n, M m_id, O o_id, MM mm, MO mo, OO oo, OI oi = [](const O& a, int b) { return a; }) :n(n), h(sizeof(int)*CHAR_BIT - __builtin_clz(n)), m_id(m_id), o_id(o_id), mm(mm), mo(mo), oo(oo), oi(oi), m(n * 2, m_id), o(n * 2, o_id) {} inline void apply(int i, const O& v, int k) { m[i] = mo(m[i], oi(v, k)); if(i < n) o[i] = oo(o[i], v); } inline void build(int i) { while(i >>= 1) if(o[i] == o_id) m[i] = mm(m[i * 2], m[i * 2 + 1]); } inline void push(int i) { int s{ i >> h ? h : h - 1 }; for(int k{ 1 << (s - 1) }; s > 0; --s, k >>= 1) { int p{ i >> s }; if(o[p] == o_id) continue; apply(p * 2, o[p], k); apply(p * 2 + 1, o[p], k); o[p] = o_id; } } void modify(int l, int r, const O& v) { // [l,r) 変更クエリ l += n, r += n; push(l), push(r - 1); int ll{ l }, rr{ r }; for(int k{ 1 }; l < r; l >>= 1, r >>= 1, k <<= 1) { if(l & 1) apply(l++, v, k); if(r & 1) apply(r - 1, v, k); } build(ll), build(rr - 1); } M query(int l, int r) { // [l,r) 出力クエリ l += n, r += n; push(l), push(r - 1); M a{ m_id }, b{ m_id }; for(; l < r; l >>= 1, r >>= 1) { if(l & 1) a = mm(a, m[l++]); if(r & 1) b = mm(m[r - 1], b); } return mm(a, b); } }; //SegTree (size, M_I, O_I, MM, MO, OO, (OI)) const ll m_id = 0; const ll o_id = 10000; SegTree a(100001, m_id, o_id, plus(), [](const ll a, const ll b) { return b; }, [](const ll a, const ll b) { return b; }, [](const ll a, const int k) { return (a == o_id)? a:a * k; }); int main(){ int n,q; cin >> n >>q; ll ans_a = 0; ll ans_b = 0; rep(i,q){ int x,l,r; cin >> x >> l >> r; if(x == 1){ a.modify(l,++r,1); }else if(x == 2){ a.modify(l,++r,1000000); }else{ ll aq = a.query(l,++r); ll aa = aq % 1000000; ll bb = aq / 1000000; if(aa < bb) ans_b += bb; if(aa > bb) ans_a += aa; } } ll aq = a.query(0,n); ll aa = aq % 1000000; ll bb = aq / 1000000; cout << ans_a + aa << " " << ans_b + bb << endl; }