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

#define mp make_pair
#define pb push_back

#define int int64_t
#define ld long double

const int MOD = 1e9+7;
const int N = 1e6+5;

typedef int dat;
int n;
 
struct SegmentTree
{
    int N;
    vector<dat> st;
    vector<int> lazy;
    vector<bool> isLazy;
    
    dat merge(dat a, dat b)
    {
    	return min(a,b);
    }
 
    void build(int node, int l, int r)
    {
        if(l == r)
        {
        	st[node]=n;
            return;
        }
        int m = (l+r)/2;
        build(2*node, l, m);
        build(2*node+1, m+1, r);
        st[node] = merge(st[2*node], st[2*node+1]);
    }
 
    dat query(int node, int l, int r, int i, int j)
    {
        propagate(node, l, r);
        if(l >= i && r <= j)
            return st[node];
        int m = (l+r)/2;
        if(j <= m)
            return query(2*node, l, m, i, j);
        else if(i >= m+1)
            return query(2*node+1, m+1, r, i, j);
        else
            return merge(query(2*node, l, m, i, j), query(2*node+1, m+1, r, i, j));
    }

    void propagate(int node, int l, int r) {
        if(isLazy[node]) {
            //update st[node]
        	st[node]=min(st[node], lazy[node]);
            if(l!=r) {
                isLazy[2*node]=1; lazy[2*node]=min(lazy[node],lazy[2*node]);
                isLazy[2*node+1]=1; lazy[2*node+1]=min(lazy[2*node+1],lazy[node]);
            }
            isLazy[node]=0;
            lazy[node]=MOD;
        }
    }
 
    //modify arguments and handle point update as per question
    void update(int node, int l, int r, int i, int j, int val)
    {
        propagate(node, l, r);
        if(l >= i && r<=j)
        {
            //Single element value
            lazy[node]=min(lazy[node],val);
            isLazy[node] = 1;
            propagate(node,l, r);
            return;
        }
        int m = (l+r)/2;
        if(j <= m) {
            update(2*node, l, m, i, j, val);
            propagate(2*node+1, m+1, r);
        }
        else if(i >= m+1) {
            propagate(2*node, l, m);
            update(2*node+1, m+1, r, i, j, val);
        }
        else {
            update(2*node, l, m, i, j, val);
            update(2*node+1, m+1, r, i, j, val);
        }
        st[node] = merge(st[2*node], st[2*node+1]);
    }
 
    SegmentTree(int tree_size)
    {
        N=tree_size;
        st.resize(4*N+5);
        lazy.assign(4*N+5, MOD);
        isLazy.resize(4*N+5);
        build();
    }
 
    void build()
    {
        build(1, 1, N);
    }
 
    dat query(int i, int j)
    {
        dat res = query(1, 1, N, i, j);
        return res;
    }
    
    void update(int l, int r, int val)
    {
    	if(l>r)
    		return;
        update(1, 1, N, l, r, val);
    }
};

int32_t main()
{
	ios_base::sync_with_stdio(false);
	cin.tie(NULL);

	int q;
	cin>>n>>q;
	int ans = (n-2)*(n-2);
	vector<bool> cdone(n+1, 0), rdone(n+1, 0);
	SegmentTree rowmin = SegmentTree(n+1);
	SegmentTree colmin = SegmentTree(n+1);
	for(int i=0;i<q;i++)  {
		int qt, x;
		cin>>qt>>x;
		if(qt==1) {
			if(cdone[x]) {
				continue;
			}
			int lb = rowmin.query(x, x);
			ans-=(lb-2);
			// cout<<qt<<" "<<x<<" "<<lb<<endl;
			colmin.update(1, lb, x);
			cdone[x]=1;
		}
		else {
			if(rdone[x]) {
				continue;
			}
			int rb = colmin.query(x,x);
			ans-=(rb-2);
			// cout<<qt<<" "<<x<<" "<<rb<<endl;
			rowmin.update(1, rb, x);
			rdone[x]=1;
		}
	}
	cout<<ans;

	return 0;
}

Measured memory_bytes: 28552