#include<bits/stdc++.h>
using namespace std;
using ll = long long;
#define _overload3(_1,_2,_3,name,...) name
#define _rep(i,n) repi(i,0,n)
#define repi(i,a,b) for(int i=int(a);i<int(b);++i)
#define rep(...) _overload3(__VA_ARGS__,repi,_rep,)(__VA_ARGS__)
#define VIEW(x) do {cerr << #x << ": "; for(auto i : x) cerr << i << " "; cerr << endl;} while(0)
#define ALL(x) (x).begin(),(x).end()
template<class T>bool umax(T &a, const T &b) {if(a<b){a=b;return 1;}return 0;}
template<class T>bool umin(T &a, const T &b) {if(b<a){a=b;return 1;}return 0;}

template<typename A,size_t N,typename T> void FILL(A (&array)[N],const T &val){fill((T*)array,(T*)(array+N),val);}
template<typename T> void FILL(vector<T> &v, const T &x) {fill(v.begin(), v.end(), x);}
template<typename T> void FILL(vector<vector<T>> &v, const T &x) {for(auto &i:v)fill(i.begin(), i.end(), x);}

struct segment_tree {
  vector<ll> node, lazy;
  vector<bool> has_lazy;
  ll n;
  const ll dummy;

  segment_tree(ll n, ll dummy) : dummy(dummy) {
    ll msb = 1LL << ((n==0) ? 0 : 64 - __builtin_clzll(n)-1);
    this->n = (n==msb) ? n : msb << 1;
    node.resize(2 * this->n - 1);
    fill(node.begin(), node.end(), dummy);
    lazy.resize(2 * this->n - 1);
    fill(lazy.begin(), lazy.end(), dummy);
    has_lazy.resize(2 * this->n - 1);
    fill(has_lazy.begin(), has_lazy.end(), false);
  }

  inline ll r_child(ll v) { return v*2+2; }
  inline ll l_child(ll v) { return v*2+1; }
  inline ll parent(ll v) { return (v + (v%2)) / 2 - 1; }
  inline bool is_leaf(ll v) { return v >= node.size()/2; }

  ll query(ll ql, ll qr, ll v=0, ll l=0, ll r=-1) {
    r = (r==-1) ? n-1 : r;
    lazy_update(v);
    if(ql<=l && r<=qr) return node[v];
    ll ret = dummy, mid=(l+r)/2;
    if(ql <= mid)   ret = min(ret, query(ql, qr, l_child(v), l,     mid));
    if(qr >= mid+1) ret = min(ret, query(ql, qr, r_child(v), mid+1, r  ));
    return ret;
  }

  void lazy_update(ll v) { 
    if(has_lazy[v]) {
      node[v] = min(node[v], lazy[v]);
      if ( !is_leaf(v) ) {
        umin(lazy[l_child(v)], lazy[v]);
        umin(lazy[r_child(v)], lazy[v]);
        has_lazy[l_child(v)] = true;
        has_lazy[r_child(v)] = true;
      }
      lazy[v] = dummy;
      has_lazy[v] = false;
    }
  }

  void set_value(ll ql, ll qr, ll val, ll v=0, ll l=0, ll r=-1) {
    r = (r==-1) ? n-1 : r;
    lazy_update(v);
    if(ql > r ||  qr < l) return;
    if(ql<=l && r<=qr) {
      umin(lazy[v], val);
      has_lazy[v] = true;
      lazy_update(v);
    }
    else {
      ll mid=(l+r)/2;
      set_value(ql, qr, val, l_child(v), l,     mid);
      set_value(ql, qr, val, r_child(v), mid+1, r  );
      node[v] = min(node[l_child(v)], node[r_child(v)]);
    }
  }
};

int main() {
  ll n, q; cin >> n >> q;

  segment_tree upper(n, n-1);
  segment_tree lefter(n, n-1);

  ll ans = (n-2) * (n-2);

  rep(i,q) {
    //cerr << "query " << i+1 << "(before): " << ans << endl;
    ll t, x; cin >> t >> x;
    x--;
    if(t==1) { //上に置く
      ll limit = upper.query(x,x);
      //cerr << "lim: " << limit << endl;
      ans -= limit - 1;
      lefter.set_value(0, limit, x);
    }
    else { //左に置く
      ll limit = lefter.query(x,x);
      //cerr << "lim: " << limit << endl;
      ans -= limit - 1;
      upper.set_value(0, limit, x);
    }
    //cerr << "query " << i+1 << "(after ): " << ans << endl;
  }
  cout << ans << endl;
}


Measured memory_bytes: 19896