#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

#ifdef on_linux
	#include <sys/resource.h>
#endif

#ifdef dobby_is_a_free_elf
	#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
#else
	#define trace(...) 0;
#endif

using namespace std;
using namespace __gnu_pbds;


#define all(x)                  (x).begin(), (x).end()
#define between(i,x,y)          ((i) >= (x) && (i) <= (y))
#define DECIMAL(n)              cout << fixed << setprecision(n)
#define fi                      first
#define lbd                     lower_bound
#define mem0(x)                 memset(x, 0, sizeof (x))
#define mem1(x)                 memset(x, -1, sizeof (x))
#define mp                      make_pair
#define pb                      push_back
#define pf                      push_front
#define ppb                     pop_back
#define ppf                     pop_front
#define sc                      second
#define sqr(a)                  ((a) * (a))
#define sz(x)                   (int)((x).size())
#define ubd                     upper_bound

#define int                     long long

using ll = long long;
using pii = pair<int, int>;
using pll = pair<ll, ll>;

template <typename T>
using ordered_set = tree<T, null_type,
      less<T>,
      rb_tree_tag,
      tree_order_statistics_node_update>;
// find_by_order(k)  returns iterator to kth element starting from 0
// order_of_key(k) returns count of elements strictly smaller than k


const long double PI = 3.14159265358979323846264338;
const double eps = 1e-10;
#ifdef int
	const long long INF = 1e18;
#else
	const long long INF = 1e9;
#endif
const int32_t fftmod = 998244353;
const int32_t MOD = 1000000007;
const int32_t N = 2e5 + 10;
const int32_t NN = 1e6 + 10;

const int32_t maxn = N;

int n, q;

struct node
{
	int v = n;
	int lazy = n;
	bool islazy = false;
	// only used to assign value to leaf nodes in build and pupd
	void assign(int val) {
		v = min(v, val);
	}
	// used in build, rquery, pupd, rupd
	void merge(node &l, node &r) {
		v = min(l.v, r.v);
	}
};

struct SegTree
{
	int32_t len = 0;
	node zero;
	vector<node> t;

	SegTree (int32_t _len) {
		len = _len;
		t.resize((len << 2) + 10);
	}
	SegTree () {
		len = maxn;
		t.resize((len << 2) + 10);
	}

	//if a node has lazy tag then its info is correct but its children's info
	//is old, so pushdown() before going into children
	inline void pushdown(int32_t v, int32_t tl, int32_t tr) {
		if (!t[v].islazy) { return; }

		int32_t tm = (tl + tr) >> 1;
		apply((v << 1), tl, tm, t[v].lazy);
		apply(((v << 1) | 1), tm + 1, tr, t[v].lazy);

		t[v].lazy = zero.lazy;
		t[v].islazy = false;
		return;
	}
	//apply() is an auxillary function to apply range update and set lazy tag
	inline void apply(int32_t v, int32_t tl, int32_t tr, int val) {
		if (tl != tr) {
			t[v].lazy = min(t[v].lazy, val);				// modify the lazy by val, eg. lazy += val
			t[v].islazy = true;
		}
		// incorporate the change (=val) in node
		t[v].v = min(t[v].v, val);
		return;
	}
	void build(int a[], int32_t v, int32_t tl, int32_t tr) {
		if (tl == tr) {
			t[v].assign(a[tl]);
			return;
		}
		int32_t tm = (tl + tr) >> 1;
		build(a, (v << 1), tl, tm);
		build(a, ((v << 1) | 1), tm + 1, tr);
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void build(int a[]) {
		build(a, 1, 0, len - 1);
		return;
	}
	node pquery(int32_t v, int32_t tl, int32_t tr, int32_t pos) {
		if (tl == tr) {
			return t[v];
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		if (pos <= tm) {
			return pquery((v << 1), tl, tm, pos);
		}
		else {
			return pquery(((v << 1) | 1), tm + 1, tr, pos);
		}
	}
	node pquery(int32_t pos) {
		return pquery(1, 0, len - 1, pos);
	}
	node rquery(int32_t v, int32_t tl, int32_t tr, int32_t l, int32_t r) {
		if (l > tr || r < tl) {
			return zero;
		}
		if (l <= tl && tr <= r) {
			return t[v];
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		node a, b, ans;
		a = rquery((v << 1), tl, tm, l, r);
		b = rquery(((v << 1) | 1), tm + 1, tr, l, r);
		ans.merge(a, b);
		return ans;
	}
	node rquery(int32_t l, int32_t r) {
		return rquery(1, 0, len - 1, l, r);
	}
	void pupd(int32_t v, int32_t tl, int32_t tr, int32_t pos, int val) {
		if (tl == tr) {
			t[v].assign(val);
			return;
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		if (pos <= tm) {
			pupd((v << 1), tl, tm, pos, val);
		}
		else {
			pupd(((v << 1) | 1), tm + 1, tr, pos, val);
		}
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void pupd(int32_t pos, int val) {
		pupd(1, 0, len - 1, pos, val);
		return;
	}
	void rupd(int32_t v, int32_t tl, int32_t tr, int32_t l, int32_t r, int val) {
		if (l > tr || r < tl) {
			return;
		}
		if (l <= tl && tr <= r) {
			apply(v, tl, tr, val);
			return;
		}
		pushdown(v, tl, tr);
		int32_t tm = (tl + tr) >> 1;
		rupd((v << 1), tl, tm, l, r, val);
		rupd(((v << 1) | 1), tm + 1, tr, l, r, val);
		t[v].merge(t[(v << 1)], t[((v << 1) | 1)]);
		return;
	}
	void rupd(int32_t l, int32_t r, int val) {
		rupd(1, 0, len - 1, l, r, val);
	}
};

template <typename Arg1>
void __f(const char *name, Arg1 &&arg1) {
	cout << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char *names, Arg1 &&arg1, Args &&... args) {
	const char *comma = strchr(names + 1, ',');
	cout.write(names, comma - names) << " : " << arg1 << " | "; __f(comma + 1, args...);
}

inline void elf_magic(int testcase)
{
	cin >> n >> q;

	SegTree hor(n), ver(n);

	int ans = (n - 2) * (n - 2);
	for (int i = 0; i < q; ++i) {
		int t, x;
		cin >> t >> x;
		if (t == 1) {
			int v = ver.pquery(x).v;
			hor.rupd(2, v - 1, x);
			ans -= (v - 2);
		} else {
			int v = hor.pquery(x).v;
			ver.rupd(2, v - 1, x);
			ans -= (v - 2);
		}
	}

	cout << ans;

	return;
}

int32_t main()
{
	#ifdef on_linux
	rlimit cpu_time {.rlim_cur = 2, .rlim_max = RLIM_INFINITY};
	setrlimit(RLIMIT_CPU, &cpu_time);
	#endif

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

	int TESTS = 1;
	//cin >> TESTS;
	for (int i = 1; i <= TESTS; ++i) {
		// cout << "Case #" << i << ": ";
		elf_magic(i);
		if (i != TESTS)	{ cout << '\n'; }
	}
	return 0;
}

Measured memory_bytes: 40696