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

template <typename T>
struct RangeTreeMin {
	int N; vector<T> node_vals;
	T base_value;
	int ceil_pow_2(int v) { // Nearest power of two upper bound.
		int p; for (p = 1; p < v; p *= 2) {} return p;
	}
	RangeTreeMin(int sz, T base) : base_value(base), N(ceil_pow_2(sz)) {
		node_vals.resize(2*N-1, base_value);
	}
	T combine(T a, T b) { return min(a, b); } // Could be min or +.
	T query(int l, int r, int nid, int nl, int nr) {
		if (l == nl && r == nr)
			return node_vals[nid];
		int mid = (nl+nr)/2; T result = base_value;
		if (l <= mid)
			result = combine(result, query(l, min(r, mid), 2*nid+1, nl, mid));
		if (r > mid)
			result = combine(result, query(max(l, mid+1), r, 2*nid+2, mid+1, nr));
		return result;
	}
	T query(int l, int r) { return query(l, r, 0, 0, N-1); }
	void update(int index, T value, int nid, int nl, int nr) {
		if (nl == nr) { node_vals[nid] = value; return; }
		int mid = (nl+nr)/2;
		if (index <= mid) 	update(index, value, 2*nid+1, nl, mid);
		else				update(index, value, 2*nid+2, mid+1, nr);
		node_vals[nid] = combine(node_vals[2*nid+1], node_vals[2*nid+2]);
	}
	void update(int index, T value) { update(index, value, 0, 0, N-1); }

	T leftmost_lt(int v, int l, int r, int nid, int nl, int nr) {
		if (nl == nr) {
			return node_vals[nid] < v ? nl : -1; 
		}
		if (node_vals[nid] >= v) {
			return -1;
		}
		int mid = (nl+nr)/2;
		if (l <= mid) {
			int res = leftmost_lt(v, l, min(r, mid), 2*nid+1, nl, mid);
			if (res != -1)
				return res;
		}
		if (r > mid) {
			int res = leftmost_lt(v, max(l, mid+1), r, 2*nid+2, mid+1, nr);
			if (res != -1)
				return res;
		}
		return -1;
	}
	int leftmost_lt(int v, int l, int r) { return leftmost_lt(v, l, r, 0, 0, N-1); }
	T rightmost_lt(int v, int l, int r, int nid, int nl, int nr) {
		if (nl == nr) {
			return node_vals[nid] < v ? nl : -1; 
		}
		if (node_vals[nid] >= v) {
			return -1;
		}
		int mid = (nl+nr)/2;
		if (r > mid) {
			int res = rightmost_lt(v, max(l, mid+1), r, 2*nid+2, mid+1, nr);
			if (res != -1)
				return res;
		}
		if (l <= mid) {
			int res = rightmost_lt(v, l, min(r, mid), 2*nid+1, nl, mid);
			if (res != -1)
				return res;
		}
		return -1;
	}
	int rightmost_lt(int v, int l, int r) { return rightmost_lt(v, l, r, 0, 0, N-1); }
};


int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int64_t N, Q;
	cin >> N >> Q;

	int64_t ans = (N-2)*(N-2);
	RangeTreeMin<int> rtcols(N+5, 0), rtrows(N+5, 0);

	vector<int64_t> rowprog(N+5), colprog(N+5);

	// cout << ans << endl;

	for (int i = 0; i < Q; ++i) {
		int t, x;
		cin >> t >> x;
		if (t == 1) {
			if (colprog[x] == N) continue;
			int64_t row = rtrows.leftmost_lt(-(x-1), colprog[x]+1, N-1);
			if (row == -1) row = N;
			ans -= ((row-1)-max((int64_t)1,colprog[x]));
			// cout << 1 << " " << colprog[x] << " " << row << endl;
			colprog[x] = row;
			rtcols.update(x, -row);
		} else {
			if (rowprog[x] == N) continue;
			int64_t col = rtcols.leftmost_lt(-(x-1), rowprog[x]+1, N-1);
			if (col == -1) col = N;
			ans -= ((col-1)-max((int64_t)1,rowprog[x]));
			// cout << 2 << " " << rowprog[x] << " " << col << endl;
			rowprog[x] = col;
			rtrows.update(x, -col);
		}
		// cout << ans << endl;
	}

	cout << ans << endl;
	
}

Measured memory_bytes: 10524