#include <bits/stdc++.h>
using namespace std;
 
using ll = long long;
#define endl '\n'

constexpr ll MAX_N = 2e5+10;

class SegTree {
public:
  int n;
  ll a[MAX_N];
  bool lazy[MAX_N*4];
  ll lazy_init[MAX_N*4];
  ll lazy_mult[MAX_N*4];
  ll lazy_add[MAX_N*4];
  ll sum[MAX_N*4];

  void Build(ll v, ll tl, ll tr) {
    if (tl == tr) {
      sum[v] = a[tl];
    } else {
      ll tm = (tl+tr)>>1;
      Build(v*2 + 0, tl, tm);
      Build(v*2 + 1, tm+1, tr);
      sum[v] = sum[v*2] + sum[v*2+1];
    }
  }
  void init_tree(ll _n) {
    n = _n;
    memset(lazy, 0, n<<2);
    memset(lazy_init, 0, n<<4);
    memset(lazy_add, 0, n<<4);
    fill(lazy_mult, lazy_mult+(n<<2), 1);
    Build(1, 0, n-1);
  }


  ll get(ll v, ll tl, ll tr) {
    if (lazy[v]) {
      ll s = lazy_init[v] != 0 ? lazy_init[v]*(tr-tl+1) : sum[v];
      if (lazy_mult[v] != 1) s = s*lazy_mult[v];
      if (lazy_add[v] != 0) s = s + lazy_add[v]*(tr-tl+1);
      return s;
    } else {
      return sum[v];
    }
  }

  void update(ll v, ll tl, ll tr) {
    ll tm = (tl+tr)/2;
    sum[v] = get(v*2, tl, tm) + get(v*2+1, tm+1, tr);
  }

  void push(ll v) {
    if (!lazy[v]) return;
    lazy[v*2] = lazy[v*2+1] = true;
    if (lazy_init[v] != 0) {
      lazy_init[v*2] = lazy_init[v*2+1] = lazy_init[v];
      lazy_mult[v*2] = lazy_mult[v*2+1] = lazy_mult[v];
      lazy_add[v*2] = lazy_add[v*2+1] = lazy_add[v];
    } else {
      lazy_mult[v*2] = lazy_mult[v*2]*lazy_mult[v];
      lazy_mult[v*2+1] = lazy_mult[v*2+1]*lazy_mult[v];
      lazy_add[v*2] = lazy_add[v*2]*lazy_mult[v] + lazy_add[v];
      lazy_add[v*2+1] = lazy_add[v*2+1]*lazy_mult[v] + lazy_add[v];
    }
    lazy_init[v] = 0;
    lazy_mult[v] = 1;
    lazy_add[v] = 0;
    lazy[v] = false;
  }

  void add(ll v, ll tl, ll tr, ll l, ll r, ll value) {
    if (l > r) return;
    if (tl == l && tr == r) {
      lazy[v] = true;
      lazy_add[v] += value;
    } else {
      push(v);
      ll tm = (tl+tr)>>1;
      add(v*2, tl, tm, l, min(tm, r), value);
      add(v*2+1, tm+1, tr, max(l, tm+1), r, value);
      update(v, tl, tr);
    }
  }

  void add(ll l, ll r, ll x) {
    add(1, 0, n-1, l, r, x);
  }

  void mult(ll v, ll tl, ll tr, ll l, ll r, ll value) {
    if (l > r) return;
    if (tl == l && tr == r) {
      lazy[v] = true;
      lazy_mult[v] = lazy_mult[v]*value;
      lazy_add[v] = lazy_add[v]*value;
    } else {
      push(v);
      ll tm = (tl+tr)>>1;
      mult(v*2, tl, tm, l, min(tm, r), value);
      mult(v*2+1, tm+1, tr, max(l, tm+1), r, value);
      update(v, tl, tr);
    }
  }

  void mult(ll l, ll r, ll v) {
    mult(1, 0, n-1, l, r, v);
  }

  void init(ll v, ll tl, ll tr, ll l, ll r, ll value) {
    if (l > r) return;
    if (tl == l && tr == r) {
      lazy[v] = true;
      lazy_init[v] = value;
      lazy_mult[v] = 1;
      lazy_add[v] = 0;
    } else {
      push(v);
      ll tm = (tl+tr)>>1;
      init(v*2, tl, tm, l, min(tm, r), value);
      init(v*2+1, tm+1, tr, max(l, tm+1), r, value);
      update(v, tl, tr);
    }
  }

  void init(ll l, ll r, ll v) {
    init(1, 0, n-1, l, r, v);
  }

  ll Query(ll v, ll tl, ll tr, ll l, ll r) {
    if (l > r) return 0;
    if (tl == l && tr == r) {
      return get(v, tl, tr);
    }
    push(v);
    ll tm = (tl+tr)>>1;
    ll ret = Query(v*2, tl, tm, l, min(tm, r)) + Query(v*2+1, tm+1, tr, max(tm+1, l), r);
    update(v, tl, tr);
    return ret;
  }
};

int main() {
  ios::sync_with_stdio(0); cin.tie(0);
 
  ll N,q;
  cin >> N >> q;

  ll ans = (N-2)*(N-2);
  SegTree stree_y, stree_x;
  for (int i = 0; i < N; ++i) {
    stree_y.a[i] = N-1;
    stree_x.a[i] = N-1;
  }
  stree_y.init_tree(N);
  stree_x.init_tree(N);
  int MIN_X = N+1, MIN_Y = N+1;
  for (int i = 0; i < q; ++i) {
    int type,val;
    cin >> type >> val;
    --val;
    if (type == 1) {
      // vertical line starting at x
      int x = val;
      int y_white = stree_x.Query(1, 0, N-1, x, x);
      int n_rem = y_white-1;
      ans -= max(0,y_white-1); // -1 since first line is blanks
      if (x < MIN_X) {
        MIN_X = x;
        stree_y.init(0, y_white, x);
      }
    } else {
      int y = val;
      int x_white = stree_y.Query(1, 0, N-1, y, y);
      int n_rem = x_white-1;
      ans -= max(0,x_white-1); // -1 since first line is blanks
      if (y < MIN_Y) {
        MIN_Y = y;
        stree_x.init(0, x_white, y);
      }
    }
  }
  cout << ans << endl;
}


Measured memory_bytes: 44496