#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#include<iostream>
using namespace std;

#define int long long int
#define all(x) (x).begin(), (x).end()
#define removeDuplicates(a) a.resize(unique(all(a))-a.begin())
#define endl '\n'

class segtree{
	int sz;
	vector<int>val;
	vector<int>opt;
	vector<int>cnt;
	int NOP=0;
	int NEU=0;
public:
	segtree (int n){
		sz=1;
		while(sz<n){
			sz = sz*2;
		}
		NEU=n;
		val.assign(2*sz,NEU);
		opt.assign(2*sz,LLONG_MAX);
		cnt.assign(2*sz,0LL);
	}
	// void build(int n,int curr,int left,int right){
	// 	if(right-left==1){ 
	// 		if(left<n){
	// 			cnt[curr]=1;
	// 			val[curr]=n;
	// 		}
	// 		return;
	// 	}
	// 	int mid=(left+right)/2;
	// 	build(n,2*curr+1,left,mid);
	// 	build(n,2*curr+2,mid,right);
	// 	cnt[curr]=cnt[2*curr+1]+cnt[2*curr+2];
	// }
	// void build(vector<int>&a,int n){
	// 	build(a,n,0,0,sz);
	// }
	// void propogate(int curr,int left,int right){
	// 	if((right-left)==1){
	// 		return;
	// 	}
	// 	if(opt[curr]!=NOP){
	// 		opt[2*curr+1]+=opt[curr];
	// 		val[2*curr+1]+=opt[curr]*cnt[2*curr+1];
	// 		opt[2*curr+2]+=opt[curr];
	// 		val[2*curr+2]+=opt[curr]*cnt[2*curr+2];
	// 		opt[curr]=NOP;
	// 	}
	// }
	void updateRange(int l,int r,int value,int curr,int left,int right){
		if(left>=r || right<=l){
			return;
		}
		// propogate(curr,left,right);
		if(left>=l && right<=r){
			opt[curr]=min(opt[curr],value);
			return;
		}
		int mid=(left+right)/2;
		updateRange(l,r,value,2*curr+1,left,mid);   
		updateRange(l,r,value,2*curr+2,mid,right);
		// val[curr]=val[2*curr+1]+val[2*curr+2];
	}
	void updateRange(int l,int r,int value){
		updateRange(l,r,value,0,0,sz);
	}
	// void updateIndex(int i,int value,int curr,int left,int right){
	// 	if(right-left==1){
	// 		opt[curr]+=value;
	// 		val[curr]+=value*cnt[curr];
	// 		return;
	// 	}
	// 	int mid=(left+right)/2;
	// 	if(i<mid){
	// 		updateIndex(l,r,value,2*curr+1,left,mid);
	// 	}else{
	// 		updateIndex(l,r,value,2*curr+2,mid,right);
	// 	}   
	// 	val[curr]=val[2*curr+1]+val[2*curr+2];
	// }
	// void updateIndex(int i,int value){
	// 	updateIndex(i,value,0,0,sz);
	// }
	int queryIndex(int i,int curr,int left,int right){
		if(right-left==1){
			return min(opt[curr],val[curr]);
		}		
		// propogate(curr,left,right);
		int mid=(left+right)/2;
		if(i<mid){
			return min(opt[curr],queryIndex(i,2*curr+1,left,mid));
		}else{
			return min(opt[curr],queryIndex(i,2*curr+2,mid,right));
		}
	}
	int queryIndex(int i){
		return queryIndex(i,0,0,sz);
	}
	// int queryRange(int l,int r,int curr,int left,int right){
	// 	if(left>=r || right<=l){
	// 		return NEU;
	// 	}
	// 	propogate(curr,left,right);
	// 	if(left>=l && right<=r){
	// 		return val[curr];
	// 	}
	// 	int mid=(left+right)/2;
	// 	int c1=queryRange(l,r,2*curr+1,left,mid);
	// 	int c2=queryRange(l,r,2*curr+2,mid,right);
	// 	return c1+c2;
	// }
	// int queryRange(int l,int r){
	// 	return queryRange(l,r,0,0,sz);
	// }
};

void solve(){
	int n,m;
	cin>>n>>m;
	segtree vertical(n);
	segtree horizontal(n);
	int ans=(n-2)*(n-2);
	for(int i=0;i<m;i++){
		int t,x;
		cin>>t>>x;
		if(t==1){
			int get=vertical.queryIndex(x-1);
			if(get>1){
				ans-=(get-2);
			}
			horizontal.updateRange(0,get,x);
		}else{
			int get=horizontal.queryIndex(x-1);
			if(get>1){
				ans-=(get-2);
			}
			vertical.updateRange(0,get,x);
		}
	}
	cout<<ans<<endl;
}

int32_t main(){

	//remove for interactive problems
	ios_base::sync_with_stdio(false);
	cin.tie(0); cout.tie(0);

	solve();
	cerr<<"Time : "<<1000*((double)clock())/(double)CLOCKS_PER_SEC<<"ms\n";

	return 0;
}

Measured memory_bytes: 27768