#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
typedef pair<int, int> pii;
typedef pair<ll, ll> pll;
typedef vector<int> vi;
typedef vector<vector<int>> vvi;
typedef vector<ll> vll;
typedef vector<vector<ll>> vvll;

#define REP(k, n) for (ll k = 0; k < (ll)(n); ++k)
#define REPREV(k, n) for (ll k = (ll)(n)-1; k >= 0; --k)
#define FOR(k, a, b) for (ll k = (ll)(a); k < (ll)(b); ++k)
#define FORREV(k, a, b) for (ll k = (ll)(b)-1; k >= (ll)(a); --k)
#define FOREACH(e, v) for (auto& e : v)

#define TGET(t, i) get<i>(t)
#define TSET(t, i, a) get<i>(t) = a
// MinHeap - priority_queue<ll, vll, greater<ll>> pq;

#define EVEN(n) ((n)&1) == 0
#define ODD(n) ((n)&1) == 1

#define SORT(v) sort(v.begin(), v.end())
#define SORTREV(v) sort(v.rbegin(), v.rend())
#define SHUFFLE(v) random_shuffle(v.begin(), v.end())
//srand(unsigned(time(0)));

#define REMOVEAT(v, i) v.erase(v.begin() + i)
#define REVERSE(v) reverse(v.begin(), v.end())
#define UNIQUE(v) \
    SORT(v);      \
    v.resize(distance(v.begin(), unique(v.begin(), v.end())))

ostream& operator<<(ostream& str, const pll& p) {
    str << p.first << " " << p.second;
    return str;
}

template <typename T>
void join(T& arr, string sep) {
    bool first = true;
    for (auto t : arr) {
        if (first) {
            first = false;
            cout << t;
        } else {
            cout << sep << t;
        }
    }
    cout << "\n";
}

const ll md = 1e9 + 7;
ll MOD(ll x) {
    ll r = x % md;
    if (r < 0) {
        r += md;
    }
    return r;
}

#define POS "POSSIBLE"
#define IMPOS "IMPOSSIBLE"

// #define INF DBL_MAX
// #define INF LLONG_MAX
// #define MINF LLONG_MIN
#define INF 1e18
#define MINF -INF

struct SegmentTree {

    struct TreeNode {
        ll __prefix = 0;
        ll __suffix = 0;
        ll __maxSum = 0;
        ll __max = 0;
        ll __min = 0;
        ll __sum = 0;
        ll __maxi = -1;
        ll __mini = -1;

        ll __size = 0;
        ll __prefixSize = 0;
        ll __suffixSize = 0;
        ll __maxSumSize = 0;
        
        ll __pendingDelta = 0;
        pll __pendingOverwrite = {0, 0};

        TreeNode() {

        }

        TreeNode(ll x, ll i) {
            init(x, i);
        }

        void init(ll x, ll i) {
            __prefix = x;
            __suffix = x;
            __maxSum = x;
            __max = x;
            __min = x;
            __sum = x;
            __maxi = i;
            __mini = i;
            
            __size = 1;
            __prefixSize = 1;
            __suffixSize = 1;
            __maxSumSize = 1;
        }

        ll result() {
            return __sum;
            // return __maxi;
        }

        static TreeNode join(TreeNode& n1, TreeNode& n2) {
            assert(!n1.__pendingDelta && !n1.__pendingOverwrite.first);
            assert(!n2.__pendingDelta && !n2.__pendingOverwrite.first);
            TreeNode res;
            if (n1.__prefix >= n1.__sum + n2.__prefix) {
                res.__prefix = n1.__prefix;
                res.__prefixSize = n1.__prefixSize;
            } else {
                res.__prefix = n1.__sum + n2.__prefix;
                res.__prefixSize = n1.__size + n2.__prefixSize;
            }
            if (n2.__suffix >= n2.__sum + n1.__suffix) {
                res.__suffix = n2.__suffix;
                res.__suffixSize = n2.__suffixSize;
            } else {
                res.__suffix = n2.__sum + n1.__suffix;
                res.__suffixSize = n2.__size + n1.__suffixSize;
            }
            if (n1.__maxSum >= n2.__maxSum) {
                if (n1.__maxSum >= n1.__suffix + n2.__prefix) {
                    res.__maxSum = n1.__maxSum;
                    res.__maxSumSize = n1.__maxSumSize;
                } else {
                    res.__maxSum = n1.__suffix + n2.__prefix;
                    res.__maxSumSize = n1.__suffixSize + n2.__prefixSize;
                }
            } else {
                if (n2.__maxSum >= n1.__suffix + n2.__prefix) {
                    res.__maxSum = n2.__maxSum;
                    res.__maxSumSize = n2.__maxSumSize;
                } else {
                    res.__maxSum = n1.__suffix + n2.__prefix;
                    res.__maxSumSize = n1.__suffixSize + n2.__prefixSize;
                }
            }
            res.__max = max(n1.__max, n2.__max);
            res.__maxi = n1.__max >= n2.__max ? n1.__maxi : n2.__maxi;
            res.__min = min(n1.__min, n2.__min);
            res.__mini = n1.__min <= n2.__min ? n1.__mini : n2.__mini;
            res.__sum = n1.__sum + n2.__sum;
            res.__size = n1.__size + n2.__size;
            return res;
        }
    };

    vector<TreeNode> __tree;
    ll __n;

    SegmentTree(ll n) : __n(n) {
        vll arr(n);
        __tree = vector<TreeNode>(arr.size()*4);
        init(0, arr.size()-1, 0, arr);
    }

    SegmentTree(vector<ll> arr) {
        __tree = vector<TreeNode>(arr.size()*4);
        __n = arr.size();
        init(0, arr.size()-1, 0, arr);
    }

    ll query(ll l, ll r) {
        assert(l <= r && l >= 0 && r < __n);
        return queryHelper(0, __n-1, 0, l, r).result();
    }

    TreeNode queryHelper(ll s, ll e, ll i, ll l, ll r) {
        applyPendingChanges(s, e, i);
        if (l == s && r == e) {
            return __tree[i];
        }

        ll m = SegmentTree::middleIdx(s, e);
        if (r <= m) {
            return queryHelper(s, m, SegmentTree::leftIdx(i), l, r);
        }
        if (l > m) {
            return queryHelper(m+1, e, SegmentTree::rightIdx(i), l, r);
        }

        TreeNode left = queryHelper(s, m, SegmentTree::leftIdx(i), l, m);
        TreeNode right = queryHelper(m+1, e, SegmentTree::rightIdx(i), m+1, r);
        return TreeNode::join(left, right);
    }

    void updataRangeHelper(ll s, ll e, ll i, ll l, ll r, ll v, bool isDelta) {
        applyPendingChanges(s, e, i);
        if (l == s && r == e) {
            if (isDelta) {
                __tree[i].__pendingDelta = v;
            } else {
                __tree[i].__pendingOverwrite = {1, v};
            }
            applyPendingChanges(s, e, i);
            return;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll lidx = SegmentTree::leftIdx(i);
        ll ridx = SegmentTree::rightIdx(i);

        if (r <= m) {
            updataRangeHelper(s, m, lidx, l, r, v, isDelta);
            applyPendingChanges(m+1, e, ridx);
        }
        else if (l > m) {
            updataRangeHelper(m+1, e, ridx, l, r, v, isDelta);
            applyPendingChanges(s, m, lidx);
        } else {
            updataRangeHelper(s, m, lidx, l, m, v, isDelta);
            updataRangeHelper(m+1, e, ridx, m+1, r, v, isDelta);
        }

        __tree[i] = TreeNode::join(__tree[lidx], __tree[ridx]);
    }

    void updateRange(ll l, ll r, ll v) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n-1, 0, l, r, v, false);
    }

    void addToRange(ll l, ll r, ll d) {
        assert(l >= 0 && r < __n && l <= r);
        updataRangeHelper(0, __n-1, 0, l, r, d, true);
    }

    void add(ll i, ll d) {
        addToRange(i, i, d);
    }

    void update(ll i, ll v) {
        updateRange(i, i, v);
    }

    void init(ll s, ll e, ll i, vector<ll>& arr) {
        assert(s <= e && i < __tree.size());
        if (s == e) {
            __tree[i].init(arr[s], s);
            return;
        }

        ll m = SegmentTree::middleIdx(s, e);
        ll l = SegmentTree::leftIdx(i);
        ll r = SegmentTree::rightIdx(i);

        init(s, m, l, arr);
        init(m+1, e, r, arr);
        auto& left = __tree[l];
        auto& right = __tree[r];
        __tree[i] = TreeNode::join(left, right);
    }

    void applyPendingChanges(ll s, ll e, ll j) {
        TreeNode& treeNode = __tree[j];
        pll pendingOverwrite = treeNode.__pendingOverwrite;
        ll pendingDelta = treeNode.__pendingDelta;
        if (pendingOverwrite.first) {
            ll v = pendingOverwrite.second;
            if (v <= 0) {
                treeNode.__prefix = v;
                treeNode.__prefixSize = 1;
                treeNode.__suffix = v;
                treeNode.__suffixSize = 1;
                treeNode.__maxSum = v;
                treeNode.__maxSumSize = 1;
            } else {
                treeNode.__prefix = v * treeNode.__size;
                treeNode.__prefixSize = treeNode.__size;
                treeNode.__suffix = v * treeNode.__size;
                treeNode.__suffixSize = treeNode.__size;
                treeNode.__maxSum = v * treeNode.__size;
                treeNode.__maxSumSize = treeNode.__size;
            }
            treeNode.__max = v;
            treeNode.__min = v;
            treeNode.__sum = v * treeNode.__size;
            treeNode.__pendingOverwrite = {0, 0};
        }
        if (pendingDelta) {
            treeNode.__prefix += pendingDelta * treeNode.__prefixSize;
            treeNode.__suffix += pendingDelta * treeNode.__suffixSize;
            treeNode.__maxSum += pendingDelta * treeNode.__maxSumSize;
            treeNode.__max += pendingDelta;
            treeNode.__min += pendingDelta;
            treeNode.__sum += pendingDelta * treeNode.__size;
            treeNode.__pendingDelta = 0;
        }

        if (s == e || !pendingOverwrite.first && !pendingDelta)
            return;

        ll l = SegmentTree::leftIdx(j);
        ll r = SegmentTree::rightIdx(j);
        auto& left = __tree[l];
        auto& right = __tree[r];
        if (pendingOverwrite.first) {
            left.__pendingDelta = 0;
            left.__pendingOverwrite = pendingOverwrite;
            right.__pendingDelta = 0;
            right.__pendingOverwrite = pendingOverwrite;
        }
        if (pendingDelta) {
            left.__pendingDelta += pendingDelta;
            right.__pendingDelta += pendingDelta;
        }
    }

    static ll leftIdx(ll i) {
        return i*2 + 1;
    }

    static ll rightIdx(ll i) {
        return i*2 + 2;
    }

    static ll middleIdx(ll s, ll e) {
        return (s + e) / 2;
    }
};


void solve() {
    ll n, q;
    cin >> n >> q;
    vll a(n, n - 1);
    SegmentTree stLeft(a);
    SegmentTree stBottom(a);
    set<ll> leftSet;
    set<ll> bottomSet;

    ll cnt = (n - 2) * (n - 2);
    REP(i, q) {
        ll t, x;
        cin >> t >> x;
        x--;
        if (t == 1) {
            if (bottomSet.count(x))
                continue;
            bottomSet.insert(x);
            ll i = stBottom.query(x, x);
            cnt -= i - 1;
            auto it = bottomSet.lower_bound(x);
            if (it == bottomSet.begin())
                stLeft.updateRange(0, i, x);
        } else {
            if (leftSet.count(x))
                continue;
            leftSet.insert(x);
            ll i = stLeft.query(x, x);
            cnt -= i - 1;
            auto it = leftSet.lower_bound(x);
            if (it == leftSet.begin())
                stBottom.updateRange(0, i, x);
        }
    }

    cout << cnt << endl;
}

int main() {
    ios::sync_with_stdio(false);
    cin.tie(0);
    int tt = 1;
    // cin >> tt;
    for (int t = 1; t <= tt; t++) {
        // cout << "Case #" << t << ": ";
        solve();
    }

    // #ifdef DEBUG
    //     for (int t = 1; t <= tt || cin.rdbuf()->in_avail(); t++) {
    //         // cout << "Case #" << t << ": ";
    //         solve();
    //     }
    // #else
    //     for (int t = 1; t <= tt; t++) {
    //         // cout << "Case #" << t << ": ";
    //         solve();
    //     }
    // #endif

    return 0;
}

Measured memory_bytes: 201592