#pragma GCC optimize("O3") //コンパイラ最適化用

// #define _GLIBCXX_DEBUG //配列に[]でアクセス時のエラー表示
#include <algorithm> //sort,二分探索,など
#include <bitset>    //固定長bit集合
#include <cassert>   //assert(p)で，not pのときにエラー
#include <cctype>
#include <chrono> //実行時間計測
#include <climits>
#include <cmath>   //pow,logなど
#include <complex> //複素数
#include <cstdio>
#include <cstring>
#include <deque>
#include <functional> //sortのgreater
#include <iomanip>    //setprecision(浮動小数点の出力の誤差)
#include <ios>        // std::left, std::right
#include <iostream>   //入出力
#include <iterator>   //集合演算(積集合,和集合,差集合など)
#include <map>
#include <numeric> //iota(整数列の生成),gcdとlcm,accumulate
#include <queue>
#include <random>
#include <set>
#include <stack>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility> //pair
#include <vector>
using namespace std;
typedef long long LL;
typedef long double LD;

#define ALL(x) x.begin(), x.end()
const long long INF = 1e12;
const int MOD = 1e9 + 7;
// const int MOD=998244353;
//略記
#define UMAP unordered_map
#define USET unordered_set
#define FF first
#define SS second
#define int long long
#define LD long double
#define PII pair<int, int>
#define PB push_back
#define MP make_pair
#define SZ(x) (int)((x).size())
#define VI vector<int>
#define VVI vector<vector<int>>
#define VLL vector<LL>
#define VVLL vector<vector<LL>>

#define REP(i, n) for (int i = 0; i < (int)(n); i++)
#define REPD(i, n) for (int i = (int)(n)-1; i >= 0; i--)
#define FOR(i, a, b) for (int i = a; i < (int)(b); i++)
#define FORD(i, a, b) for (int i = (int)(b)-1; i >= (int)a; i--)

const unsigned int BIT_FLAG_0 = (1 << 0); // 0000 0000 0000 0001
const unsigned int BIT_FLAG_1 = (1 << 1); // 0000 0000 0000 0010
const unsigned int BIT_FLAG_2 = (1 << 2); // 0000 0000 0000 0100
const unsigned int BIT_FLAG_3 = (1 << 3); // 0000 0000 0000 1000
const unsigned int BIT_FLAG_4 = (1 << 4); // 0000 0000 0001 0000
const unsigned int BIT_FLAG_5 = (1 << 5); // 0000 0000 0010 0000
const unsigned int BIT_FLAG_6 = (1 << 6); // 0000 0000 0100 0000
const unsigned int BIT_FLAG_7 = (1 << 7); // 0000 0000 1000 0000
const int dx[4] = {0, 1, 0, -1}, dy[4] = {-1, 0, 1, 0};
const int Dx[8] = {0, 1, 1, 1, 0, -1, -1, -1},
          Dy[8] = {-1, -1, 0, 1, 1, 1, 0, -1};

// https://qiita.com/Lily0727K/items/06cb1d6da8a436369eed#c%E3%81%A7%E3%81%AE%E5%AE%9F%E8%A3%85
void print() { cout << "\n"; }

template <class Head, class... Tail> void print(Head &&head, Tail &&... tail) {
    cout << head;
    if (sizeof...(tail) != 0)
        cout << " ";
    print(forward<Tail>(tail)...);
}

template <class T> void print(vector<T> &vec) {
    for (auto &a : vec) {
        cout << a;
        if (&a != &vec.back())
            cout << " ";
    }
    cout << "\n";
}

template <class T> void print(set<T> &set) {
    for (auto &a : set) {
        cout << a << " ";
    }
    cout << "\n";
}

template <class T> void print(vector<vector<T>> &df) {
    for (auto &vec : df) {
        print(vec);
    }
}
long long power(long long x, long long n) {
    // O(logn)
    // https://algo-logic.info/calc-pow/#toc_id_1_2
    long long ret = 1;
    while (n > 0) {
        if (n & 1)
            ret *= x; // n の最下位bitが 1 ならば x^(2^i) をかける
        x *= x;
        n >>= 1; // n を1bit 左にずらす
    }
    return ret;
}
long long comb(int n, int k) {
    vector<vector<long long>> v(n + 1, vector<long long>(n + 1, 0));

    for (int i = 0; i < SZ(v); i++) {
        v[i][0] = 1;
        v[i][i] = 1;
    }
    for (int k = 1; k < SZ(v); k++) {
        for (int j = 1; j < k; j++) {
            v[k][j] = (v[k - 1][j - 1] + v[k - 1][j]);
        }
    }
    return v[n][k];
}
void add(long long &a, long long b) {
    a += b;
    if (a >= MOD)
        a -= MOD;
}
template <class T> inline bool chmin(T &a, T b) {
    if (a > b) {
        a = b;
        return true;
    }
    return false;
}
template <class T> inline bool chmax(T &a, T b) {
    if (a < b) {
        a = b;
        return true;
    }
    return false;
}

__attribute__((constructor)) void faster_io() {
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
}
/**
 * @brief Dual-Segment-Tree(双対セグメント木)
 * @docs docs/dual-segment-tree.md
 */
template <typename OperatorMonoid, typename H> struct DualSegmentTree {
    int sz, height;
    vector<OperatorMonoid> lazy;
    const H h;
    const OperatorMonoid OM0;

    DualSegmentTree(int n, const H h, const OperatorMonoid &OM0)
        : h(h), OM0(OM0) {
        sz = 1;
        height = 0;
        while (sz < n)
            sz <<= 1, height++;
        lazy.assign(2 * sz, OM0);
    }

    inline void propagate(int k) {
        if (lazy[k] != OM0) {
            lazy[2 * k + 0] = h(lazy[2 * k + 0], lazy[k]);
            lazy[2 * k + 1] = h(lazy[2 * k + 1], lazy[k]);
            lazy[k] = OM0;
        }
    }

    inline void thrust(int k) {
        for (int i = height; i > 0; i--)
            propagate(k >> i);
    }

    void update(int a, int b, const OperatorMonoid &x) {
        thrust(a += sz);
        thrust(b += sz - 1);
        for (int l = a, r = b + 1; l < r; l >>= 1, r >>= 1) {
            if (l & 1)
                lazy[l] = h(lazy[l], x), ++l;
            if (r & 1)
                --r, lazy[r] = h(lazy[r], x);
        }
    }

    OperatorMonoid operator[](int k) {
        thrust(k += sz);
        return lazy[k];
    }
};

template <typename OperatorMonoid, typename H>
DualSegmentTree<OperatorMonoid, H>
get_dual_segment_tree(int N, const H &h, const OperatorMonoid &OM0) {
    return {N, h, OM0};
}

signed main() {
    int n, q; //要素数、クエリ数
    cin >> n >> q;
    // https://ei1333.github.io/library/library/structure/segment-tree/dual-segment-tree.cpp.html
    // http://judge.u-aizu.ac.jp/onlinejudge/description.jsp?id=DSL_2_D&lang=ja

    // 作用を定義
    auto h = [](int a, int b) { return min(a, b); }; // 区間をbに更新
    // auto h = [](int a, int b) { return a+b; }; // 区間にbを加算
    // auto h = [](mint a, mint b) { return mint(a+b); }; //区間にbを加算してmod

    // 第3引数は初期値。全部0なら0に。
    auto seg1 = get_dual_segment_tree(n, h, n - 1);
    auto seg2 = get_dual_segment_tree(n, h, n - 1);

    // dpとか、予め初期値とは異なる要素があればupdateしておく
    // seg.update(0,1,1); // seg[0]=1とする

    int ans = (n - 2) * (n - 2);
    while (q--) {
        int type, idx;
        cin >> type >> idx;
        idx--;
        if (type == 1) {
            ans -= seg1[idx] - 1;
            seg2.update(0, seg1[idx], idx);
            seg1.update(idx, idx + 1, 0);
        } else {
            ans -= seg2[idx] - 1;
            seg1.update(0, seg2[idx], idx);
            seg2.update(idx, idx + 1, 0);
        }
        /* REP(ni, n - 1) { cout << seg1[ni] << " "; }
        cout << "\n";
        REP(ni, n - 1) { cout << seg2[ni] << " "; }
        cout << "\n"; */
    }
    print(ans);
}

Measured memory_bytes: 11444