// Original C++ solution (slower):
#include <iostream>

#include <sstream>

#include <algorithm>

#include <string>

#include <vector>

#include <map>

#include <set>

#include <queue>

#include <deque>

#include <stack>

#include <memory>

#include <complex>

#include <numeric>

#include <cstdio>

#include <iomanip>

#include <random>



#define REP(i,m,n) for(int i=int(m);i<int(n);i++)

#define RREP(i,m,n) for(int i=int(n)-1;i>=int(m);--i)

#define EACH(i,c) for (auto &(i): c)

#define all(c) begin(c),end(c)

#define EXIST(s,e) ((s).find(e)!=(s).end())

#define SORT(c) sort(begin(c),end(c))

#define pb emplace_back

#define MP make_pair

#define SZ(a) int((a).size())

//#define int long long



#ifdef LOCAL

#define DEBUG(s) cout << (s) << endl

#define dump(x)  cerr << #x << " = " << (x) << endl

#define BR cout << endl;

#else

#define DEBUG(s) do{}while(0)

#define dump(x) do{}while(0)

#define BR 

#endif

using namespace std;



using UI = unsigned int;

using UL = unsigned long;

using LL = long long;

using ULL = unsigned long long;

using VI = vector<int>;

using VVI = vector<VI>;

using VLL = vector<LL>;

using VVLL = vector<VLL>;

using VS = vector<string>;

using PII = pair<int,int>;

using VP = vector<PII>;

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; }



// constexpr double EPS = 1e-10;

//constexpr double PI  = acos(-1.0);

//constexpr int INF = INT_MAX;

// constexpr int MOD = 1'000'000'007;

//inline void modAdd(LL &l, LL &r) {l = (l + r) % MOD;}





template<typename T = long long>

class SegmentTree {

    void update(int k) {

        while (k > 0) {

            k = (k - 1) / 2;

            ary[k] = ope(ary[2 * k + 1], ary[2 * k + 2]);

        }

    }

public:

    std::vector<T> ary;

    int n;

    const T default_value = std::numeric_limits<T>::max() / 4;

    SegmentTree(int n) {

        this->n = 1;

        while (this->n < n) this->n *= 2;

        ary.resize(this->n * 2 - 1, default_value); // sum -> 0, min -> INF, 0?

    }

    T ope(T l, T r) {

        return std::min(l, r);

    }

    void add(int k, T d) {

        k += n - 1;

        ary[k] += d;

        update(k);

    }

    void update(int k, T d) {

        k += n - 1;

        if (d >= ary[k]) return;

        ary[k] = d;

        update(k);

    }

    T query(int a, int b) {

        return query(a, b, 0, n, 0);

    }

    T query(int a, int b, int l, int r, int i) {

        if (a <= l && b >= r) return ary[i];

        //if (a >= r || b <= l) return 0; // sum

        if (a >= r || b <= l) return default_value; // min

        int m = (l + r) / 2;

        T vl = query(a, b, l, m, 2 * i + 1);

        T vr = query(a, b, m, r, 2 * i + 2);

        return ope(vl, vr);

    }

};



void solve() {

    int n,q;

    cin >> n >> q;

    int t,x;

    LL ans = 1LL * (n-2) * (n-2);



    SegmentTree<> l(n),r(n);

    REP(i,0,n) l.update(i,n);

    REP(i,0,n) r.update(i,n);

    REP(i,0,q) {

        cin >> t >> x;

        if (t == 1) {

            int v = l.query(x,n);

            // dump(v);

            ans -= v - 2;

            r.update(v-1,x);

        } else {

            int v = r.query(x,n);

            // dump(v);

            ans -= v - 2;

            l.update(v-1,x);

        }

    }

    cout << ans << endl;

}



signed main() {

    solve();

    

    return 0;

}

// Optimized solution to the same problem (faster):
#include <iostream>

#include <sstream>

#include <algorithm>

#include <string>

#include <vector>

#include <map>

#include <set>

#include <queue>

#include <deque>

#include <stack>

#include <memory>

#include <complex>

#include <numeric>

#include <cstdio>

#include <iomanip>

#include <random>



#define REP(i,m,n) for(int i=int(m);i<int(n);i++)

#define RREP(i,m,n) for(int i=int(n)-1;i>=int(m);--i)

#define EACH(i,c) for (auto &(i): c)

#define all(c) begin(c),end(c)

#define EXIST(s,e) ((s).find(e)!=(s).end())

#define SORT(c) sort(begin(c),end(c))

#define pb emplace_back

#define MP make_pair

#define SZ(a) int((a).size())

//#define int long long



#ifdef LOCAL

#define DEBUG(s) cout << (s) << endl

#define dump(x)  cerr << #x << " = " << (x) << endl

#define BR cout << endl;

#else

#define DEBUG(s) do{}while(0)

#define dump(x) do{}while(0)

#define BR 

#endif

using namespace std;



using UI = unsigned int;

using UL = unsigned long;

using LL = long long;

using ULL = unsigned long long;

using VI = vector<int>;

using VVI = vector<VI>;

using VLL = vector<LL>;

using VVLL = vector<VLL>;

using VS = vector<string>;

using PII = pair<int,int>;

using VP = vector<PII>;

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; }



void solve() {

    int n,q;

    cin >> n >> q;

    int t,x;

    LL ans = 1LL * (n-2) * (n-2);

    VI rs(n), cs(n);

    int r = n - 1, c = n - 1;

    REP(i,0,q) {

        cin >> t >> x;

        --x;

        if (t == 1) {

            if (x > r) ans -= rs[x] - 1;

            else {

                REP(j,x,r+1) {

                    rs[j] = c;

                }

                r = x;

                ans -= rs[x] - 1;

            }

        } else {

            if (x > c) ans -= cs[x] - 1;

            else {

                REP(j,x,c+1) {

                    cs[j] = r;

                }

                c = x;

                ans -= cs[x] - 1;

            }

        }

    }

    cout << ans << endl;

}



signed main() {

    solve();

    

    return 0;

}

// Fastest known solution for this problem: