// {{{ by unolight
#pragma region
#include <bits/stdc++.h>
#include <unistd.h>
#pragma GCC diagnostic ignored "-Wunused-result"
#pragma GCC diagnostic ignored "-Wunused-function"
#define SZ(x) ((int)(x).size())
#define ALL(x) begin(x),end(x)
#define RALL(x) rbegin(x),rend(x)
#define REP(i,n) for ( int i=0; i<int(n); i++ )
#define REP1(i,a,b) for ( int i=(a); i<=int(b); i++ )
#define MP make_pair
#define PB push_back
using namespace std;
typedef int64_t LL;
typedef pair<int,int> PII;
typedef vector<int> VI;

namespace { namespace unolight {
// Read Input
template<class T> void _R( T &x ) { cin>>x; }
void _R( int &x ) { scanf("%d",&x); }
void _R( int64_t &x ) { scanf("%" PRId64,&x); }
void _R( double &x ) { scanf("%lf",&x); }
void _R( char &x ) { scanf(" %c",&x); }
void _R( char *x ) { scanf("%s",x); }
void R() {}
template<class T, class... U> void R( T& head, U&... tail ) { _R(head); R(tail...); }
// Write Output
template<class T> void _W( const T &x ) { cout<<x; }
void _W( const int &x ) { printf("%d",x); }
void _W( const int64_t &x ) { printf("%" PRId64,x); }
void _W( const double &x ) { printf("%.16f\n",x); }
void _W( const char &x ) { putchar(x); }
void _W( const char *x ) { printf("%s",x); }
template<class T> void _W( const vector<T> &x ) { for (auto i = x.begin(); i != x.end(); _W(*i++)) if (i != x.cbegin()) putchar(' '); }
void W() {}
template<class T, class... U> void W( const T& head, const U&... tail ) { _W(head); putchar(sizeof...(tail)?' ':'\n'); W(tail...); }

#ifdef UNOLIGHT
#include "dump.hpp"
#else
#define dump(...)
#endif

template<class T> inline bool chmax( T &a, const T &b ) { return b>a ? a=b,true : false; }
template<class T> inline bool chmin( T &a, const T &b ) { return b<a ? a=b,true : false; }
template<class T> using MaxHeap = priority_queue<T>;
template<class T> using MinHeap = priority_queue<T, vector<T>, greater<T>>;
template<class T, class F=less<T>> void sort_uniq( vector<T> &v, F f=F() ) {
    sort(begin(v),end(v),f);
    v.resize(unique(begin(v),end(v))-begin(v));
}
#pragma endregion
// }}}

template<typename T>
struct LazySegtree {
    int n;
    T e; // default value
    vector<T> dat, lazy;
    typedef function<T(T a, T b)> Func;
    Func f;

    LazySegtree(){}
    LazySegtree(int n_input, Func f_input, T e_input) {
        initialize(n_input, f_input, e_input);
    }

    void initialize(int n_input, Func f_input, T e_input) {
        f = f_input;
        e = e_input;
        n = 1;
        while ( n<n_input ) { n<<=1; }
        dat.resize(2*n-1, e);
        lazy.resize(2*n-1, e);
    }
  
    // [l, r)
    void propagate(int k, int l, int r) {
        // dat[k] += (r - l) * lazy[k];
        dat[k] = f(dat[k], lazy[k]);
        if ( l+1<r ) { 
           lazy[2*k+1] = f(lazy[2*k+1], lazy[k]);
           lazy[2*k+2] = f(lazy[2*k+2], lazy[k]);
        }
        lazy[k] = n;
    }

    void update(int a, int b, T x) {
        _update(a, b, 0, 0, n, x);
    }

    // top-down
    void _update(int a, int b, int k, int l, int r, T x) {
        propagate(k, l, r);
        if ( r<=a || b<=l ) {
            return;
        }
        if ( a<=l && r<=b ) {
            lazy[k] = f(lazy[k], x);
            return;
        }
        _update(a, b, 2*k+1, l, (l+r)/2, x);
        _update(a, b, 2*k+2, (l+r)/2, r, x);
        propagate(2*k+1, l, (l+r)/2);
        propagate(2*k+2, (l+r)/2, r);
        dat[k] = f(dat[2*k+1], dat[2*k+2]);
    }

    T get(int k) {
        return query(k, k+1);
    }

    // [a, b)
    T query(int a, int b) {
        return _query(a, b, 0, 0, n);
    }

    // [a, b)
    T _query(int a, int b, int k, int l, int r) {
        propagate(k, l, r);
        if ( r<=a || b<=l ) return e;  // not in range
        if ( a<=l && r<=b ) return dat[k]; // in range
        T vl = _query(a, b, 2*k+1, l, (l+r)/2);
        T vr = _query(a, b, 2*k+2, (l+r)/2, r);
        return f(vl, vr);
    }
};
/** Usage:
LazySegtree<int> seg(n, [](int a, int b) {return max(a,b);}, 0); // init
REP(i, n+1) seg.update(i, i)
seg.query(a, b)
*/

void main() {
    LL n,q;
    R(n,q);
    LL ans=(n-2)*(n-2);
    // 0 ~ n-1
    // black 2 ~ n-1
    LazySegtree<int> col(n+1, [](int a, int b) {return min(a,b);}, n-1); // init
    LazySegtree<int> row(n+1, [](int a, int b) {return min(a,b);}, n-1); // init
    REP(qq,q) {
        int t,x;
        R(t,x);
        if ( t==1 ) { // change (1,x) to (n,x)
            int y=col.query(x,x+1); // upmost black
            ans-=y-1;
            // dump(y,ans);
            row.update(1,y+1,x-1);
        } else { // change (x,1) to (x,n)
            int y=row.query(x,x+1); // upmost black
            ans-=y-1;
            // dump(y,ans);
            col.update(1,y+1,x-1);
        }
    }
    W(ans);
}

}} // {{{ main
int main() { unolight::main(); return 0; }
// }}}


Measured memory_bytes: 11436