#include <bits/stdc++.h>

using namespace std;
using llong = long long;
using ldbl = long double;
using lpair = pair<llong, llong>;

#define ALL(x) x.begin(), x.end()

constexpr llong mod = 1e9+7;
constexpr llong inf = mod * mod;

template <typename T>
struct RMQ {
    const T INF = numeric_limits<T>::max();
    int n;
    vector<T> dat, lazy;
    RMQ(int n_) : n(), dat(n_ * 4, INF), lazy(n_ * 4, INF) {
        int x = 1;
        while (n_ > x) x *= 2;
        n = x;
    }
    /* lazy eval */
    void eval(int k) {
        if (lazy[k] == INF) return;  // 更新するものが無ければ終了
        if (k < n - 1) {             // 葉でなければ子に伝搬
            lazy[k * 2 + 1] = lazy[k];
            lazy[k * 2 + 2] = lazy[k];
        }
        // 自身を更新
        dat[k] = lazy[k];
        lazy[k] = INF;
    }
    void update(int a, int b, T x, int k, int l, int r) {
        eval(k);
        if (a <= l && r <= b) {  // 完全に内側の時
            lazy[k] = x;
            eval(k);
        } else if (a < r && l < b) {                     // 一部区間が被る時
            update(a, b, x, k * 2 + 1, l, (l + r) / 2);  // 左の子
            update(a, b, x, k * 2 + 2, (l + r) / 2, r);  // 右の子
            dat[k] = min(dat[k * 2 + 1], dat[k * 2 + 2]);
        }
    }
    void update(int a, int b, T x) { update(a, b, x, 0, 0, n); }
    T query_sub(int a, int b, int k, int l, int r) {
        eval(k);
        if (r <= a || b <= l) {  // 完全に外側の時
            return INF;
        } else if (a <= l && r <= b) {  // 完全に内側の時
            return dat[k];
        } else {  // 一部区間が被る時
            T vl = query_sub(a, b, k * 2 + 1, l, (l + r) / 2);
            T vr = query_sub(a, b, k * 2 + 2, (l + r) / 2, r);
            return min(vl, vr);
        }
    }
    T query(int a, int b) { return query_sub(a, b, 0, 0, n); }
    /* debug */
    inline T operator[](int a) { return query(a, a + 1); }
    void print() {
        for (int i = 0; i < 2 * n - 1; ++i) {
            cout << (*this)[i];
            if (i != n) cout << ",";
        }
        cout << endl;
    }
};

int main() {
  llong N, Q;
  vector<lpair> query;

  cin >> N >> Q;
  query.resize(Q);
  for (auto &in: query) {
    cin >> in.first >> in.second;
  }

  RMQ<llong> col(N + 1), row(N + 1);
  col.update(0, N + 1, N);
  row.update(0, N + 1, N);
  col.update(N, N + 1, 0);
  row.update(N, N + 1, 0);

  llong ans = 0;
  for (auto q: query) {
    if (q.first == 1) {
      ans += max(0ll, col.query(q.second, q.second + 1) - 2);
      col.update(q.second, q.second + 1, 0);

      llong ok = 0, ng = N;
      while (abs(ok - ng) > 1) {
        llong mid = (ok + ng) >> 1;
        if (row.query(0, mid + 1) >= q.second) {
          ok = mid;
        }
        else {
          ng = mid;
        }
      }
      row.update(0, ok + 1, q.second);
    }
    else {
      ans += max(0ll, row.query(q.second, q.second + 1) - 2);

      row.update(q.second, q.second + 1, 0);
      llong ok = 0, ng = N;
      while (abs(ok - ng) > 1) {
        llong mid = (ok + ng) >> 1;
        if (col.query(0, mid + 1) >= q.second) {
          ok = mid;
        }
        else {
          ng = mid;
        }
      }
      col.update(0, ok + 1, q.second);
    }

    // for (int i = 1; i <= N; i++) {
    //   cerr << col.query(i, i + 1) << " ";
    // }
    // cerr << endl;
    // for (int i = 1; i <= N; i++) {
    //   cerr << row.query(i, i + 1) << " ";
    // }
    // cerr << endl << endl;
    
  }

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

  return 0;
}

/*

0
column
N N N N 0
row
N N N N 0
ans
2N - 2

1
column
N N 0 N 0
row
3 3 3 3 0
ans
2N - 2 + (N - 1) = 3N - 3

2
column
3 3 0 N 0
row
3 3 0 3 0
ans
3N - 3 + (3 - 1) = 3N - 1

3
column
3 3 0 0 0
row
3 3 0 3 0 → 4 未満
ans
3N - 3 + (3 - 1) = 3N - 1 + (N - 1) = 4N - 2

4
column
2 2 0 0 0
row
3 0 0 3 0
ans
3N - 3 + (3 - 1) = 3N - 1 + (N - 1) = 4N - 2 + (3 - 1) = 4N

5
column
2 0 0 0 0
row
2 0 0 3 0
ans
3N - 3 + (3 - 1) = 3N - 1 + (N - 1) = 4N - 2 + (3 - 1) = 4N + (2 - 1) = 4N + 1


*/

Measured memory_bytes: 31504