#include<bits/stdc++.h>
#define ll long long
#define ull unsigned long long
#define pii pair<int,int>
#define pp pair<pair<ll, ll>,pair<ll, ll>>
#define pll pair<ll,ll>
#define ppll pair<ll,pll>
#define pdd pair<double,double>
#define vii vector<int>
#define vll vector<ll>
#define mat vector<vector<ll>>
#define lb lower_bound
#define ub upper_bound
#define pb push_back
#define eb emplace_back
#define fi first
#define sc second
#define rep(i,n) for(ll i=0;i<n;i++)
#define rep2(i,a,b) for(ll i=a;i<b;i++)
#define repr(i,n) for(ll i=n-1;i>=0;i--)
#define all(x) x.begin(),x.end()
#define sz(x) (ll) (x).size()
#define pq priority_queue<ll>
#define pqg priority_queue<ll,vector<ll>,greater<ll>>
#define LB(v,x) (lower_bound(v.begin(),v.end(),x)-v.begin())
#define UB(v,x) (upper_bound(v.begin(),v.end(),x)-v.begin())
#define ERASE(v) sort(v.begin(),v.end());v.erase(unique(v.begin(),v.end()),v.end())
#define int ll
// #define ll int
using namespace std;
const ll INF = 1 << 29;
const ll LLINF = (1LL << 60LL);
const ll MOD = 1000000007;
const int MAX_V = 500;
const ll mod = 998244353;
const ll MAX = 2100000;
const double pi = acos(-1);
const double eps = 1e-10;
ll dx[8] ={1,0,-1,0,1,-1,1,-1};
ll dy[8] ={0,1,0,-1,1,-1,-1,1};
template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; }
template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; }




template<class Monoid, class Action>
struct LazySegmentTree {
    using FuncMonoid = function< Monoid(Monoid, Monoid) >;
    using FuncAction = function< void(Monoid&, Action) >;
    using FuncLazy = function< void(Action&, Action) >;
    using FuncPropotional = function< Action(Action, int)>;
    FuncMonoid FM;
    FuncAction FA;
    FuncLazy FL;
    FuncPropotional FP;
    Monoid UNITY_MONOID;
    Action UNITY_LAZY;
    int size, height;
    vector<Monoid> dat;
    vector<Action> lazy;

    LazySegmentTree() { }
    LazySegmentTree(int n, const FuncMonoid fm, const FuncAction fa, const FuncLazy fl,
            const Monoid &unity_monoid, const Action &unity_lazy,
            const FuncPropotional fp = [](Action a, int b){return a;})
    : FM(fm), FA(fa), FL(fl),FP(fp), UNITY_MONOID(unity_monoid), UNITY_LAZY(unity_lazy) {
        size = 1; height = 0;
        while(size < n){ size <<= 1; height++; }
        dat.assign(size * 2, UNITY_MONOID);
        lazy.assign(size * 2, UNITY_LAZY);
    }

    void init(int n, const FuncMonoid fm, const FuncAction fa, const FuncLazy fl,
            const Monoid &unity_monoid, const Action &unity_lazy,
            const FuncPropotional fp = [](Action a, int b){return a;}) {
        FM = fm; FA = fa; FL = fl; FP = fp;
        UNITY_MONOID = unity_monoid;
        UNITY_LAZY = unity_lazy;
        size = 1; height = 0;
        while(size < n){ size <<= 1; height++; }
        dat.assign(size * 2, UNITY_MONOID);
        lazy.assign(size * 2, UNITY_LAZY);
    }

    void set(int a, const Monoid &v) { dat[a + size] = v; }
    void build() {
        for (int k = size - 1; k > 0; --k){
            dat[k] = FM(dat[k * 2], dat[k * 2 + 1]);
        }
    }

    // [a,b)
    inline void evaluate(int k, int len) {
        if(lazy[k] == UNITY_LAZY) return;
        if(k < size) FL(lazy[k * 2], lazy[k]), FL(lazy[k * 2 + 1], lazy[k]);
        FA(dat[k], FP(lazy[k], len));
        lazy[k] = UNITY_LAZY;
    }
    inline void update(int a, int b, const Action &v, int k, int l, int r){
        evaluate(k, r - l);
        if(a <= l && r <= b) FL(lazy[k], v), evaluate(k, r - l);
        else if(a < r && l < b) {
            update(a, b, v, k * 2, l, (l+r)>>1), update(a, b, v, k * 2 + 1, (l+r)>>1, r);
            dat[k] = FM(dat[k * 2], dat[k * 2 + 1]);
        }
    }
    inline void update(int a, int b, const Action &v) { update(a, b, v, 1, 0, size);}


    inline Monoid get(int a, int b, int k, int l, int r) {
        evaluate(k, r - l);
        if (a <= l && r <= b) 
            return dat[k];
        else if (a < r && l < b) 
            return FM(get(a, b, k*2, l, (l+r)>>1), get(a, b, k*2+1, (l+r)>>1, r));
        else
            return UNITY_MONOID;
    }
    inline Monoid get(int a, int b) { return get(a, b, 1, 0, size); }
    inline Monoid operator[] (int a) { return get(a, a+1); }
    
    void print() {
        for (int i = 0; i < size; i++) {
            cout << (*this)[i];
            if (i != size) cout << ", ";
        }
        cout<<endl;
    }

};



void solve() {
    ll n,q;
    cin>>n>>q;
    auto fm = [](ll a, ll b){return a+b;};
    auto fa = [](ll &a, ll b){ chmin(a,b); };
    auto fl = [](ll &a, ll b){ chmin(a, b); };
    ll ex = 0;
    ll em = LLINF;
    LazySegmentTree<ll,ll> sg1(n,fm,fa,fl,ex,em);
    LazySegmentTree<ll,ll> sg2(n,fm,fa,fl,ex,em);
    ll ans = 0;


    rep(i,n) sg1.set(i,n-1);
    sg1.build();
    rep(i,n) sg2.set(i,n-1);
    sg2.build();


    rep(query,q){
        ll c,x;
        cin>>c>>x;
        x--;
        if(c==1){
            ll now = sg1[x];
            sg1.update(x,x+1,0);
            sg2.update(0,now,x);
        }
        else{
            ll now = sg2[x];
            sg2.update(x,x+1,0);
            sg1.update(0,now,x);
        }
    }

    // sg1.print();
    // sg2.print();


    rep2(i,1,n-1){
        ans += max(0ll,sg1[i]-1);
        // cout<<sg1[i]<<endl;
        sg2.update(0,sg1[i],i);
    }
    rep2(i,1,n-1){
        ans += max(0ll,sg2[i]-1);
    }
    // sg1.print();
    // sg2.print();
    cout<<ans<<endl;



}




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


    ll t=1;
    
    // cin>>t;

    rep(i,t){
        solve(); 
    }

    return 0;
}


Measured memory_bytes: 19544