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

#define FAST ios_base::sync_with_stdio(false), cin.tie(0), cout.tie(0);
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
using namespace __gnu_pbds;
#define ordered_set tree<int, null_type,lessl<int>, rb_tree_tag,tree_order_statistics_node_update>
#define ll long long
#define int long long
#define double long double

#define all(a)      (a).begin(),(a).end()
#define sz(x)       (int)x.size()

#define ff first
#define ss second
#define mp make_pair

#define pb push_back
#define endl "\n"
#define E endl

#define f(i,l,r) for(int i=l;i<=r;i++)
#define rf(i,r,l) for(int i=r;i>=l;i--)

#define bp __builtin_popcountll
#define inf 1e18
 



int n,q;
vector<int> a;

struct data1
{
    //Use required attributes
    int mn,cnt;

    //Default Values
    data1() : mn(1e10) {};
};

struct SegTree
{
    int N;
    vector<data1> st;
    vector<bool> cLazy;
    vector<int> lazy;

    void init(int n)
    {
        N = n;
        st.resize(4 * N + 5);
        cLazy.assign(4 * N + 5, false);
        lazy.assign(4 * N + 5, 0);
    }

    //Write reqd merge functions
    void merge(data1 &cur, data1 &l, data1 &r) 
    {
        cur.mn = min(l.mn, r.mn);
    }
    
    //Handle lazy propagation appriopriately
    void propagate(int node, int L, int R)
    {
        if(L != R)
        {
            cLazy[node*2] = 1;
            cLazy[node*2 + 1] = 1;
            if(lazy[node*2]==0) lazy[2*node]=lazy[node];
            else  lazy[node*2] = min(lazy[2*node],lazy[node]);

            if(lazy[node*2+1]==0) lazy[2*node+1]=lazy[node];
            else  lazy[node*2+1] = min(lazy[2*node+1],lazy[node]);

        }
        if(st[node].mn>lazy[node]) st[node].mn=lazy[node]; 
        cLazy[node] = 0;
        lazy[node]=0;
    }

    void build(int node, int L, int R)
    {
        if(L==R)
        {
            st[node].mn = n;
            return;
        }
        int M=(L + R)/2;
        build(node*2, L, M);
        build(node*2 + 1, M + 1, R);
        merge(st[node], st[node*2], st[node*2+1]);
    }

    data1 Query(int node, int L, int R, int i, int j)
    {
        if(cLazy[node])
            propagate(node, L, R);
        if(j<L || i>R)
            return data1();
        if(i<=L && R<=j)
            return st[node];
        int M = (L + R)/2;
        data1 left=Query(node*2, L, M, i, j);
        data1 right=Query(node*2 + 1, M + 1, R, i, j);
        data1 cur;
        merge(cur, left, right);
        return cur;
    }

    data1 pQuery(int node, int L, int R, int pos)
    {
        if(cLazy[node])
            propagate(node, L, R);
        if(L == R)
            return st[node];
        int M = (L + R)/2;
        if(pos <= M)
            return pQuery(node*2, L, M, pos);
        else
            return pQuery(node*2 + 1, M + 1, R, pos);
    }    

    void Update(int node, int L, int R, int i, int j, int val)
    {
        if(cLazy[node])
            propagate(node, L, R);
        if(j<L || i>R)
            return;
        if(i<=L && R<=j)
        {
            cLazy[node] = 1;
            lazy[node] = val;
            propagate(node, L, R);
            return;
        }
        int M = (L + R)/2;
        Update(node*2, L, M, i, j, val);
        Update(node*2 + 1, M + 1, R, i, j, val);
        merge(st[node], st[node*2], st[node*2 + 1]);
    }

    void pUpdate(int node, int L, int R, int pos, int val)
    {
        if(cLazy[node])
            propagate(node, L, R);
        if(L == R)
        {
            cLazy[node] = 1;
            if(lazy[node]==0) lazy[node]=val;
            else lazy[node] = min(val,lazy[node]);
            propagate(node, L, R);
            return;
        }
        int M = (L + R)/2;
        if(pos <= M)
            pUpdate(node*2, L, M, pos, val);
        else
            pUpdate(node*2 + 1, M + 1, R, pos, val);
        merge(st[node], st[node*2], st[node*2 + 1]);
    }

    data1 query(int pos)
    {
        return pQuery(1, 1, N, pos);
    }

    void query(int l, int r)
    {
        data1 c=Query(1, 1, N, l, r);
        cout<<c.mn<<" "<<c.cnt<<E;

    }

    void update(int pos, int val)
    {
        pUpdate(1, 1, N, pos, val);
    }

    void update(int l, int r, int val)
    {
        Update(1, 1, N, l, r, val);
    }
};

 
  
    





        




int32_t main()
{


    SegTree row,col;
    cin >> n >> q;
    row.init(n);
    col.init(n);
    row.build(1,1,n);   
    col.build(1,1,n);   
       

    int black=(n-2)*(n-2);

        while(q--)
        {
            int a,b;
            cin >> a >> b;
            if(a==1)
            {
               int mx=col.query(b).mn;
               row.update(1,mx,b);
               black-=max(mx-2,0LL);
            }
            else
            {   
                int mx=row.query(b).mn;
                col.update(1,mx,b);
                black-=max(mx-2,0LL);
            }   
        }  

        cout<<black<<endl;
     return 0;
}


Measured memory_bytes: 41000