#include <bits/stdc++.h>
using namespace std;

// #include <ext/pb_ds/assoc_container.hpp> 
// #include <ext/pb_ds/tree_policy.hpp> 
// using namespace __gnu_pbds; 

#define int long long
#define mod 1000000007
#define pb push_back
#define S second
#define F first
#define INF 1e18
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 

#define deb(x) cerr << "\n" \
                    << #x << "=" << x << "\n";
#define deb2(x, y) cerr << "\n" \
                        << #x << "=" << x << "\n" \
                        << #y << "=" << y << "\n";
#define w(x) \
  int x;     \
  cin >> x;  \
  while (x--)


class LazySegmentTree
{
public:
    vector<int> tree;
    vector<int> delta;

    LazySegmentTree(int n, int val)
    {
        tree.resize(4 * n + 2, val);
        delta.resize(4 * n + 2, INF);
    }

    void build(int node, int start, int end)
    {
        if (start == end)
        {
           // tree[node] = v[start];
            return;
        }
        int mid = (start + end) / 2;
        build(2 * node + 1, start, mid);
        build(2 * node + 2, mid + 1, end);

        tree[node] = operation(tree[2 * node + 1], tree[2 * node + 2]);
    }

    void updateRange(int node, int start, int end, int l, int r, int diff)
    {
        if (delta[node] != INF)
        {
            updateDelta(node, delta[node], start, end);
            delta[node] = INF;
        }
        if (start > end || start > r || end < l)
            return;

        if (start >= l && end <= r)
        {
            updateDelta(node, diff, start, end);
            return;
        }

        int mid = (start + end) / 2;
        updateRange(node * 2 + 1, start, mid, l, r, diff);
        updateRange(node * 2 + 2, mid + 1, end, l, r, diff);

        tree[node] = operation(tree[node * 2 + 1], tree[node * 2 + 2]);
    }

    int query(int node, int start, int end, int l, int r)
    {
        if (delta[node] != INF)
        {
            updateDelta(node, delta[node], start, end);
            delta[node] = INF;
        }
        if (r < start || l > end)
        {
            return INF;
        }

        if (l <= start && r >= end)
        {
            return tree[node];
        }
        int mid = (start + end) / 2;
        int a = query(2 * node + 1, start, mid, l, r);
        int b = query(2 * node + 2, mid + 1, end, l, r);

        return operation(a, b);
    }

    void updateDelta(int node, int val, int start, int end)
    {
        tree[node] = min(tree[node], val);

        if (start != end)
        {
            delta[node * 2 + 1] = min(delta[node * 2 + 1], val);
            delta[node * 2 + 2] = min(delta[node * 2 + 2], val);
        }
    }
    int operation(int a, int b)
    {
        return min(a, b);
    }
};
int32_t main() {

  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  int n;
  cin >> n;
  LazySegmentTree row(n,n-2),col(n,n-2);

  int ans = (n - 2) * (n - 2);
  w(tt) {
 
 //   for(int i = 0; i <= n - 3; i++)
 //     cout << row.query(0,0,n-3,i,i) << " ";

 //   cout << "\n";

 //   for(int i = 0; i <= n - 3; i++)
 //     cout << col.query(0,0,n-3,i,i) << " ";
 //   cout << "\n";   
    int type,pos;
    cin >> type >> pos;
    pos -= 2;
    if(type == 1) {
      // place at (1,pos)
      int elm = col.query(0,0,n-3,pos,pos);
      ans -= elm;
      row.updateRange(0,0,n-3,0,elm,pos);
      col.updateRange(0,0,n-3,pos,pos,0);
    }else {
     
      //place at (pos,1)
      int elm = row.query(0,0,n-3,pos,pos);
      ans -= elm;
      col.updateRange(0,0,n-3,0,elm,pos);
      row.updateRange(0,0,n-3,pos,pos,0);
    }
  }
  cout << ans;
  return 0;
}


Measured memory_bytes: 28256