// Original C++ solution (slower):
#include <bits/stdc++.h>

 

#define TRACE(x) cerr << #x << " = " << x << endl

#define pb push_back

#define mp make_pair

#define fi first

#define se second

 

#define SZ(x) (int)(x).size()

 

using namespace std;

 

typedef long long ll;

typedef pair<int, int> pii;

 

template<class Num>

Num mabs(Num A){

  if(A < 0) return -A;

  return A;

}



const int N = 1 << 18;



struct Tour{

  int n, off;

  vector<int> tree;

  

  Tour(int _n){

    n = _n;

    int i;

    for(i = 1; i <= n; i *= 2);

    off = i;

    tree.resize(2 * off + 1);

  }

  

  void build(int node, int a, int b){

    if(a == b){

      tree[node] = 0;

      return;

    }

    int mid = (a + b) / 2;

    build(node * 2, a, mid);    

    build(node * 2 + 1, mid + 1, b);    

    tree[node] = max(tree[node * 2], tree[node * 2 + 1]);

  }

  

  void update(int node, int a, int b, int pos, int val){

    if(a == b){

      tree[node] = max(tree[node], val);

      return;

    }

    int mid = (a + b) / 2;

    if(pos <= mid)

      update(node * 2, a, mid, pos, val);

    else

      update(node * 2 + 1, mid + 1, b, pos, val);

      

    tree[node] = max(tree[node * 2], tree[node * 2 + 1]);

  }

  

  pii walk(int node, int a, int b, int least){

    if(a == b) return mp(a, tree[node]);

    int mid = (a + b) / 2;

    if(tree[node * 2] >= least)

      return walk(node * 2, a, mid, least);

    else return walk(node * 2 + 1, mid + 1, b, least);

  }

  

  int query(int least){

    if(tree[1] < least) return n;

    return walk(1, 0, off - 1, least).fi;

  }

  

  void build(){

    build(1, 0, off - 1);

  }

  

  void update(int p, int val){

    update(1, 0, off - 1, p, val);

  }

  

  

  /*

   

  int get(int least){    

    if(tree[1] < least) return N;

    return walk(1, 0, off - 1, least).se;

  }

  

  

  int qq(int node, int a, int b, int pos){

    if(a == b) return tree[node];

    int mid = (a + b) / 2;

    if(pos <= mid) return  qq(node * 2, a, mid, pos);

    return qq(node * 2 + 1, mid + 1, b, pos);

  }

  

  int get_pos_val(int p){

    return qq(1, 0, off - 1, p);

  }

   

  */

  

};



int n, q;



int main(){

  scanf("%d %d", &n, &q);

  Tour rows(n), cols(n);

  rows.build(); cols.build();

  

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

  

  while(q--){

    int f, x; scanf("%d %d", &f, &x);

    if(f == 1){

      //x-ta kolona, spustam dolje

      int dokle = rows.query(x);

      ans -= (ll)(dokle - 2);

      cols.update(x, dokle);

    }

    

    else{

      int dokle = cols.query(x);

      ans -= (ll)(dokle - 2);

      rows.update(x, dokle);

    }

  }

  

  printf("%lld\n", ans);

  

  return 0;

}


// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

 

#define TRACE(x) cerr << #x << " = " << x << endl

#define pb push_back

#define mp make_pair

#define fi first

#define se second

 

#define SZ(x) (int)(x).size()

 

using namespace std;

 

typedef long long ll;

typedef pair<int, int> pii;

 

template<class Num>

Num mabs(Num A){

  if(A < 0) return -A;

  return A;

}



const int N = 2e5 + 10;



int n, q;

int lef_col[N];

int lef_row[N];



int main(){

  scanf("%d %d", &n, &q);

  

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

  for(int i = 1; i <= n; i++){

    lef_col[i] = lef_row[i] = n;

  }

  

  int W = n, H = n;

  

  while(q--){

    int f, x; scanf("%d %d", &f, &x);

    if(f == 1){

      if(x < W){

        for(int i = x; i < W; i++)

          lef_col[i] = H;

        W = x;

      }

      

      ans -= (ll)(lef_col[x] - 2);

    }

    else{

      if(H > x){

        for(int i = x; i < H; i++){

          lef_row[i] = W;

        }

        H = x;

      }

      

      ans -= (ll)(lef_row[x] - 2);    

    }

  } 

  

  printf("%lld\n", ans);

  

  return 0;

}


// Fastest known solution for this problem: