#include <bits/stdc++.h>
using namespace std;
using ll = long long;

#define ALL(obj) (obj).begin(),(obj).end()
template<class T> using priority_queue_reverse = priority_queue<T,vector<T>,greater<T>>;

constexpr long long MOD = 1'000'000'000LL + 7;
constexpr long long MOD2 = 998244353;
constexpr long long HIGHINF = (long long)1e18;
constexpr long long LOWINF = (long long)1e15;
constexpr long double PI = 3.1415926535897932384626433L;

template <class T> vector<T> multivector(size_t N,T init){return vector<T>(N,init);}
template <class... T> auto multivector(size_t N,T... t){return vector<decltype(multivector(t...))>(N,multivector(t...));}
template <class T> void corner(bool flg, T hoge) {if (flg) {cout << hoge << endl; exit(0);}}
template <class T, class U>ostream &operator<<(ostream &o, const map<T, U>&obj) {o << "{"; for (auto &x : obj) o << " {" << x.first << " : " << x.second << "}" << ","; o << " }"; return o;}
template <class T>ostream &operator<<(ostream &o, const set<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const multiset<T>&obj) {o << "{"; for (auto itr = obj.begin(); itr != obj.end(); ++itr) o << (itr != obj.begin() ? ", " : "") << *itr; o << "}"; return o;}
template <class T>ostream &operator<<(ostream &o, const vector<T>&obj) {o << "{"; for (int i = 0; i < (int)obj.size(); ++i)o << (i > 0 ? ", " : "") << obj[i]; o << "}"; return o;}
template <class T, class U>ostream &operator<<(ostream &o, const pair<T, U>&obj) {o << "{" << obj.first << ", " << obj.second << "}"; return o;}
void print(void) {cout << endl;}
template <class Head> void print(Head&& head) {cout << head;print();}
template <class Head, class... Tail> void print(Head&& head, Tail&&... tail) {cout << head << " ";print(forward<Tail>(tail)...);}
template <class T> void chmax(T& a, const T b){a=max(a,b);}
template <class T> void chmin(T& a, const T b){a=min(a,b);}
vector<string> split(const string &str, const char delemiter) {vector<string> res;stringstream ss(str);string buffer; while( getline(ss, buffer, delemiter) ) res.push_back(buffer); return res;}
int msb(int x) {return x?31-__builtin_clz(x):-1;}
void YN(bool flg) {cout << (flg ? "YES" : "NO") << endl;}
void Yn(bool flg) {cout << (flg ? "Yes" : "No") << endl;}
void yn(bool flg) {cout << (flg ? "yes" : "no") << endl;}

/*
 * @title SegmentTreeBeats
 */
template<class T> class SegmentTreeBeats {
	T inf;
	size_t length;
	vector<T>
	node_max_first,node_max_second,count_max_first,
	node_min_first,node_min_second,count_min_first,
	node_sum,lazy_add,lazy_update;
	vector<pair<int,int>> range;
	stack<int> down,up;
	inline void internal_chmax(int k, long long x) {
		node_sum[k] += (x - node_max_first[k]) * count_max_first[k];
		if(node_max_first[k] == node_min_first[k]) node_max_first[k] = node_min_first[k] = x;
		else if(node_max_first[k] == node_min_second[k]) node_max_first[k] = node_min_second[k] = x;
		else node_max_first[k] = x;
		if(lazy_update[k] != inf && x < lazy_update[k]) lazy_update[k] = x;
	}
	inline void internal_chmin(int k, long long x) {
		node_sum[k] += (x - node_min_first[k]) * count_min_first[k];
		if(node_max_first[k] == node_min_first[k]) node_max_first[k] = node_min_first[k] = x;
		else if(node_max_second[k] == node_min_first[k]) node_min_first[k] = node_max_second[k] = x;
		else node_min_first[k] = x;
		if(lazy_update[k] != inf && lazy_update[k] < x) lazy_update[k] = x;
	}
	inline void internal_add(int k, long long x) {
		node_max_first[k] += x;
		if(node_max_second[k] != -inf) node_max_second[k] += x;
		node_min_first[k] += x;
		if(node_min_second[k] != inf) node_min_second[k] += x;
		node_sum[k] += x * (range[k].second - range[k].first);
		(lazy_update[k] != inf ? lazy_update[k]:lazy_add[k]) += x;
	}
	inline void internal_update(int k, long long x) {
		node_max_first[k] = x; node_max_second[k] = -inf;
		node_min_first[k] = x; node_min_second[k] = inf;
		count_max_first[k] = count_min_first[k] = (range[k].second - range[k].first);
		node_sum[k] = x * (range[k].second - range[k].first);
		lazy_update[k] = x;
		lazy_add[k] = 0;
	}
	inline void propagate(int k) {
		if(length-1 <= k) return;
		if(lazy_update[k] != inf) {
			internal_update(2*k+0, lazy_update[k]);
			internal_update(2*k+1, lazy_update[k]);
			lazy_update[k] = inf;
			return;
		}
		if(lazy_add[k] != 0) {
			internal_add(2*k+0, lazy_add[k]);
			internal_add(2*k+1, lazy_add[k]);
			lazy_add[k] = 0;
		}
		if(node_max_first[k] < node_max_first[2*k+0]) {
			internal_chmax(2*k+0, node_max_first[k]);
		}
		if(node_min_first[2*k+0] < node_min_first[k]) {
			internal_chmin(2*k+0, node_min_first[k]);
		}
		if(node_max_first[k] < node_max_first[2*k+1]) {
			internal_chmax(2*k+1, node_max_first[k]);
		}
		if(node_min_first[2*k+1] < node_min_first[k]) {
			internal_chmin(2*k+1, node_min_first[k]);
		}
	}
	inline void merge(int k) {
		node_sum[k] = node_sum[2*k+0] + node_sum[2*k+1];
		if(node_max_first[2*k+0] < node_max_first[2*k+1]) {
			node_max_first[k] = node_max_first[2*k+1];
			count_max_first[k] = count_max_first[2*k+1];
			node_max_second[k] = max(node_max_first[2*k+0], node_max_second[2*k+1]);
		}
		else if(node_max_first[2*k+0] > node_max_first[2*k+1]) {
			node_max_first[k] = node_max_first[2*k+0];
			count_max_first[k] = count_max_first[2*k+0];
			node_max_second[k] = max(node_max_second[2*k+0], node_max_first[2*k+1]);
		}
		else {
			node_max_first[k] = node_max_first[2*k+0];
			count_max_first[k] = count_max_first[2*k+0] + count_max_first[2*k+1];
			node_max_second[k] = max(node_max_second[2*k+0], node_max_second[2*k+1]);
		}
		if(node_min_first[2*k+0] < node_min_first[2*k+1]) {
			node_min_first[k] = node_min_first[2*k+0];
			count_min_first[k] = count_min_first[2*k+0];
			node_min_second[k] = min(node_min_second[2*k+0], node_min_first[2*k+1]);
		}
		else if(node_min_first[2*k+0] > node_min_first[2*k+1]) {
			node_min_first[k] = node_min_first[2*k+1];
			count_min_first[k] = count_min_first[2*k+1];
			node_min_second[k] = min(node_min_first[2*k+0], node_min_second[2*k+1]);
		}
		else {
			node_min_first[k] = node_min_first[2*k+0];
			count_min_first[k] = count_min_first[2*k+0] + count_min_first[2*k+1];
			node_min_second[k] = min(node_min_second[2*k+0], node_min_second[2*k+1]);
		}
	}
	inline void up_merge(void){
		while(up.size()) {
			merge(up.top());
			up.pop();
		}
	}
	inline void down_propagate(const int& k) {
		propagate(k);
		down.push(2*k+0);
		down.push(2*k+1);
	}
public:
	SegmentTreeBeats(const int num,const T inf = (1LL<<60)) {
		vector<T> a(num,0);
		*this = SegmentTreeBeats(a,inf);
	}
	SegmentTreeBeats(const vector<T>& a,const T inf = (1LL<<60)) : inf(inf){
		int num = a.size();
		for (length = 1; length <= num; length *= 2);
		node_max_first.resize(2*length);
		node_max_second.resize(2*length);
		count_max_first.resize(2*length);
		node_min_first.resize(2*length);
		node_min_second.resize(2*length);
		count_min_first.resize(2*length);
		node_sum.resize(2*length);
		range.resize(2*length);
		lazy_add.resize(2*length);
		lazy_update.resize(2*length);

		for(int i=0; i<2*length; ++i) lazy_add[i] = 0, lazy_update[i] = inf;
		for(int i = 0; i < length; ++i) range[i+length] = make_pair(i,i+1);
		for(int i = length - 1; i >= 0; --i) range[i] = make_pair(range[(i<<1)+0].first,range[(i<<1)+1].second);

		for(int i=0; i<num; ++i) {
			node_max_first[length+i] = node_min_first[length+i] = node_sum[length+i] = a[i];
			node_max_second[length+i] = -inf;
			node_min_second[length+i] = inf;
			count_max_first[length+i] = count_min_first[length+i] = 1;
		}
		for(int i=num; i<length; ++i) {
			node_max_first[length+i] = node_max_second[length+i] = -inf;
			node_min_first[length+i] = node_min_second[length+i] = inf;
			count_max_first[length+i] = count_min_first[length+i] = 0;
		}
		for(int i=length-1; i; --i) merge(i);
	}
	inline void range_chmin(int a, int b, long long x) {
		down.push(1);
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a || node_max_first[k] <= x) continue;
			if(a <= range[k].first && range[k].second <= b && node_max_second[k] < x) {
				internal_chmax(k, x);
				continue;
			}
			down_propagate(k);
			up.push(k);
		}
		up_merge();
	}
	inline void range_chmax(int a, int b, long long x,int k = 1) {
		down.push(1);
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a || x <= node_min_first[k]) continue;
			if(a <= range[k].first && range[k].second <= b && x < node_min_second[k]) {
				internal_chmin(k, x);
				continue;
			}
			down_propagate(k);
			up.push(k);
		}
		up_merge();
	}
	inline void range_add(int a, int b, long long x,int k = 1) {
		down.push(1);
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a) continue;
			if(a <= range[k].first && range[k].second <= b) {
				internal_add(k, x);
				continue;
			}
			down_propagate(k);
			up.push(k);
		}
		up_merge();
	}
	inline void range_update(int a, int b, long long x,int k = 1) {
		down.push(1);
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a) continue;
			if(a <= range[k].first && range[k].second <= b) {
				internal_update(k, x);
				continue;
			}
			down_propagate(k);
			up.push(k);
		}
		up_merge();
	}
	inline T get_max(int a, int b, int k = 1) {
		down.push(1);
		long long v = inf;
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a) continue;
			if(a <= range[k].first && range[k].second <= b) {
				v = max(v,node_max_first[k]);
				continue;
			}
			down_propagate(k);
		}
		return v;
	}
	inline T get_min(int a, int b, int k = 1) {
		down.push(1);
		long long v = inf;
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a) continue;
			if(a <= range[k].first && range[k].second <= b) {
				v = min(v,node_min_first[k]);
				continue;
			}
			down_propagate(k);
		}
		return v;
	}
	inline T get_sum(int a, int b, int k=1) {
		down.push(1);
		long long v = 0;
		while(down.size()) {
			int k = down.top();
			down.pop();
			if(b <= range[k].first || range[k].second <= a) continue;
			if(a <= range[k].first && range[k].second <= b) {
				v += node_sum[k];
				continue;
			}
			down_propagate(k);
		}
		return v;
	}
};

int main() {
    cin.tie(0);ios::sync_with_stdio(false);
    ll N,Q; cin >> N >> Q;
    ll ans = (N-2)*(N-2);
    SegmentTreeBeats<ll> segh(N),segw(N);
	segh.range_add(0,N,N-2);  
	segw.range_add(0,N,N-2);  
    for(int i = 0; i < Q; ++i) {
        int q,y; cin >> q >> y;
        y--;
        if(q == 1) {
			int d = segw.get_sum(y,y+1); 
            ans -= d;
            segh.range_chmin(0,d+1,y-1);
        }
        if(q == 2) {
			int r = segh.get_sum(y,y+1); 
            ans -= r;
            segw.range_chmin(0,r+1,y-1);
        }
    }
    cout << ans << endl;
    return 0;
}


Measured memory_bytes: 86840