// Original C++ solution (slower):
#include <bits/stdc++.h>

using namespace std;

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

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



#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)

{ return s << '<' << P.first << ", " << P.second << '>'; }

template<class T> ostream& operator << (ostream &s, deque<T> P)

{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }

template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)

{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }

template<class T> ostream& operator << (ostream &s, set<T> P)

{ for(auto it : P) { s << "<" << it << "> "; } return s << endl; }

template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)

{ for(auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s << endl; }







// Segment Tree

template<class Monoid, class Action> struct SegTree {

    using FuncMonoid = function< Monoid(Monoid, Monoid) >;

    using FuncAction = function< void(Monoid&, Action) >;

    using FuncLazy = function< void(Action&, Action) >;

    FuncMonoid FM;

    FuncAction FA;

    FuncLazy FL;

    Monoid UNITY_MONOID;

    Action UNITY_LAZY;

    int SIZE, HEIGHT;

    vector<Monoid> dat;

    vector<Action> lazy;

    

    SegTree() { }

    SegTree(int n, const FuncMonoid fm, const FuncAction fa, const FuncLazy fl,

            const Monoid &unity_monoid, const Action &unity_lazy)

    : FM(fm), FA(fa), FL(fl), UNITY_MONOID(unity_monoid), UNITY_LAZY(unity_lazy) {

        SIZE = 1; HEIGHT = 0;

        while (SIZE < n) SIZE <<= 1, ++HEIGHT;

        dat.assign(SIZE * 2, UNITY_MONOID);

        lazy.assign(SIZE * 2, UNITY_LAZY);

    }

    void init(int n, const FuncMonoid fm, const FuncAction fa, const FuncLazy fl,

              const Monoid &unity_monoid, const Action &unity_lazy) {

        FM = fm; FA = fa; FL = fl;

        UNITY_MONOID = unity_monoid; UNITY_LAZY = unity_lazy;

        SIZE = 1; HEIGHT = 0;

        while (SIZE < n) SIZE <<= 1, ++HEIGHT;

        dat.assign(SIZE * 2, UNITY_MONOID);

        lazy.assign(SIZE * 2, UNITY_LAZY);

    }

    

    /* set, a is 0-indexed */

    void set(int a, const Monoid &v) { dat[a + SIZE] = v; }

    void build() {

        for (int k = SIZE - 1; k > 0; --k)

            dat[k] = FM(dat[k*2], dat[k*2+1]);

    }

    

    /* update [a, b) */

    inline void evaluate(int k) {

        if (lazy[k] == UNITY_LAZY) return;

        if (k < SIZE) FL(lazy[k*2], lazy[k]), FL(lazy[k*2+1], lazy[k]);

        FA(dat[k], lazy[k]);

        lazy[k] = UNITY_LAZY;

    }

    inline void update(int a, int b, const Action &v, int k, int l, int r) {

        evaluate(k);

        if (a <= l && r <= b)  FL(lazy[k], v), evaluate(k);

        else if (a < r && l < b) {

            update(a, b, v, k*2, l, (l+r)>>1), update(a, b, v, k*2+1, (l+r)>>1, r);

            dat[k] = FM(dat[k*2], dat[k*2+1]);

        }

    }

    inline void update(int a, int b, const Action &v) { update(a, b, v, 1, 0, SIZE); }

    

    /* get [a, b) */

    inline Monoid get(int a, int b, int k, int l, int r) {

        evaluate(k);

        if (a <= l && r <= b)

            return dat[k];

        else if (a < r && l < b)

            return FM(get(a, b, k*2, l, (l+r)>>1), get(a, b, k*2+1, (l+r)>>1, r));

        else

            return UNITY_MONOID;

    }

    inline Monoid get(int a, int b) { return get(a, b, 1, 0, SIZE); }

    inline Monoid operator [] (int a) { return get(a, a+1); }

    

    /* debug */

    void print() {

        for (int i = 0; i < SIZE; ++i) { cout << (*this)[i]; if (i != SIZE) cout << ","; }

        cout << endl;

    }

};







int main() {

    long long N, Q;

    cin >> N >> Q;

    long long res = (N - 2) * (N - 2);



    auto fm = [](long long a, long long b) { return min(a, b); };

    auto fa = [](long long &a, long long d) { chmin(a, d); };

    auto fl = [](long long &d, long long e) { chmin(d, e); };

    SegTree<long long, long long> yoko(N, fm, fa, fl, N-1, N-1);

    SegTree<long long, long long> tate(N, fm, fa, fl, N-1, N-1);



    for (int _ = 0; _ < Q; ++_) {

        int type, a, val;

        cin >> type >> a;

        --a;

        if (type == 1) {

            val = yoko.get(a, a + 1);

            res -= val - 1;

            tate.update(0, val, a);

            tate.update(val, val + 1, 0);

        }

        else {

            val = tate.get(a, a + 1);

            res -= val - 1;

            yoko.update(0, val, a);

            yoko.update(val, val + 1, 0);

        }



/*

        COUT("----------");

        COUT(_);

        COUT(type); COUT(a);

        COUT(val);

        tate.print();

        yoko.print();

        */

    }

    cout << res << endl;

}

// Optimized solution to the same problem (faster):
#include <bits/stdc++.h>

using namespace std;

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

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



#define COUT(x) cout << #x << " = " << (x) << " (L" << __LINE__ << ")" << endl

template<class T1, class T2> ostream& operator << (ostream &s, pair<T1,T2> P)

{ return s << '<' << P.first << ", " << P.second << '>'; }

template<class T> ostream& operator << (ostream &s, vector<T> P)

{ for (int i = 0; i < P.size(); ++i) { if (i > 0) { s << " "; } s << P[i]; } return s; }

template<class T> ostream& operator << (ostream &s, vector<vector<T> > P)

{ for (int i = 0; i < P.size(); ++i) { s << endl << P[i]; } return s << endl; }

template<class T> ostream& operator << (ostream &s, set<T> P)

{ for(auto it : P) { s << "<" << it << "> "; } return s << endl; }

template<class T1, class T2> ostream& operator << (ostream &s, map<T1,T2> P)

{ for(auto it : P) { s << "<" << it.first << "->" << it.second << "> "; } return s << endl; }





int main() {

    long long N, Q;

    cin >> N >> Q;

    int R = N-1, C = N-1;

    long long res = (N - 2) * (N - 2);

    vector<long long> yoko(N, N-1), tate(N, N-1);

    for (int q = 0; q < Q; ++q) {

        int type, x;

        cin >> type >> x;

        --x;



        // (0, x) に置く

        if (type == 1) {

            if (x > C) res -= tate[x] - 1;

            else {

                res -= R - 1;

                tate[x] = 0;

                for (int c = C-1; c > x; --c) tate[c] = R;

                C = x;

            }

        }

        // (x, 0) に置く

        else {

            if (x > R) res -= yoko[x] - 1;

            else {

                res -= C - 1;

                yoko[x] = 0;

                for (int r = R-1; r > x; --r) yoko[r] = C;

                R = x;

            }

        }

    }

    cout << res << endl;

}
































// Fastest known solution for this problem: