#include <bits/stdc++.h>
using namespace std;
using ll = long long;
using ld = long double;
using vl = vector<ll>;
template<class T> using vc = vector<T>;
template<class T> using vvc = vector<vector<T>>;

#define eb emplace_back
#define all(x) (x).begin(), (x).end()
#define rep(i, n) for (ll i = 0; i < (n); i++)
#define repr(i, n) for (ll i = (n)-1; i >= 0; i--)
#define repe(i, l, r) for (ll i = (l); i < (r); i++)
#define reper(i, l, r) for (ll i = (r)-1; i >= (l); i--)
#define repa(i,n) for (auto& i: n)

template<class T> inline bool chmax(T &a, const T &b) {if (a<b) { a=b; return 1;} return 0;}
template<class T> inline bool chmin(T &a, const T &b) {if (b<a) { a=b; return 1;} return 0;}
struct init{init(){cin.tie(0);ios::sync_with_stdio(false);cout<<fixed<<setprecision(15);}}init_;

#ifdef DEBUG
template <class T, class N> void verr(const T& a, const N& n) { rep(i, n) cerr << a[i] << " "; cerr << "\n" << flush; }
ll dbgt = 1; void err() { cerr << "passed " << dbgt++ << "\n" << flush; }
template<class H, class... T> void err(H&& h,T&&... t){ cerr<< h << (sizeof...(t)?" ":"\n") << flush; if(sizeof...(t)>0) err(forward<T>(t)...); }
#endif

const ll INF = 4e18;
const ld EPS = 1e-11;
const ld PI = acos(-1.0L);
const ll MOD = 1e9 + 7;
// const ll MOD = 998244353;
//--------------------------------------------------------------------------------//
template <
    class T,
    T (*fMerge)(T, T)
>
struct DualSegTree {
    int n, height;
    // 値配列, 値の単位元
    vector<T> data;
    T dataId;

    DualSegTree(
        int _n, T _did
    )
        : dataId(_did){
        n = 1, height = 0;
        while (n < _n) n *= 2, height++;
        data = vector<T>(2 * n, dataId);
    }

    inline void propagate(int k){
        data[2 * k + 0] = fMerge(data[2 * k + 0], data[k]);
        data[2 * k + 1] = fMerge(data[2 * k + 1], data[k]);
        data[k] = dataId;
    }


    // [a, b)を更新
    inline void update(int a, int b, T x) {
        a += n, b += n - 1;
        for (int i = height; i > 0; i--) propagate(a >> i), propagate(b >> i);

        for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
            if (l & 1) data[l] = fMerge(data[l], x), l++;
            if (r & 1) r--, data[r] = fMerge(data[r], x);
        }
    }

    // data[k]の取得
    inline T query(int k){
        k += n;
        for (int i = height; i > 0; i--) propagate(k >> i);
        return data[k];
    }

    inline void build(vector<T> vec){
        for (int i = 0; i < vec.size(); i++) data[i + n] = vec[i];
    }

    // 添字でアクセス
    inline T& operator[](int i) {
        return data[i + n];
    }
};

struct Data {
    ll v;                       // ☆
};
Data dataid = {INF};              // ☆

Data fme(Data f, Data g){
    return {min(f.v, g.v)};         // ☆
}

// 区間更新、点取得
// DualSegTree<Data, fme> seg(N, dataid);
// <data型, 作用素ｘ作用素> seg(個数, data単位元)

int main() {
    ll N, Q;
    cin >> N >> Q;

    DualSegTree<Data, fme> hseg(N, dataid), wseg(N, dataid);
    rep(i, N) hseg[i] = wseg[i] = {N - 2};

    ll ans = 0;
    rep(_, Q){
        ll m, k;
        cin >> m >> k, k-=2;
        if(m == 1){
            ll v = wseg.query(k).v;
            ans += v;
            hseg.update(0, v + 1, {k});
        }else{
            ll v = hseg.query(k).v;
            ans += v;
            wseg.update(0, v + 1, {k});
        }
    }

    cout << (N - 2) * (N - 2) - ans << endl;
}

Measured memory_bytes: 11296