#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace std;
using namespace __gnu_pbds;
 
#ifndef ONLINE_JUDGE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
	template <class Arg1> void __f(const char* name, Arg1&& arg1) { cerr << name << " : " << arg1 << endl; }
	template <class Arg1, class... Args>
	void __f(const char* names, Arg1&& arg1, Args&&... args) {
		const char* sep = strchr(names + 1, ',');
		cerr.write(names, sep - names) << " : " << arg1 << "  ";
		__f(sep + 1, args...);
	}
#else
#define trace(...) 0
#pragma GCC optimize ("O3")
#pragma GCC optimize ("unroll-loops")
#pragma GCC target("popcnt")
#pragma GCC target("avx2,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
#define _CRT_SECURE_NO_WARNINGS
#endif
 
typedef long long int ll;
typedef pair<int,int> pii;
typedef pair<int,pii> piii;
typedef pair<char,int> pci;
typedef pair<ll,ll> pll;
typedef pair<ll,pll> plll;
 


#define pb push_back
 
// order_of_key (k), find_by_order(k)
#define fi first
#define se second
#define input_arr(a,n) for(__typeof (n) i=0; i<n; ++i) {cin>>a[i];}
#define debug_arr(a,n) {{for(__typeof (n) i=0; i<n; ++i) {cout<<a[i]<<" ";}cout<<"\n";}}
#define maxheap priority_queue<ll>
#define minheap priority_queue<ll,vector<ll> ,greater<ll>>
#define initialise(a, x) memset(a, x, sizeof(a))
#define endl '\n'
#define ordered_set tree<pll, null_type,less<pll>, rb_tree_tag,tree_order_statistics_node_update>
#define MAX 1000020
#define maxn 200005
#define eps 0.0000001

const ll mod=998244353;
const ll inf=1e18+2;

#define int ll

int n,q;
vector<pair<int,int> > v;
int tot;

int seg[4*maxn];
int lazy[4*maxn];

void update(int l,int h,int pos,int ql,int qh,ll val)
{
	seg[pos]+=lazy[pos];
	if(l!=h)
	{
		lazy[2*pos+1]+=lazy[pos];
		lazy[2*pos+2]+=lazy[pos];
	}
	lazy[pos]=0;

	if(qh<l || ql>h) return;
	if(l>=ql and h<=qh)
	{
		seg[pos]+=val;
		if(l!=h)
		{
			lazy[2*pos+1]+=val;
			lazy[2*pos+2]+=val;
		}
		return;
	}
	int m=(l+h)/2;

	update(l,m,2*pos+1,ql,qh,val);
	update(m+1,h,2*pos+2,ql,qh,val);

	seg[pos]=max(seg[2*pos+1],seg[2*pos+2]);
}

ll query(int l,int h,int pos,int ql,int qh)
{
	seg[pos]+=lazy[pos];
	if(l!=h)
	{
		lazy[2*pos+1]+=lazy[pos];
		lazy[2*pos+2]+=lazy[pos];
	}
	lazy[pos]=0;

	if(qh<l || ql>h) return 0;
	if(l>=ql and h<=qh) return seg[pos];

	int m=(l+h)/2;
	return max(query(l,m,2*pos+1,ql,qh),query(m+1,h,2*pos+2,ql,qh));
}



int seg2[4*maxn];
int lazy2[4*maxn];

void update2(int l,int h,int pos,int ql,int qh,ll val)
{
	seg2[pos]+=lazy2[pos];
	if(l!=h)
	{
		lazy2[2*pos+1]+=lazy2[pos];
		lazy2[2*pos+2]+=lazy2[pos];
	}
	lazy2[pos]=0;

	if(qh<l || ql>h) return;
	if(l>=ql and h<=qh)
	{
		seg2[pos]+=val;
		if(l!=h)
		{
			lazy2[2*pos+1]+=val;
			lazy2[2*pos+2]+=val;
		}
		return;
	}
	int m=(l+h)/2;

	update2(l,m,2*pos+1,ql,qh,val);
	update2(m+1,h,2*pos+2,ql,qh,val);

	seg2[pos]=max(seg2[2*pos+1],seg2[2*pos+2]);
}

ll query2(int l,int h,int pos,int ql,int qh)
{
	seg2[pos]+=lazy2[pos];
	if(l!=h)
	{
		lazy2[2*pos+1]+=lazy2[pos];
		lazy2[2*pos+2]+=lazy2[pos];
	}
	lazy2[pos]=0;

	if(qh<l || ql>h) return 0;
	if(l>=ql and h<=qh) return seg2[pos];

	int m=(l+h)/2;
	return max(query2(l,m,2*pos+1,ql,qh),query2(m+1,h,2*pos+2,ql,qh));
}


signed main()
{

	ios_base::sync_with_stdio(false);
	cin.tie(0);
	cout.tie(0);

	// freopen("input.txt", "r", stdin);
	// freopen("out.txt", "w", stdout);

	cin>>n>>q;

	for(int i=0;i<q;i++)
	{
		int l,r;
		cin>>l>>r;
		v.pb({l,r});
	}

	tot=(n-2)*(n-2);

	if(q==0)
	{
		cout<<tot<<'\n';
		return 0;
	}

	for(int i=0;i<4*maxn;i++) {seg[i]=n;seg2[i]=n;}

	for(int i=0;i<q;i++)
	{
		int x=v[i].se;

		if(v[i].fi==1)
		{
			int q2=query2(1,n,0,1,x);
			tot-=q2-2;

			int q1=query(1,n,0,1,q2);

			if(q1>x)
			{
				update(1,n,0,1,q2,-q1);
				update(1,n,0,1,q2,x);
			}
		}
		else
		{
			int q1=query(1,n,0,1,x);
			tot-=q1-2;

			int q2=query2(1,n,0,1,q1);

			if(q2>x)
			{
				update2(1,n,0,1,q1,-q2);
				update2(1,n,0,1,q1,x);
			}
		}
	}


	cout<<tot<<'\n';

	
	

	return 0;
}

Measured memory_bytes: 27192