#include <bits/stdc++.h>
using namespace std;
template<class T> ostream& operator<<(ostream &os, vector<T> V) { os << "[ "; 
  for(auto v:V)os << v << " "; return os << "]";
}
template<class T> ostream& operator<<(ostream &os, set<T> S){ os << "{ "; 
  for(auto s:S) os<<s<<" ";  return os<<"}"; 
}
template<class L, class R> ostream& operator<<(ostream &os, pair<L,R> P) {
  return os<<"("<<P.first<<","<< P.second << ")";
}
template<class L, class R> ostream& operator<<(ostream &os, map<L,R> M) {
  os<<"{ ";for(auto m:M)os<<"("<<m.first<<":"<<m.second<<")";
  return os<<"}";
}
#define cerr cout
#define TRACE
#ifdef TRACE
#define trace(...) __f(#__VA_ARGS__, __VA_ARGS__)
template <typename Arg1>
void __f(const char* name, Arg1&& arg1){
  cerr << name << " : " << arg1 << std::endl;
}
template <typename Arg1, typename... Args>
void __f(const char* names, Arg1&& arg1, Args&&... args){
  const char* comma = strchr(names + 1, ',');cerr.write(names, comma - names) << " : " << arg1<<" | ";__f(comma+1, args...);
}
#else
#define trace(...) 1
#endif
// #include <ext/pb_ds/assoc_container.hpp> 
// #include <ext/pb_ds/tree_policy.hpp> 
// using namespace __gnu_pbds;
// #define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update>
// find_by_order(k)  returns iterator to kth element starting from 0;
// order_of_key(k) returns count of elements strictly smaller than k;
//For multiset use less_equal operator but it does support erase operations for multiset
#define ll long long
#define ld long double
#define vll vector<ll>
#define pll pair<ll,ll>
#define vpll vector<pll>
#define I insert 
#define pb push_back
#define F first
#define S second
#define endl "\n"
#define all(v) (v).begin(),(v).end()
#define For(i,n) for(int i=0;i<(int)n;++i)
#define Rev(i,n) for(int i=(int)n-1;i>=0;--i)
#define Rep(i,n) for(int i=1;i<=(int)n;++i)
typedef vector<int> vi;
typedef pair<int,int> pii;
typedef pair<pii,int> ppi;
typedef vector<pii> vpi;
#define fio ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL)
#define mp make_pair
// inline void modadd(int &a,int &b){a+=b;if(a>=mod)a-=mod;} 
const int N = 2e5 + 100; 

int seg[2][4*N];
int del[2][4*N];
int n;
void build(int i, int l, int r){
  seg[0][i] = n;
  del[0][i] = n;
  seg[1][i] = n;
  del[1][i] = n;

  if(l == r){
    return;
  }
  int m = (l+r)>>1;
  build(2*i , l , m);
  build(2*i+1, m+1 , r);
}
void update(int t, int i, int l, int r, int L , int R, int val){
  //for(int j = L;j <= R; ++j)
    //del[t][j] = min(del[t][j] , val);
  if(l > R || r < L) return;
  if(l >= L && r <= R){
    del[t][i] =min(del[t][i] , val);
    return;
  }
  int m = (l+r)>>1;
  update(t , 2*i , l , m , L , R , val);
  update(t , 2*i+1 , m+1, r , L , R , val);
}
void get(int t, int i, int l, int r, int x, int &ans){
  //ans = del[t][x];
  ans = min(ans , del[t][i]);
  if(l == r){
      return;
  }
  int m = (l+r)>>1;
  if(x <= m) get(t , 2*i, l , m ,x , ans);
  else get(t , 2*i+1 , m+1 , r , x , ans); 
}

int query(int t, int x){
  int ans = n;
  get(t , 1 , 1 , n , x , ans);
  return ans;
}

//0 
//  |
//  |
//  |
//  1 - - - - -
int main(){
  fio; cout<<fixed<<setprecision(25);	
  int q; cin >> n >> q; 
  ll ans = (n-2)*1ll*(n-2);
  ll mn_x = n , mn_y = n;
  build(1 , 1 , n);
  int t, x;
  for(int i = 0;i < q ; ++i){
    cin >> t >> x;
    int v;
    if(t == 1) v = query(0 , x);
    else v = query(1 , x);
    //cout << i << ' ' << v << endl;
    ans -= (v-2ll);
    if(x < mn_x && t == 1){
      update(1 , 1 , 1 , n , 1 , mn_y-1 , x);
      mn_x = x;
    }
    if(x < mn_y && t == 2){
      update(0 , 1 , 1,  n , 1 , mn_x-1 , x);
      mn_y = x;
    }
  }
  cout << ans << endl;
  return 0;
}


Measured memory_bytes: 11760