#include <bits/stdc++.h>
#define rep(i, n) for (ll i = 0; i < ll(n); i++)
#define rrep(i, n) for (int i = (n); i >= 0; i--)
#define loop(i, r, n) for (int i = (r); i < (n); i++)
#define pb push_back
#define all(in) in.begin(),in.end()

template<class T>bool chmax(T& a, const T& b) { if (a < b) { a = b; return 1; } return 0; }
template<class T>bool chmin(T& a, const T& b) { if (b < a) { a = b; return 1; } return 0; }

using ll = long long;
using namespace std;
// cout << fixed << setprecision(10）<<  << endl;

// 遅延評価セグメント木 RSQ

struct lazyRMQ {
    const ll INF = 1ll<<60;
    int n;
    vector<ll> data, lazy;

    lazyRMQ() {}
    lazyRMQ(int n_) { init(n_); }
    lazyRMQ(int n_, vector<ll> &vec) { init(n_); set(vec); build(); }
    void init(int n_) {
        n = 1; while (n < n_) n <<= 1;
        data.assign(n<<1,INF);
        lazy.assign(n<<1,INF);
    }
    void set(vector<ll> &vec) {
        for (int i = 0; i < (int)vec.size(); i++) data[i+n] = vec[i];
    }
    void build() {
        for (int i = n-1; i > 0; i--) data[i] = min(data[i<<1],data[(i<<1)|1]);
    }

    void eval(int k) {
        if (lazy[k] == INF) return;
        data[k] = min(data[k],lazy[k]);
        if (k < n) {
            lazy[(k<<1)|0] = min(lazy[(k<<1)|0],lazy[k]);
            lazy[(k<<1)|1] = min(lazy[(k<<1)|1],lazy[k]);
        }
        lazy[k] = INF;
    }
    void update(int a, int b, ll x, int k = 1, int l = 0, int r = 0) {
        if (r == 0) r = n;
        eval(k);
        if (r <= a || b <= l) return;
        else if (a <= l && r <= b) { lazy[k] = x; eval(k); }
        else {
            update(a, b, x, (k<<1)|0, l, (l+r)/2);
            update(a, b, x, (k<<1)|1, (l+r)/2, r);
            data[k] = min(data[k<<1],data[(k<<1)|1]);
        }
    }
    ll query(int a, int b, int k = 1, int l = 0, int r = 0) {
        if (r == 0) r = n;
        if (r <= a || b <= l) return INF;
        eval(k);
        if (a <= l && r <= b) return data[k];
        else {
            ll vl = query(a, b, (k<<1)|0, l, (l+r)/2);
            ll vr = query(a, b, (k<<1)|1, (l+r)/2, r);
            return min(vl,vr);
        }
    }
    int find_rightest(int a, int b, ll x, int k = 1, int l = 0, int r = 0) {
        if (r == 0) r = n;
        eval(k);
        if (data[k] > x || r <= a || b <= l) return -1;
        else if (k >= n) return k - n;
        int vr = find_rightest(a, b, x, (k<<1)|1, (l+r)/2, r);
        if (vr != -1) return vr;
        return find_rightest(a, b, x, k<<1, l, (l+r)/2);
    } // [a,b)でx以上となるrihgtest_index(ない場合 : -1)
    int find_leftest(int a, int b, ll x, int k = 1, int l = 0, int r = 0) {
        if (r == 0) r = n;
        eval(k);
        if (data[k] > x || r <= a || b <= l) return -1;
        else if (k >= n) return k - n;
        int vr = find_leftest(a, b, x, k<<1, (l+r)/2, r);
        if (vr != -1) return vr;
        return find_leftest(a, b, x, (k<<1)|1, l, (l+r)/2);
    } // [a,b)でx以上となるleftest_index(ない場合 : -1)
};

int main() {
    ll n, q; cin >> n >> q;
    vector<ll> sub(n,n);
    lazyRMQ save1(n,sub), save2(n,sub);
    ll count = (n - 2) * (n - 2);
    while (q--) {
        ll t, x; cin >> t >> x;
        if (t == 1) {
            int end = save1.query(x-1,x);
            count -= end - 2;
            save2.update(1,end,x);
        }
        else {
            int end = save2.query(x-1,x);
            count -= end - 2;
            save1.update(1,end,x);
        }
    }
    cout << count << endl;
    return 0;
}

Measured memory_bytes: 21140