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

using ll = long long;

template< typename Monoid >
struct SegmentTree {
  using F = function< Monoid(Monoid, Monoid) >;

  int sz;
  vector< Monoid > seg;

  const F f;
  const Monoid M1;

  SegmentTree(int n, const F f, const Monoid &M1) : f(f), M1(M1) {
    sz = 1;
    while(sz < n) sz <<= 1;
    seg.assign(2 * sz, M1);
  }

  void set(int k, const Monoid &x) {
    seg[k + sz] = x;
  }

  void build() {
    for(int k = sz - 1; k > 0; k--) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  void update(int k, const Monoid &x) {
    k += sz;
    seg[k] = x;
    while(k >>= 1) {
      seg[k] = f(seg[2 * k + 0], seg[2 * k + 1]);
    }
  }

  Monoid query(int a, int b) {
    Monoid L = M1, R = M1;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) L = f(L, seg[a++]);
      if(b & 1) R = f(seg[--b], R);
    }
    return f(L, R);
  }

  Monoid operator[](const int &k) const {
    return seg[k + sz];
  }

  template< typename C >
  int find_subtree(int a, const C &check, Monoid &M, bool type) {
    while(a < sz) {
      Monoid nxt = type ? f(seg[2 * a + type], M) : f(M, seg[2 * a + type]);
      if(check(nxt)) a = 2 * a + type;
      else M = nxt, a = 2 * a + 1 - type;
    }
    return a - sz;
  }


  template< typename C >
  int find_first(int a, const C &check) {
    Monoid L = M1;
    if(a <= 0) {
      if(check(f(L, seg[1]))) return find_subtree(1, check, L, false);
      return -1;
    }
    int b = sz;
    for(a += sz, b += sz; a < b; a >>= 1, b >>= 1) {
      if(a & 1) {
        Monoid nxt = f(L, seg[a]);
        if(check(nxt)) return find_subtree(a, check, L, false);
        L = nxt;
        ++a;
      }
    }
    return -1;
  }

  template< typename C >
  int find_last(int b, const C &check) {
    Monoid R = M1;
    if(b >= sz) {
      if(check(f(seg[1], R))) return find_subtree(1, check, R, true);
      return -1;
    }
    int a = sz;
    for(b += sz; a < b; a >>= 1, b >>= 1) {
      if(b & 1) {
        Monoid nxt = f(seg[--b], R);
        if(check(nxt)) return find_subtree(b, check, R, true);
        R = nxt;
      }
    }
    return -1;
  }
};

int main(){
    ll N, Q;cin >> N >> Q;
    SegmentTree< int > MinSegH(Q, [](int a, int b) { return min(a, b); }, INT_MAX), MinSegW(Q, [](int a, int b) { return min(a, b); }, INT_MAX);
    SegmentTree< int > indexH(N + 1, [](int a, int b) { return min(a, b); }, INT_MAX), indexW(N + 1, [](int a, int b) { return min(a, b); }, INT_MAX);
    ll ans = (N - 2) * (N - 2);
    vector<pair<int, int>> Query;
    for(int i = 0;i < Q;i++){
        int a, b;
        cin >> a >> b;
        Query.push_back({a, b});
        if(a == 1){
            MinSegW.update(i, b);
        }else{
            MinSegH.update(i, b);
        }
    }
    for(int i = 0;i < Q;i++){
        int a = Query[i].first;
        int b = Query[i].second;
        if(a == 1){
            int w = indexW.query(0, b);
            //cout<<w<<" ";
            if(w == INT_MAX){
                w = i;
            }
            int q = MinSegH.query(0, w + 1);
            //cout<<q<<endl;
            if(q == INT_MAX){
                q = N;
            }
            ans -= q - 2;
            indexW.update(b - 1, i);
        }else{
            int w = indexH.query(0, b);
            if(w == INT_MAX){
                w = i;
            }
            int q = MinSegW.query(0, w + 1);
            if(q == INT_MAX){
                q =  N;
            }
            ans -= q - 2;
            indexH.update(b - 1, i);
        }
        //cout<<ans<<endl;
    }
    cout<<ans<<endl;
    return 0;
}


Measured memory_bytes: 13512