#include <bits/stdc++.h>

using namespace std;

#define REP(i, n) for (int i=0; i<(n); ++i)
#define FOR(i, a, n) for (int i=(a); i<(n); ++i)

#define SZ(x) ((int)(x).size())
#define ALL(x) (x).begin(),(x).end()

#define DUMP(x) cerr<<#x<<" = "<<(x)<<endl
#define DEBUG(x) cerr<<#x<<" = "<<(x)<<" (L"<<__LINE__<<")"<<endl;

template<class T>
ostream &operator<<(ostream &os, const vector <T> &v) {
  os << "[";
  REP(i, SZ(v)) {
    if (i) os << ", ";
    os << v[i];
  }
  return os << "]";
}

template<class T, class U>
ostream &operator<<(ostream &os, const pair <T, U> &p) {
  return os << "(" << p.first << " " << p.second << ")";
}

template<class T>
bool chmax(T &a, const T &b) {
  if (a < b) {
    a = b;
    return true;
  }
  return false;
}

template<class T>
bool chmin(T &a, const T &b) {
  if (b < a) {
    a = b;
    return true;
  }
  return false;
}

using ll = long long;
using ull = unsigned long long;
using ld = long double;
using P = pair<int, int>;
using vi = vector<int>;
using vll = vector<ll>;
using vvi = vector<vi>;
using vvll = vector<vll>;

const ll MOD = 1e9 + 7;
const int INF = INT_MAX / 2;
const ll LINF = LLONG_MAX / 2;
const ld eps = 1e-9;

struct LazySegmentTree {
private:
  int n;
  vector<int> node, lazy;
  vector<bool> lazyFlag;

public:
  LazySegmentTree(vector<int> v) {
    int sz = (int)v.size();
    n = 1; while(n < sz) n *= 2;
    node.resize(2*n-1);
    lazy.resize(2*n-1, INF);
    lazyFlag.resize(2*n-1, false);

    for(int i=0; i<sz; i++) node[i+n-1] = v[i];
    for(int i=n-2; i>=0; i--) node[i] = min(node[i*2+1], node[i*2+2]);
  }

  void lazyEvaluate(int k, int l, int r) {
    if(lazyFlag[k]) {
      node[k] = lazy[k];
      if(r - l > 1) {
        lazy[k*2+1] = lazy[k*2+2] = lazy[k];
        lazyFlag[k*2+1] = lazyFlag[k*2+2] = true;
      }
      lazyFlag[k] = false;
    }
  }

  void update(int a, int b, int x, int k=0, int l=0, int r=-1) {
    if(r < 0) r = n;
    lazyEvaluate(k, l, r);
    if(b <= l || r <= a) return;
    if(a <= l && r <= b) {
      lazy[k] = x;
      lazyFlag[k] = true;
      lazyEvaluate(k, l, r);
    }
    else {
      update(a, b, x, 2*k+1, l, (l+r)/2);
      update(a, b, x, 2*k+2, (l+r)/2, r);
      node[k] = min(node[2*k+1], node[2*k+2]);
    }
  }

  int find(int a, int b, int k=0, int l=0, int r=-1) {
    if(r < 0) r = n;
    lazyEvaluate(k, l, r);
    if(b <= l || r <= a) return INF;
    if(a <= l && r <= b) return node[k];
    int vl = find(a, b, 2*k+1, l, (l+r)/2);
    int vr = find(a, b, 2*k+2, (l+r)/2, r);
    return min(vl, vr);
  }
};

int main() {
  cin.tie(0);
  ios::sync_with_stdio(false);
  cout << fixed << setprecision(10);

  ll n, q; cin >> n >> q;

  vi init(n-1, n-2);
  LazySegmentTree st1(init), st2(init);

  ll a = n-1, b = n-1;

  vector<bool> va(n-1), vb(n-1);

  ll ans = (n-2) * (n-2);
  REP(i, q) {
    int t, x; cin >> t >> x;
    x--;
    if(t == 1) {
      if(va[x]) {
        continue;
      }

      if(a < x) {
        ans -= st1.find(x, x+1);
        va[x] = true;
      } else {
        int res = st1.find(x, x+1);
        ans -= res;
        st2.update(1, res+1, x-1);
        va[x] = true;
        a = x-1;
      }
    } else {
      if(vb[x]) continue;

      if(b < x) {
        ans -= st2.find(x, x+1);
        vb[x] = true;
      } else {
        int res = st2.find(x, x+1);

        ans -= res;
        st1.update(1, res+1, x-1);
        vb[x] = true;
        b = x - 1;
      }
    }

    /*
    REP(j, n-1) {
      cout << st1.find(j, j+1) << " ";
    }
    cout << endl;
    REP(j, n-1) {
      cout << st2.find(j, j+1) << " ";
    }
    cout << endl;
    cout << va << endl;
    cout << vb << endl;
    cout << a << " " << b << endl;
    cout << endl;
     */
  }

  cout << ans << endl;


  return 0;
}

Measured memory_bytes: 13064