// @iamnifer
#include <iostream>
#include <set>
#include <vector>
#include <string>
#include <algorithm>
#include <map>
#include <stack>
#include <deque>
#include <queue>
#include <iomanip>
#include <ext/pb_ds/detail/standard_policies.hpp>
#include <ext/pb_ds/assoc_container.hpp>
#include <bits/stdc++.h>

#define ll long long
#define ld long double
#define ull unsigned long long
#define elif else if
#define pb push_back
#define add insert
#define fastio cout.tie(nullptr);cin.tie(nullptr);ios_base::sync_with_stdio(false)
#define all(x) (x).begin(),(x).end()
#define rall(x) (x).rbegin(),(x).rend()
#define len(x) (ll)((x).size())
#define gcd __gcd
#define lcm(a,b) (a)/gcd((a),(b))*(b)
#define precision(x) cout<<setprecision((x))
#define endl '\n'

using namespace std;
using namespace __gnu_pbds;

typedef pair<ll,ll>pll;
typedef tree<ll,null_type,less<ll>,rb_tree_tag,tree_order_statistics_node_update>ordered_set;
typedef tree<pll,null_type,less<pll>,rb_tree_tag,tree_order_statistics_node_update>ordered_multiset;
typedef vector<vector<ll>>graph;

template<typename A,typename B>void umin(A&a,B b){if(a>b)a=b;}
template<typename A,typename B>void umax(A&a,B b){if(a<b)a=b;}
template<typename B,typename E,typename M>M binpow(B b,E e,M m){M r=1;while(e>0){if(e&1)r=r*b%m;b=b*b%m;e>>=1;}return r;}
string to_string(string&s){return "\""+s+"\"";}
template<typename A,typename B>string to_string(pair<A,B>v){return "{"+to_string(v.first)+" "+to_string(v.second)+"}";}
template<typename T>string to_string(set<T>v){string r="{",e;for(auto i:v)r+=e+to_string(i),e=", ";return r+"}";}
template<typename T>string to_string(vector<T>v){string r="{",e;for(auto i:v)r+=e+to_string(i),e=", ";return r+"}";}
void debug(){cerr<<endl;}template<typename Head,typename...Tail>void debug(Head H,Tail...T){cerr<<" "<<to_string(H);debug(T...);}
#ifdef LOCAL
#define debug(...)cerr<<"["<<#__VA_ARGS__<<"]:",debug(__VA_ARGS__)
#else
#define debug(...)
#endif

//#pragma GCC optimize("Ofast,unroll-loops")
//#pragma GCC target("avx,avx2,fma,sse4")
//#pragma comment(linker,"/STACK:128777216")

const ld pi  = 3.14159265358979323846264338327950288419716939937510;
const ld eps = 1e-8;
const ll inf = 1e12;
const ll MOD = 1e9+7; // 998244353
const ll maxN= 2e5+9;
vector<ll>trow(maxN*3);
vector<ll>tcol(maxN*3);
vector<bool>lazyR(maxN*3,false);
vector<bool>lazyC(maxN*3,false);
void push(ll v,vector<ll>&t,vector<bool>&lazy){
    if(!lazy[v])return;
    lazy[v*2]=lazy[v*2+1]=true;
    lazy[v]=false;
    umin(t[v*2],t[v]);
    umin(t[v*2+1],t[v]);
}
void update(ll v,ll tl,ll tr,ll l,ll r,vector<bool>&lazy,vector<ll>&t,ll val){
    if(l>r)return;
    if(tl==l && tr==r){
        umin(t[v],val);
        lazy[v]=true;
        return;
    }
    push(v,t,lazy);
    ll tm=(tl+tr)/2;
    update(v*2,tl,tm,l,min(r,tm),lazy,t,val);
    update(v*2+1,tm+1,tr,max(tm+1,l),r,lazy,t,val);
}
ll get(ll v,ll tl,ll tr,ll ind,vector<ll>&t,vector<bool>&lazy){
    if(tl==tr)return t[v];
    ll tm=(tl+tr)/2;
    push(v,t,lazy);
    if(ind<=tm)return get(v*2,tl,tm,ind,t,lazy);
    return get(v*2+1,tm+1,tr,ind,t,lazy);
}
int main()
{
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    fastio;
    ll n,q;
    cin>>n>>q;
    ll ans=(n-2)*(n-2);
    trow.assign(maxN*3,n-1);
    tcol.assign(maxN*3,n-1);
    ll t,x;
    while(q--){
        cin>>t>>x;
        x--;
        if(t==1){//column
            ll res=get(1,0,n-1,x,tcol,lazyC);
            ans-=res-1;
            update(1,0,n-1,0,res-1,lazyR,trow,x);
        }
        else{
            ll res=get(1,0,n-1,x,trow,lazyR);
            ans-=res-1;
            update(1,0,n-1,0,res-1,lazyC,tcol,x);
        }
    }
    cout<<ans;
}

Measured memory_bytes: 12548