#include <iostream>
#include <iomanip>
#include <algorithm>
#include <array>
#include <cassert>
#include <utility>
#include <vector>
// #include <atcoder/all>

template <class InputIterator>
std::ostream& range_output(std::ostream& os_arg, InputIterator first_arg, InputIterator last_arg){ if(first_arg != last_arg){ do{ os_arg << *(first_arg++); if(first_arg == last_arg) break; os_arg << ' '; } while(true); }  return os_arg; }
template <class Tp> std::ostream& operator << (std::ostream& os_arg, const std::vector<Tp>& arr_arg){ return range_output(os_arg, arr_arg.cbegin(), arr_arg.cend()); }
template <class Tp, std::size_t Size> std::ostream& operator << (std::ostream& os_arg, const std::array<Tp, Size>& arr_arg){ return range_output(os_arg, arr_arg.cbegin(), arr_arg.cend()); }
template <class S, class T> std::ostream& operator << (std::ostream& os_arg, const std::pair<S, T>& pair_arg){ return os_arg << '(' << pair_arg.first << ", " << pair_arg.second << ')'; }

#ifndef ONLINE_JUDGE
    template <typename Head> void dump_out(Head head_arg){ std::cerr << head_arg << '\n'; }
    template <typename Head, typename... Tail>
    void dump_out(Head head_arg, Tail... tail_args){ std::cerr << head_arg << ", "; dump_out(tail_args...); }
    #define dump(...) do { std::cerr << "[in line " << __LINE__ << "] " << #__VA_ARGS__ << " : "; dump_out(__VA_ARGS__); } while(false)
#else
    #define dump(...) (void(0))
#endif


// 双対セグメント木 : 区間更新点取得
// i ∈ [l, r) に関して xi ← f(xi) に変更する
// f(x ; op) := x operator op
template <typename element_t, const element_t id, class func_type = std::plus<element_t>>
class dualSegmentTree{
private:
    unsigned int height;
    unsigned int size;
    std::vector<element_t> data;

    inline void propagate(unsigned int idx){
        unsigned int i, j;
        for(i = height; i ; --i){
            j = idx >> i;
            data[j << 1] = func_type()(data[j << 1], data[j]);
            data[(j << 1) | 1U] = func_type()(data[(j << 1) | 1U], data[j]);
            data[j] = id;
        }
    }
public:
    dualSegmentTree(const unsigned int n = 1){
        size = 1, height = 0; while(size < n) size <<= 1, ++height;
        data.assign(size << 1, id);
    }
    dualSegmentTree(const unsigned int n, const element_t& val){
        size = 1, height = 0; while(size < n) size <<= 1, ++height;
        data.assign(size << 1, id);
        for(unsigned int i = 0, j = size; i < n; ++i, ++j) data[j] = val;
    }
    template <class InputIterator>
    dualSegmentTree(const InputIterator first, const InputIterator last){
        const unsigned int n = last - first;
        size = 1, height = 0; while(size < n) size <<= 1, ++height;
        data.assign(size << 1, id);
        InputIterator itr = first;
        for(unsigned int j = size; itr != last; ++j, ++itr) data[j] = *itr;
    }
    // 区間更新 : O(logN)
    inline void update(unsigned int l, unsigned int r, const element_t& op){
        propagate(l + size); propagate(r + size - 1);
        for(l += size, r += size; l < r; l >>= 1, r >>= 1){
            if(l & 1U) { data[l] = func_type()(data[l], op); l++; }
            if(r & 1U) { --r; data[r] = func_type()(data[r], op); }
        }
    }

    // 点取得 : 計算量 O(logN)
    inline element_t operator [](unsigned int idx) const {
        element_t res = id; 
        for(idx += size; idx ; idx >>= 1) res = func_type()(res, data[idx]);
        return res;
    }
    inline element_t at(unsigned int idx) const {
        assert(0 <= idx and idx < size);
        element_t res = id;
        for(idx += size; idx ; idx >>= 1) res = func_type()(res, data[idx]);
        return res;
    }
};

// 代入 : rhs == id ?  lhs : rhs
template <typename element_t>
struct assignment{
    element_t operator()(const element_t& lhs, const element_t& rhs){
        return (lhs < rhs) ? lhs : rhs;
    }
};

constexpr int inf = 1 << 30;

int main(void){
    std::cin.tie(nullptr); std::ios_base::sync_with_stdio(false); 
    std::cout << std::fixed << std::setprecision(16);

    int n, q; std::cin >> n >> q;
    long long int res = static_cast<long long int>(n - 2) * (n - 2);

    std::vector<int> V(n - 2, n - 2);
    dualSegmentTree<int, inf, assignment<int>> X(V.cbegin(), V.cend()), Y(V.cbegin(), V.cend());
    for(int _ = 0; _ < q; ++_){
        char c; int x; std::cin >> c >> x; x -= 2;
        if(c == '1'){
            const int t = X[x];
            res -= t; Y.update(0, t, x);
        }
        else{
            const int t = Y[x];
            res -= t; X.update(0, t, x);
        }
    }
    std::cout << res << '\n';
    

    return 0;
}

Measured memory_bytes: 8204