#include <bits/stdc++.h>
#define pb push_back
#define SZ(x) ((int)(x.size()))
#define FOR(i,s,n) for (ll i = (s); (i) < (n); ++i)
#define FORD(i,s,l) for (ll i = (s); (i) >= l; --i)
#define F first
#define S second
#define TC int __tc; cin >> __tc; FOR(case_num,1,__tc+1)
#define TEST(x,i) ((x)&(1ll<<(i)))
#define SET(x,i) ((x)|(1ll<<(i)))
#define FLIP(x,i) ((x)^(1ll<<(i)))
#define CLEAR(x,i) ((x)&~(1ll<<(i)))
const double pi = 4 * atan(1);
using namespace std;
typedef long long ll;

template <typename T> void print_vec(const vector<T>& v) {
	for(int i = 0; i < SZ(v); i++) {
		if (i) cout << " ";
		cout << v[i];
	}
	cout << "\n";
}

inline ll floorDiv(ll x, ll y) {
	ll d = x / y;
	ll r = x % y;
	return r ? (d - ((x < 0) ^ (y < 0))) : d;
}

ll ceilDiv(ll x, ll y) {
	return -floorDiv(-x,y);
}

bool predicate(ll mid) {
	return mid>10;
}

ll bin_search(ll lo, ll hi) {
	int sign = lo < hi ? 1 : -1;
	lo*=sign;
	hi*=sign;
	hi++;
	while(lo < hi) {
		ll mid = floorDiv(lo+hi,2);
		if (!predicate(sign*mid)) {
			lo = mid+1;
		} else {
			hi = mid;
		}
	}
	return sign*lo;
}
const ll MOD = 1000000007;
const int MAXN = 200005;

typedef vector<int> vi;

class SegmentTree {                              // OOP style
private:
  int n;                                         // n = (int)A.size()
  vi A, st, lazy;                                // the arrays

  int l(int p) { return  p<<1; }                 // go to left child
  int r(int p) { return (p<<1)+1; }              // go to right child

  int conquer(int a, int b) {
    if (a == -1) return b;                       // corner case
    if (b == -1) return a;
    return min(a, b);                            // RMQ
  }

  void build(int p, int L, int R) {              // O(n)
    if (L == R)
      st[p] = A[L];                              // base case
    else {
      int m = (L+R)/2;
      build(l(p), L  , m);
      build(r(p), m+1, R);
      st[p] = conquer(st[l(p)], st[r(p)]);
    }
  }

  void propagate(int p, int L, int R) {
    if (lazy[p] != -1) {                         // has a lazy flag
      st[p] = min(st[p],lazy[p]);                           // [L..R] has same value
      if (L != R) {
    	  lazy[l(p)] = conquer(lazy[p], lazy[l(p)]);
    	  lazy[r(p)] = conquer(lazy[p], lazy[r(p)]);
      }
      else                                       // L == R, a single index
        A[L] = conquer(A[L],lazy[p]);             // time to update this
      lazy[p] = -1;                              // erase lazy flag
    }
  }

  int RMQ(int p, int L, int R, int i, int j) {   // O(log n)
    propagate(p, L, R);                          // lazy propagation
    if (i > j) return -1;                        // infeasible
    if ((L >= i) && (R <= j)) return st[p];      // found the segment
    int m = (L+R)/2;
    return conquer(RMQ(l(p), L  , m, i          , min(m, j)),
                   RMQ(r(p), m+1, R, max(i, m+1), j        ));
  }

  void update(int p, int L, int R, int i, int j, int val) { // O(log n)
    propagate(p, L, R);                          // lazy propagation
    if (i > j) return;
    if ((L >= i) && (R <= j)) {                  // found the segment
      lazy[p] = val;                             // update this
      propagate(p, L, R);                        // lazy propagation
    }
    else {
      int m = (L+R)/2;
      update(l(p), L  , m, i          , min(m, j), val);
      update(r(p), m+1, R, max(i, m+1), j        , val);
      int lsubtree = (lazy[l(p)] != -1) ? lazy[l(p)] : st[l(p)];
      int rsubtree = (lazy[r(p)] != -1) ? lazy[r(p)] : st[r(p)];
      st[p] = (lsubtree <= rsubtree) ? st[l(p)] : st[r(p)];
    }
  }

public:
  SegmentTree(int sz) : n(sz), st(4*n), lazy(4*n, -1) {}

  SegmentTree(const vi &initialA) : SegmentTree((int)initialA.size()) {
    A = initialA;
    build(1, 0, n-1);
  }

  void update(int i, int j, int val) { update(1, 0, n-1, i, j, val); }

  int RMQ(int i, int j) { return RMQ(1, 0, n-1, i, j); }
};

int main() {
	ios_base::sync_with_stdio(false);
	cin.tie(0);
	
	ll n;
	cin >> n;
	
	ll ans = (n-2)*(n-2);
	
	vector<int> initial(n+1);
	initial[1]=initial[n]=2;
	for (int i = 2; i <= n-1; i++) {
		initial[i]=n;
	}
	
	SegmentTree goingDown(initial);
	SegmentTree goingRight(initial);
	
	int q;
	cin >> q;
	while(q--) {
		int t, c;
		cin >> t >> c;
		if (t == 1) {
			int f = goingDown.RMQ(c,c);
			ans-=f-2;
			goingRight.update(1,f,c);
			
		} else {
			int f = goingRight.RMQ(c,c);
			ans-=f-2;
			goingDown.update(1,f,c);
		}
	}
	cout << ans << "\n";
	
	
}


Measured memory_bytes: 17956