#include <bits/stdc++.h>
using namespace std;
#define getbit(n, i) (((n) & (1LL << (i))) != 0) 
#define setbit0(n, i) ((n) & (~(1LL << (i)))) 
#define setbit1(n, i) ((n) | (1LL << (i))) 
#define togglebit(n, i) ((n) ^ (1LL << (i))) 
#define lastone(n) ((n) & (-(n))) 
char gap = 32;
template<typename T> 
ostream& operator<<(ostream &os, const vector<T> &v) { 
    os << '{'; 
    for (const auto &x : v) os << gap << x;
        return os << '}'; 
}
template<typename A, typename B> 
ostream& operator<<(ostream &os, const pair<A, B> &p) {
        return os << '(' << p.first << gap << p.second << ')';
}

template <class T>
void read(T &x) {
    char c;
    for (c = getchar(); c < '0' || c > '9'; c = getchar())
        ;
    for (x = 0; c <= '9' && c >= '0'; c = getchar()) x = x * 10 + (c & 15);
}
#define ll long long 
#define lll __int128_t
#define pb push_back
#define mp make_pair
typedef pair < int,int> ii;
typedef vector<ii> vii;
typedef vector<ll>vl;
typedef vector<int> vi;
typedef vector<vi> vvi;
#define mx 200005
struct  {
    ll prop, mini;
} tree[mx * 4]; //sum ছাড়াও নিচে অতিরিক্ত কত যোগ হচ্ছে সেটা রাখবো prop এ
void update(ll node, ll b, ll e, ll i, ll j,ll x)
{
    if (i > e || j < b){
        if(tree[node].prop!=0){
             if(tree[node].mini!=0)
                tree[node].mini = min(tree[node].mini, tree[node].prop);
            else
                tree[node].mini = tree[node].prop;
        }
        if(b!=e&&tree[node].prop!=0){
            ll Left = node * 2;
            ll Right = (node * 2) + 1;
            if(tree[Left].prop!=0)
                tree[Left].prop = min(tree[Left].prop, tree[node].prop);
            else
                tree[Left].prop = tree[node].prop;
            if(tree[Right].prop!=0)
                tree[Right].prop = min(tree[Right].prop, tree[node].prop);
            else
                tree[Right].prop = tree[node].prop;    
        }
        tree[node].prop = 0;
        return;
    }
    if (b >= i && e <= j) //নোডের রেঞ্জ আপডেটের রেঞ্জের ভিতরে
    {
        if(tree[node].prop!=0)
            tree[node].prop = min(tree[node].prop, x);
        else
            tree[node].prop = x;
        if(tree[node].prop!=0){
             if(tree[node].mini!=0)
                tree[node].mini = min(tree[node].mini, tree[node].prop);
            else
                tree[node].mini = tree[node].prop;
        }
        if(b!=e&&tree[node].prop!=0){
            ll Left = node * 2;
            ll Right = (node * 2) + 1;
            if(tree[Left].prop!=0)
                tree[Left].prop = min(tree[Left].prop, tree[node].prop);
            else
                tree[Left].prop = tree[node].prop;
            if(tree[Right].prop!=0)
                tree[Right].prop = min(tree[Right].prop, tree[node].prop);
            else
                tree[Right].prop = tree[node].prop;    
        }
        tree[node].prop = 0;
        return;
    }
    ll Left = node * 2;
    ll Right = (node * 2) + 1;
    ll mid = (b + e) / 2;
    update(Left, b, mid, i, j, x);
    update(Right, mid + 1, e, i, j, x);
    if(tree[Right].mini!=0)
        tree[node].mini = tree[Right].mini;
    if(tree[Left].mini!=0){
        if(tree[node].mini==0)
            tree[node].mini = tree[Left].mini;
        else
            tree[node].mini = min(tree[node].mini, tree[Left].mini);
    }    
    if(tree[node].prop!=0){
             if(tree[node].mini!=0)
                tree[node].mini = min(tree[node].mini, tree[node].prop);
            else
                tree[node].mini = tree[node].prop;
        }
        if(b!=e&&tree[node].prop!=0){
            ll Left = node * 2;
            ll Right = (node * 2) + 1;
            if(tree[Left].prop!=0)
                tree[Left].prop = min(tree[Left].prop, tree[node].prop);
            else
                tree[Left].prop = tree[node].prop;
            if(tree[Right].prop!=0)
                tree[Right].prop = min(tree[Right].prop, tree[node].prop);
            else
                tree[Right].prop = tree[node].prop;    
        }
        tree[node].prop = 0;
}
ll query(ll node, ll b, ll e, ll i, ll j, ll carry)
{
    if (i > e || j < b)
        return 2e9;
    if (b >= i and e <= j){
        ll minim = carry;
        if(tree[node].mini!=0)
            minim = min(minim, tree[node].mini);
        if(tree[node].prop!=0)
            minim = min(minim, tree[node].prop);
        return minim;
    }
    ll Left = node << 1;
    ll Right = (node << 1) + 1;
    ll mid = (b + e) >> 1;
    ll minim = carry;
    if(tree[node].prop!=0)
        minim = min(minim, tree[node].prop);
     ll p1 = query(Left, b, mid, i, j, minim); //প্রপাগেট ভ্যালু বয়ে নিয়ে যাচ্ছে carry ভ্যারিয়েবল
     ll p2 = query(Right, mid + 1, e, i, j, minim);

     return min(p1, p2);
}
struct  {
    ll prop, mini;
} tree1[mx * 4];
void update1(ll node, ll b, ll e, ll i, ll j,ll x)
{
    if (i > e || j < b){
        if(tree1[node].prop!=0){
             if(tree1[node].mini!=0)
                tree1[node].mini = min(tree1[node].mini, tree1[node].prop);
            else
                tree1[node].mini = tree1[node].prop;
        }
        if(b!=e&&tree1[node].prop!=0){
            ll Left = node * 2;
            ll Right = (node * 2) + 1;
            if(tree1[Left].prop!=0)
                tree1[Left].prop = min(tree1[Left].prop, tree1[node].prop);
            else
                tree1[Left].prop = tree1[node].prop;
            if(tree1[Right].prop!=0)
                tree1[Right].prop = min(tree1[Right].prop, tree1[node].prop);
            else
                tree1[Right].prop = tree1[node].prop;    
        }
        tree1[node].prop = 0;
        return;
    }
    if (b >= i && e <= j) //নোডের রেঞ্জ আপডেটের রেঞ্জের ভিতরে
    {
        if(tree1[node].prop!=0)
            tree1[node].prop = min(tree1[node].prop, x);
        else
            tree1[node].prop = x;
        if(tree1[node].prop!=0){
             if(tree1[node].mini!=0)
                tree1[node].mini = min(tree1[node].mini, tree1[node].prop);
            else
                tree1[node].mini = tree1[node].prop;
        }
        if(b!=e&&tree1[node].prop!=0){
            ll Left = node * 2;
            ll Right = (node * 2) + 1;
            if(tree1[Left].prop!=0)
                tree1[Left].prop = min(tree1[Left].prop, tree1[node].prop);
            else
                tree1[Left].prop = tree1[node].prop;
            if(tree1[Right].prop!=0)
                tree1[Right].prop = min(tree1[Right].prop, tree1[node].prop);
            else
                tree1[Right].prop = tree1[node].prop;    
        }
        tree1[node].prop = 0;
        return;
    }
    ll Left = node * 2;
    ll Right = (node * 2) + 1;
    ll mid = (b + e) / 2;
    update1(Left, b, mid, i, j, x);
    update1(Right, mid + 1, e, i, j, x);
    if(tree1[Right].mini!=0)
        tree1[node].mini = tree1[Right].mini;
    if(tree1[Left].mini!=0){
        if(tree1[node].mini==0)
            tree1[node].mini = tree1[Left].mini;
        else
            tree1[node].mini = min(tree1[node].mini, tree1[Left].mini);
    }    
    if(tree1[node].prop!=0){
             if(tree1[node].mini!=0)
                tree1[node].mini = min(tree1[node].mini, tree1[node].prop);
            else
                tree1[node].mini = tree1[node].prop;
        }
        if(b!=e&&tree1[node].prop!=0){
            ll Left = node * 2;
            ll Right = (node * 2) + 1;
            if(tree1[Left].prop!=0)
                tree1[Left].prop = min(tree1[Left].prop, tree1[node].prop);
            else
                tree1[Left].prop = tree1[node].prop;
            if(tree1[Right].prop!=0)
                tree1[Right].prop = min(tree1[Right].prop, tree1[node].prop);
            else
                tree1[Right].prop = tree1[node].prop;    
        }
        tree1[node].prop = 0;
}
ll query1(ll node, ll b, ll e, ll i, ll j, ll carry)
{
    if (i > e || j < b)
        return 2e9;
    if (b >= i and e <= j){
        ll minim = carry;
        if(tree1[node].mini!=0)
            minim = min(minim, tree1[node].mini);
        if(tree1[node].prop!=0)
            minim = min(minim, tree1[node].prop);
        return minim;
    }
    ll Left = node << 1;
    ll Right = (node << 1) + 1;
    ll mid = (b + e) >> 1;
    ll minim = carry;
    if(tree1[node].prop!=0)
        minim = min(minim, tree1[node].prop);
     ll p1 = query1(Left, b, mid, i, j, minim); //প্রপাগেট ভ্যালু বয়ে নিয়ে যাচ্ছে carry ভ্যারিয়েবল
     ll p2 = query1(Right, mid + 1, e, i, j, minim);

     return min(p1, p2);
}
int main(){
    ios_base::sync_with_stdio(false);
    cin.tie(0);
    ll i,j,k,l,n,m;
    cin >> n >> m;
    ll ans = (n - 2) * (n - 2);
    
    for (i = 1; i <= m;i++){
        ll tp, val;
        cin >> tp;
        if(tp==1){
            cin >> val;
            ll mini1 = min(n, query1(1, 1, n, val, val, 2e9));
            ll mini2 = 1;
            ///cout << mini1 << "\n";
            ans -= max(0LL, mini1 - mini2 - 1);
            if(mini1>=2){
                update(1, 1, n, 2, mini1, val);
            }
        }
        else{
            cin >> val;
            ll mini1 = min(n, query(1, 1, n, val, val, 2e9));
            ll mini2 = 1;
            ///cout << mini1 << "\n";
            ans -= max(0LL, mini1 - mini2 - 1);
            if(mini1>=2){
                update1(1, 1, n, 2, mini1, val);
            }
        }
    }
    cout << ans << "\n";
    return 0;
}

Measured memory_bytes: 11808