// Original C++ solution (slower):
#include <algorithm>

#include <bitset>

#include <climits>

#include <cmath>

#include <cstdio>

#include <iomanip>

#include <iostream>

#include <map>

#include <numeric>

#include <queue>

#include <set>

#include <sstream>

#include <stack>

#include <string>

#include <unordered_map>

#include <vector>



#define MOD 1000000007

#define MOD2 998244353

#define int long long

#define double long double

#define EPS 1e-9

//#define PI 3.14159265358979



#define rep(i, n) for (int i = 0; i < (int)(n); i++)



using namespace std;



template < typename T >

ostream &operator<<(ostream &os, const vector< T > &A) {

	for (int i = 0; i < A.size(); i++)

		os << A[i] << " ";

	os << endl;

	return os;

}

template <>

ostream &operator<<(ostream &os, const vector< vector< int > > &A) {

	int N = A.size();

	for (int i = 0; i < N; i++) {

		for (int j = 0; j < A[i].size(); j++)

			os << A[i][j] << " ";

		os << endl;

	}

	return os;

}

template < typename T, typename U >

ostream &operator<<(ostream &os, const pair< T, U > &p) {

	os << "(" << p.first << "," << p.second << ")";

	return os;

}



typedef pair< int, int > pii;

typedef long long ll;



struct edge {

	int from, to, d, c, i;

	edge(int _from = 0, int _to = 0, int _d = 0, int _c = 0) {

		from = _from;

		to = _to;

		d = _d;

		c = _c;

	}

	bool operator<(const edge &rhs) const {

		return (d == rhs.d) ? (c < rhs.c) : (d < rhs.d);

	}

};

struct aabb {

	int x1, y1, x2, y2;

	aabb(int x1, int y1, int x2, int y2) : x1(x1), y1(y1), x2(x2), y2(y2) {}

};



typedef vector< edge > edges;

typedef vector< edges > graph;

struct flow {

	int to, cap, rev, cost;

	flow(int to = 0, int cap = 0, int rev = 0, int cost = 0) : to(to), cap(cap), rev(rev), cost(cost) {}

};

typedef vector< vector< flow > > flows;



const int di[4] = {0, -1, 0, 1};

const int dj[4] = {-1, 0, 1, 0};

const int ci[5] = {0, 0, -1, 0, 1};

const int cj[5] = {0, -1, 0, 1, 0};

const ll LINF = LLONG_MAX / 2;

const int INF = INT_MAX / 2;

const double PI = acos(-1);



int pow2(int n) { return 1LL << n; }

template < typename T, typename U >

bool chmin(T &x, const U &y) {

	if (x > y) {

		x = y;

		return true;

	}

	return false;

}

template < typename T, typename U >

bool chmax(T &x, const U &y) {

	if (x < y) {

		x = y;

		return true;

	}

	return false;

}



template < typename A, size_t N, typename T >

void Fill(A (&array)[N], const T &val) {

	fill((T *)array, (T *)(array + N), val);

}

struct initializer {

	initializer() {

		cout << fixed << setprecision(20);

	}

};

initializer _____;

template < class Monoid, class Action >

struct LSegT {

	int N;

	vector< Monoid > node;

	vector< Action > lazy;

	Monoid UNITY_MONOID = 0; //to be set------------------------

	Action UNITY_ACTION = 0; //to be set------------------------

	Monoid merge(const Monoid &l, const Monoid &r) {

		//to be set---------------------------------

		return l + r;

		//return;

	}

	LSegT(vector< Monoid > &A) {

		int sz = A.size();

		N = 1;

		while (N < sz)

			N <<= 1;

		node.resize(2 * N - 1);

		lazy.resize(2 * N - 1, 0);

		rep(i, sz) node[i + N - 1] = A[i];

		for (int i = N - 2; i >= 0; i--)

			node[i] = merge(node[i * 2 + 1], node[i * 2 + 2]);

	}

	void reflect(int k, int l, int r) {

		//to be set----------------------------------------

		node[k] += lazy[k];

	}

	void add(Action &d, const Action &e) {

		//to be set---------------------------------------

		d += e;

	}

	void eval(int k, int l, int r) {

		if (lazy[k] != UNITY_ACTION) {

			reflect(k, l, r);

			if (r - l > 1) {



				//add(lazy[2 * k + 1], lazy[k]);

				//add(lazy[2 * k + 2], lazy[k]);

				//if p,use this

				add(lazy[2 * k + 1], lazy[k] / 2);

				add(lazy[2 * k + 2], lazy[k] / 2);

			}

			lazy[k] = UNITY_ACTION;

		}

	}

	void set(int a, int b, Action x, int k = 0, int l = 0, int r = -1) {

		if (r < 0)

			r = N;

		if (b <= l || r <= a)

			eval(k, l, r);

		else if (a <= l && r <= b) {

			//add(lazy[k], x);

			//if p,use this

			add(lazy[k], (r - l) * x);

			//eval(k, l, r);

		} else {

			eval(k, l, r);

			set(a, b, x, 2 * k + 1, l, (l + r) / 2);

			set(a, b, x, 2 * k + 2, (l + r) / 2, r);

			node[k] = merge(node[2 * k + 1], node[2 * k + 2]);

		}

	}

	Monoid get(int a, int b, int k = 0, int l = 0, int r = -1) {

		if (r < 0)

			r = N;

		if (b <= l || r <= a)

			return UNITY_MONOID;

		eval(k, l, r);

		if (a <= l && r <= b)

			return node[k];

		Monoid vl = get(a, b, 2 * k + 1, l, (l + r) / 2);

		Monoid vr = get(a, b, 2 * k + 2, (l + r) / 2, r);

		return node[k] = merge(vl, vr);

	}

};

int N, M, K, T, Q, H, W;

signed main() {

	cin >> N >> Q;

	vector< pii > qs(Q);

	rep(i, Q) cin >> qs[i].first >> qs[i].second;

	int ans = (N - 2) * (N - 2);

	vector< int > tmp(N + 10, N);

	LSegT< int, int >

		sgt1(tmp), sgt2(tmp);

	for (auto qr : qs) {

		int q, x;

		tie(q, x) = qr;

		int y;

		int tmp;

		if (q == 1) {

			y = sgt1.get(x, x + 1);

			ans -= y - 2;

			tmp = sgt2.get(1, 2);

			if (sgt2.get(1, 2) > x)

				sgt2.set(1, y, x - tmp);

		} else {

			y = sgt2.get(x, x + 1);

			ans -= y - 2;

			tmp = sgt1.get(1, 2);

			if (sgt1.get(1, 2) > x)

				sgt1.set(1, y, x - tmp);

		}

		//cerr << y << endl;

	}

	cout << ans << endl;

	return 0;

}

// Optimized solution to the same problem (faster):
#include <algorithm>

#include <bitset>

#include <climits>

#include <cmath>

#include <cstdio>

#include <iomanip>

#include <iostream>

#include <map>

#include <numeric>

#include <queue>

#include <set>

#include <sstream>

#include <stack>

#include <string>

#include <unordered_map>

#include <vector>



#define MOD 1000000007

#define MOD2 998244353

#define int long long

#define double long double

#define EPS 1e-9

//#define PI 3.14159265358979



#define rep(i, n) for (int i = 0; i < (int)(n); i++)



using namespace std;



template < typename T >

ostream &operator<<(ostream &os, const vector< T > &A) {

	for (int i = 0; i < A.size(); i++)

		os << A[i] << " ";

	os << endl;

	return os;

}

template <>

ostream &operator<<(ostream &os, const vector< vector< int > > &A) {

	int N = A.size();

	for (int i = 0; i < N; i++) {

		for (int j = 0; j < A[i].size(); j++)

			os << A[i][j] << " ";

		os << endl;

	}

	return os;

}

template < typename T, typename U >

ostream &operator<<(ostream &os, const pair< T, U > &p) {

	os << "(" << p.first << "," << p.second << ")";

	return os;

}



typedef pair< int, int > pii;

typedef long long ll;



struct edge {

	int from, to, d, c, i;

	edge(int _from = 0, int _to = 0, int _d = 0, int _c = 0) {

		from = _from;

		to = _to;

		d = _d;

		c = _c;

	}

	bool operator<(const edge &rhs) const {

		return (d == rhs.d) ? (c < rhs.c) : (d < rhs.d);

	}

};

struct aabb {

	int x1, y1, x2, y2;

	aabb(int x1, int y1, int x2, int y2) : x1(x1), y1(y1), x2(x2), y2(y2) {}

};



typedef vector< edge > edges;

typedef vector< edges > graph;

struct flow {

	int to, cap, rev, cost;

	flow(int to = 0, int cap = 0, int rev = 0, int cost = 0) : to(to), cap(cap), rev(rev), cost(cost) {}

};

typedef vector< vector< flow > > flows;



const int di[4] = {0, -1, 0, 1};

const int dj[4] = {-1, 0, 1, 0};

const int ci[5] = {0, 0, -1, 0, 1};

const int cj[5] = {0, -1, 0, 1, 0};

const ll LINF = LLONG_MAX / 2;

const int INF = INT_MAX / 2;

const double PI = acos(-1);



int pow2(int n) { return 1LL << n; }

template < typename T, typename U >

bool chmin(T &x, const U &y) {

	if (x > y) {

		x = y;

		return true;

	}

	return false;

}

template < typename T, typename U >

bool chmax(T &x, const U &y) {

	if (x < y) {

		x = y;

		return true;

	}

	return false;

}



template < typename A, size_t N, typename T >

void Fill(A (&array)[N], const T &val) {

	fill((T *)array, (T *)(array + N), val);

}

struct initializer {

	initializer() {

		cout << fixed << setprecision(20);

	}

};

initializer _____;



int N, M, K, T, Q, H, W;

signed main() {

	cin >> N >> Q;

	int ans = (N - 2) * (N - 2);

	vector< set< pii > > ss(2);

	while (Q--) {

		int q, x;

		cin >> q >> x;

		--q;

		auto it = ss[q].lower_bound(pii(x, -100));

		pii p;

		if (it == ss[q].end())

			p = pii(0, N);

		else

			p = *it;

		ans -= (p.second - 2);

		ss[1 - q].insert(pii(p.second, x));

	}

	cout << ans << endl;

	return 0;

}

// Fastest known solution for this problem: