// Slower C++ solution:
//include

//------------------------------------------

#include <vector>

#include <list>

#include <map>

#include <unordered_map>

#include <climits>

#include <set>

#include <unordered_set>

#include <deque>

#include <stack>

#include <bitset>

#include <algorithm>

#include <functional>

#include <numeric>

#include <utility>

#include <sstream>

#include <iostream>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <cstdlib>

#include <cctype>

#include <string>

#include <cstring>

#include <ctime>

#include <queue>

#include <random>

#include <chrono>

#include <complex>

#include <regex>

#include <locale>

#include <random>

#include <cassert>

#include <type_traits>



using namespace std;



// typedef

//------------------------------------------

typedef long long LL;

typedef vector<int> VI;

typedef vector<bool> VB;

typedef vector<char> VC;

typedef vector<double> VD;

typedef vector<string> VS;

typedef vector<LL> VLL;

typedef vector<VI> VVI;

typedef vector<VB> VVB;

typedef vector<VS> VVS;

typedef vector<VLL> VVLL;

typedef vector<VVI> VVVI;

typedef vector<VVLL> VVVLL;

typedef pair<int, int> PII;

typedef pair<LL, LL> PLL;

typedef pair<int, string> PIS;

typedef pair<string, int> PSI;

typedef pair<string, string> PSS;

typedef vector<PII> VPII;

typedef vector<PLL> VPLL;

typedef vector<VPII> VVPII;

typedef vector<VPLL> VVPLL;

typedef vector<VS> VVS;

typedef map<int, int> MII;

typedef map<LL, LL> MLL;

typedef map<string, int> MSI;

typedef map<int, string> MIS;



// container util

//------------------------------------------



typedef int pInt[4];

#define ALL(a)  (a).begin(),(a).end()

#define SZ(a) int((a).size())

#define EACH(i, arr) for(typeof((arr).begin()) i=(arr).begin(); i!=(arr).end(); ++i)

#define EXIST(str, e) ((str).find(e)!=(str).end())

#define COUNT(arr, v) count((arr).begin(), (arr).end(), v)

#define SEARCH(v, w) search((v).begin(), (v).end(), (w).begin(), (w).end())

#define SORT(c) sort((c).begin(),(c).end())

#define RSORT(c) sort((c).rbegin(),(c).rend())

#define REVERSE(c) reverse((c).begin(), (c).end())

#define ROTATE_LEFT(arr, c) rotate((arr).begin(), (arr).begin()+(c), (arr).end())

#define ROTATE_RIGHT(arr, c) rotate((arr).rbegin(), (arr).rbegin() + (c), (arr).rend())

#define SUMI(arr) accumulate((arr).begin(), (arr).end(), 0)

#define SUMD(arr) accumulate((arr).begin(), (arr).end(), 0.)

#define SUMLL(arr) accumulate((arr).begin(), (arr).end(), 0LL)

#define MULD(arr) accumulate((arr).begin(), (arr).end(), 1., multiplies<double>())

#define UB(arr, n) upper_bound((arr).begin(), (arr).end(), n)

#define LB(arr, n) lower_bound((arr).begin(), (arr).end(), n)

#define PB push_back

#define MP make_pair

#define ft first

#define sd second





// input output

//------------------------------------------

#define GL(s) getline(cin, (s))

#define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0)

#define OUT(d) std::cout<<(d)

#define OUT_L(d) std::cout<<(d)<<endl

#define FOUT(n, data) std::cout<<std::fixed<<std::setprecision(n)<<(data)

#define FOUT_L(n, data) std::cout<<std::fixed<<std::setprecision(n)<<(data)<<"\n"

#define EL() printf("\n")

#define SHOW_VECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}

#define SHOW_MAP(v) {std::cerr << #v << endl; for(const auto& xxx: v){std::cerr << xxx.first << " " << xxx.second << "\n";}}

#define Yes() printf("Yes\n")

#define No() printf("No\n")

#define YES() printf("YES\n")

#define NO() printf("NO\n")

#define Yay() printf("Yay!\n")

#define Nnn() printf(":(\n")

#define CE(x, y) ((x + y - 1) / (y))





template<typename T1, typename T2>

istream &operator>>(istream &in, pair<T1, T2> &p) {

    in >> p.first >> p.second;

    return in;

}



template<typename T>

istream &operator>>(istream &in, vector<T> &v) {

    for (auto &x: v)

        in >> x;

    return in;

}





template<typename T1, typename T2>

ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {

    out << "[" << p.first << ", " << p.second << "]" << "\n";

    return out;

}



template<class T1, class T2>

inline bool chmin(T1 &a, T2 b) {

    if (a > b) {

        a = b;

        return true;

    }

    return false;

}



template<class T1, class T2>

inline bool chmax(T1 &a, T2 b) {

    if (a < b) {

        a = b;

        return true;

    }

    return false;

}





//repetition

//------------------------------------------

#define FOR(i, a, b) for(int i=(a);i<(b);++i)

#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)

#define REP(i, n)  FOR(i,0,n)

#define RREP(i, n) for(int i = n-1;i >= 0;i--)

#define FORLL(i, a, b) for(LL i=LL(a);i<LL(b);++i)

#define RFORLL(i, a, b) for(LL i=LL(b)-1;i>=LL(a);--i)

#define REPLL(i, n) for(LL i=0;i<LL(n);++i)

#define RREPLL(i, n) for(LL i=LL(n)-1;i>=0;--i)

#define FOREACH(x, arr) for(auto &(x) : (arr))



// Option + Control + K  Terminal

// Command + Control + K    Run

// Command + b   EOF

//#include "atcoder/all"



//------------------------------------------

//------------------------------------------



template<int_fast64_t Modulas = 1000000007ul>

class ModInt {

    using u64 = int_fast64_t;

public:

    u64 x;



    constexpr ModInt() : x(0) {}

    constexpr ModInt(int_fast64_t v) : x((v % Modulas + Modulas) % Modulas) {}

    constexpr ModInt operator+(const ModInt rhs) const noexcept {

        return ModInt(*this) += rhs;

    }

    constexpr ModInt operator-(const ModInt rhs) const noexcept {

        return ModInt(*this) -= rhs;

    }

    constexpr ModInt operator*(const ModInt rhs) const noexcept {

        return ModInt(*this) *= rhs;

    }

    constexpr ModInt operator/(const ModInt rhs) const noexcept {

        return ModInt(*this) /= rhs;

    }

    constexpr ModInt operator/(const long long rhs) const noexcept {

        return ModInt(*this) /= rhs;

    }

    constexpr ModInt operator+=(const ModInt rhs) noexcept {

        x += rhs.x;

        if (x >= Modulas) x -= Modulas;

        return *this;

    }

    constexpr ModInt operator+=(const long long rhs) noexcept {

        auto hs = ModInt<Modulas>(rhs);

        (*this) += hs;

        return *this;

    }

    constexpr ModInt operator-=(const ModInt rhs) noexcept {

        if (x < rhs.x) x += Modulas;

        x -= rhs.x;

        return *this;

    }

    constexpr ModInt operator-=(const long long rhs) noexcept {

        auto hs = ModInt<Modulas>(rhs);

        (*this) -= hs;

        return *this;

    }

    constexpr ModInt operator*=(const ModInt rhs) noexcept {

        x = x * rhs.x % Modulas;

        return *this;

    }

    constexpr ModInt operator*=(const long long rhs) noexcept {

        auto hs = ModInt<Modulas>(rhs);

        (*this) *= hs;

        return *this;

    }

    constexpr ModInt &operator/=(ModInt rhs) noexcept {

        u64 exp = Modulas - 2;

        while (exp > 0) {

            if (exp & 1ul) *this *= rhs;

            rhs *= rhs;

            exp >>= 1ul;

        }

        return *this;

    }

    constexpr ModInt &operator/=(long long rhs) noexcept {

        auto hs = ModInt<Modulas>(rhs);

        (*this) /= hs;

        return *this;

    }



    constexpr ModInt &operator++() noexcept {

        x++;

        if (x >= Modulas) x -= Modulas;

        return *this;

    }

    constexpr ModInt &operator--() noexcept {

        if (x == 0) x += Modulas;

        x--;

        return *this;

    }

    constexpr bool operator<(const ModInt rhs) const noexcept {

        return x < rhs.x;

    }

    constexpr bool operator==(const ModInt rhs) const noexcept {

        return this->x == rhs.x;

    }

    constexpr bool operator!=(const ModInt rhs) const noexcept {

        return !(*this == rhs);

    }

    friend istream &operator>>(istream &in, ModInt &m) {

        in >> m.x;

        if (m.x < 0) m.x += Modulas;

        m.x %= Modulas;

        return in;

    }

    friend ostream &operator<<(ostream &out, const ModInt &p) {

        out << p.x;

        return out;

    }

    constexpr ModInt pow(u64 p) const {

        ModInt ret(1);

        ModInt mul(x);

        while (p > 0) {

            if (p & 1ul) ret *= mul;

            mul *= mul;

            p >>= 1ul;

        }

        return ret;

    }

    constexpr ModInt operator~() const noexcept {

        u64 exp = Modulas - 2;

        return pow(exp);

    }



    constexpr static ModInt arith_sum(ModInt<Modulas> a, ModInt<Modulas> d, ModInt<Modulas> n) noexcept {

        return (a * ModInt<Modulas>(2) + (n - 1) * d) * n / ModInt<Modulas>(2);

    }

};



constexpr LL INF = 1000000000000LL;



struct LazySegmentTree {

private:

    LL n;

    vector<LL> node, lazy;

    vector<bool> lazyFlag;



public:

    LazySegmentTree(vector<LL> v) {

        LL sz = (LL) v.size();

        n = 1;

        while (n < sz) n *= 2;

        node.resize(2 * n - 1);

        lazy.resize(2 * n - 1, INF);

        lazyFlag.resize(2 * n - 1, false);



        for (LL i = 0; i < sz; i++) node[i + n - 1] = v[i];

        for (LL i = n - 2; i >= 0; i--) node[i] = min(node[i * 2 + 1], node[i * 2 + 2]);

    }



    void lazyEvaluate(LL k, LL l, LL r) {

        if (lazyFlag[k]) {

            node[k] = min(node[k], lazy[k]);

            if (r - l > 1) {

                lazy[k * 2 + 1] = min(lazy[k * 2 + 1], lazy[k]);

                lazy[k * 2 + 2] = min(lazy[k * 2 + 2], lazy[k]);

                lazyFlag[k * 2 + 1] = lazyFlag[k * 2 + 2] = true;

            }

            lazyFlag[k] = false;

        }

    }



    void update(LL a, LL b, LL x, LL k = 0, LL l = 0, LL r = -1) {

        if (r < 0) r = n;

        lazyEvaluate(k, l, r);

        if (b <= l || r <= a) return;

        if (a <= l && r <= b) {

            lazy[k] = min(lazy[k], x);

            lazyFlag[k] = true;

            lazyEvaluate(k, l, r);

        } else {

            update(a, b, x, 2 * k + 1, l, (l + r) / 2);

            update(a, b, x, 2 * k + 2, (l + r) / 2, r);

            node[k] = min(node[2 * k + 1], node[2 * k + 2]);

        }

    }



    LL find(LL a, LL b, LL k = 0, LL l = 0, LL r = -1) {

        if (r < 0) r = n;

        lazyEvaluate(k, l, r);

        if (b <= l || r <= a) return INF;

        if (a <= l && r <= b) return node[k];

        LL vl = find(a, b, 2 * k + 1, l, (l + r) / 2);

        LL vr = find(a, b, 2 * k + 2, (l + r) / 2, r);

        return min(vl, vr);

    }

};





int main() {



    LL N, Q;

    cin >> N >> Q;



    LL ans = (N - 2) * (N - 2);



    LazySegmentTree xtree(VLL(N, N - 1));

    LazySegmentTree ytree(VLL(N, N - 1));



    while (Q--) {

        LL p, x;

        cin >> p >> x;

        x--;

        if (p == 1) {

            LL d = xtree.find(x, x + 1);

            LL v = max(0LL, d - 1);

            ans -= v;

            ytree.update(1, d, x);

        } else {

            LL d = ytree.find(x, x + 1);

            LL v = max(0LL, d - 1);

            ans -= v;

            xtree.update(1, d, x);

        }

    }



    cout << ans << endl;



    return 0;

}








































































































// Faster C++ solution for the same problem (measured speedup: 1.1951195116439326x):
//include

//------------------------------------------

#include <vector>

#include <list>

#include <map>

#include <unordered_map>

#include <climits>

#include <set>

#include <unordered_set>

#include <deque>

#include <stack>

#include <bitset>

#include <algorithm>

#include <functional>

#include <numeric>

#include <utility>

#include <sstream>

#include <iostream>

#include <iomanip>

#include <cstdio>

#include <cmath>

#include <cstdlib>

#include <cctype>

#include <string>

#include <cstring>

#include <ctime>

#include <queue>

#include <random>

#include <chrono>

#include <complex>

#include <regex>

#include <locale>

#include <random>

#include <cassert>

#include <type_traits>



using namespace std;



// typedef

//------------------------------------------

typedef long long LL;

typedef vector<int> VI;

typedef vector<bool> VB;

typedef vector<char> VC;

typedef vector<double> VD;

typedef vector<string> VS;

typedef vector<LL> VLL;

typedef vector<VI> VVI;

typedef vector<VB> VVB;

typedef vector<VS> VVS;

typedef vector<VLL> VVLL;

typedef vector<VVI> VVVI;

typedef vector<VVLL> VVVLL;

typedef pair<int, int> PII;

typedef pair<LL, LL> PLL;

typedef pair<int, string> PIS;

typedef pair<string, int> PSI;

typedef pair<string, string> PSS;

typedef vector<PII> VPII;

typedef vector<PLL> VPLL;

typedef vector<VPII> VVPII;

typedef vector<VPLL> VVPLL;

typedef vector<VS> VVS;

typedef map<int, int> MII;

typedef map<LL, LL> MLL;

typedef map<string, int> MSI;

typedef map<int, string> MIS;



// container util

//------------------------------------------



typedef int pInt[4];

#define ALL(a)  (a).begin(),(a).end()

#define SZ(a) int((a).size())

#define EACH(i, arr) for(typeof((arr).begin()) i=(arr).begin(); i!=(arr).end(); ++i)

#define EXIST(str, e) ((str).find(e)!=(str).end())

#define COUNT(arr, v) count((arr).begin(), (arr).end(), v)

#define SEARCH(v, w) search((v).begin(), (v).end(), (w).begin(), (w).end())

#define SORT(c) sort((c).begin(),(c).end())

#define RSORT(c) sort((c).rbegin(),(c).rend())

#define REVERSE(c) reverse((c).begin(), (c).end())

#define ROTATE_LEFT(arr, c) rotate((arr).begin(), (arr).begin()+(c), (arr).end())

#define ROTATE_RIGHT(arr, c) rotate((arr).rbegin(), (arr).rbegin() + (c), (arr).rend())

#define SUMI(arr) accumulate((arr).begin(), (arr).end(), 0)

#define SUMD(arr) accumulate((arr).begin(), (arr).end(), 0.)

#define SUMLL(arr) accumulate((arr).begin(), (arr).end(), 0LL)

#define MULD(arr) accumulate((arr).begin(), (arr).end(), 1., multiplies<double>())

#define UB(arr, n) upper_bound((arr).begin(), (arr).end(), n)

#define LB(arr, n) lower_bound((arr).begin(), (arr).end(), n)

#define PB push_back

#define MP make_pair

#define ft first

#define sd second





// input output

//------------------------------------------

#define GL(s) getline(cin, (s))

#define INIT() std::ios::sync_with_stdio(false);std::cin.tie(0)

#define OUT(d) std::cout<<(d)

#define OUT_L(d) std::cout<<(d)<<endl

#define FOUT(n, data) std::cout<<std::fixed<<std::setprecision(n)<<(data)

#define FOUT_L(n, data) std::cout<<std::fixed<<std::setprecision(n)<<(data)<<"\n"

#define EL() printf("\n")

#define SHOW_VECTOR(v) {std::cerr << #v << "\t:";for(const auto& xxx : v){std::cerr << xxx << " ";}std::cerr << "\n";}

#define SHOW_MAP(v) {std::cerr << #v << endl; for(const auto& xxx: v){std::cerr << xxx.first << " " << xxx.second << "\n";}}

#define Yes() printf("Yes\n")

#define No() printf("No\n")

#define YES() printf("YES\n")

#define NO() printf("NO\n")

#define Yay() printf("Yay!\n")

#define Nnn() printf(":(\n")

#define CE(x, y) ((x + y - 1) / (y))





template<typename T1, typename T2>

istream &operator>>(istream &in, pair<T1, T2> &p) {

    in >> p.first >> p.second;

    return in;

}



template<typename T>

istream &operator>>(istream &in, vector<T> &v) {

    for (auto &x: v)

        in >> x;

    return in;

}





template<typename T1, typename T2>

ostream &operator<<(ostream &out, const std::pair<T1, T2> &p) {

    out << "[" << p.first << ", " << p.second << "]" << "\n";

    return out;

}



template<class T1, class T2>

inline bool chmin(T1 &a, T2 b) {

    if (a > b) {

        a = b;

        return true;

    }

    return false;

}



template<class T1, class T2>

inline bool chmax(T1 &a, T2 b) {

    if (a < b) {

        a = b;

        return true;

    }

    return false;

}





//repetition

//------------------------------------------

#define FOR(i, a, b) for(int i=(a);i<(b);++i)

#define RFOR(i, a, b) for(int i=(b)-1;i>=(a);--i)

#define REP(i, n)  FOR(i,0,n)

#define RREP(i, n) for(int i = n-1;i >= 0;i--)

#define FORLL(i, a, b) for(LL i=LL(a);i<LL(b);++i)

#define RFORLL(i, a, b) for(LL i=LL(b)-1;i>=LL(a);--i)

#define REPLL(i, n) for(LL i=0;i<LL(n);++i)

#define RREPLL(i, n) for(LL i=LL(n)-1;i>=0;--i)

#define FOREACH(x, arr) for(auto &(x) : (arr))



// Option + Control + K  Terminal

// Command + Control + K    Run

// Command + b   EOF

//#include "atcoder/all"



//------------------------------------------

//------------------------------------------





namespace atcoder {



    namespace internal {



// @param n `0 <= n`

// @return minimum non-negative `x` s.t. `n <= 2**x`

        int ceil_pow2(int n) {

            int x = 0;

            while ((1U << x) < (unsigned int) (n)) x++;

            return x;

        }



// @param n `1 <= n`

// @return minimum non-negative `x` s.t. `(n & (1 << x)) != 0`

        int bsf(unsigned int n) {

#ifdef _MSC_VER

            unsigned long index;

    _BitScanForward(&index, n);

    return index;

#else

            return __builtin_ctz(n);

#endif

        }



    }  // namespace internal



}  // namespace atcoder



#include <cassert>

#include <vector>



namespace atcoder {



    template<class S, S (*op)(S, S), S (*e)()>

    struct segtree {

    public:

        segtree() : segtree(0) {}

        segtree(int n) : segtree(std::vector<S>(n, e())) {}

        segtree(const std::vector<S> &v) : _n(int(v.size())) {

            log = internal::ceil_pow2(_n);

            size = 1 << log;

            d = std::vector<S>(2 * size, e());

            for (int i = 0; i < _n; i++) d[size + i] = v[i];

            for (int i = size - 1; i >= 1; i--) {

                update(i);

            }

        }



        void set(int p, S x) {

            assert(0 <= p && p < _n);

            p += size;

            d[p] = x;

            for (int i = 1; i <= log; i++) update(p >> i);

        }



        S get(int p) {

            assert(0 <= p && p < _n);

            return d[p + size];

        }



        S prod(int l, int r) {

            assert(0 <= l && l <= r && r <= _n);

            S sml = e(), smr = e();

            l += size;

            r += size;



            while (l < r) {

                if (l & 1) sml = op(sml, d[l++]);

                if (r & 1) smr = op(d[--r], smr);

                l >>= 1;

                r >>= 1;

            }

            return op(sml, smr);

        }



        S all_prod() { return d[1]; }



        template<bool (*f)(S)>

        int max_right(int l) {

            return max_right(l, [](S x) { return f(x); });

        }

        template<class F>

        int max_right(int l, F f) {

            assert(0 <= l && l <= _n);

            assert(f(e()));

            if (l == _n) return _n;

            l += size;

            S sm = e();

            do {

                while (l % 2 == 0) l >>= 1;

                if (!f(op(sm, d[l]))) {

                    while (l < size) {

                        l = (2 * l);

                        if (f(op(sm, d[l]))) {

                            sm = op(sm, d[l]);

                            l++;

                        }

                    }

                    return l - size;

                }

                sm = op(sm, d[l]);

                l++;

            } while ((l & -l) != l);

            return _n;

        }



        template<bool (*f)(S)>

        int min_left(int r) {

            return min_left(r, [](S x) { return f(x); });

        }

        template<class F>

        int min_left(int r, F f) {

            assert(0 <= r && r <= _n);

            assert(f(e()));

            if (r == 0) return 0;

            r += size;

            S sm = e();

            do {

                r--;

                while (r > 1 && (r % 2)) r >>= 1;

                if (!f(op(d[r], sm))) {

                    while (r < size) {

                        r = (2 * r + 1);

                        if (f(op(d[r], sm))) {

                            sm = op(d[r], sm);

                            r--;

                        }

                    }

                    return r + 1 - size;

                }

                sm = op(d[r], sm);

            } while ((r & -r) != r);

            return 0;

        }



    private:

        int _n, size, log;

        std::vector<S> d;



        void update(int k) { d[k] = op(d[2 * k], d[2 * k + 1]); }

    };



}  // namespace atcoder



int op(int a, int b) {

    return min(a, b);

}



int e() {

    return (int) (1e9);

}



int main() {



    int N, Q;

    cin >> N >> Q;



    atcoder::segtree<int, op, e> tx(N + 1), ty(N + 1);

    tx.set(N, N);

    ty.set(N, N);



    LL ans = LL(N - 2) * (N - 2);

    REP(_, Q) {

        int typ, i;

        cin >> typ >> i;

        if (typ == 1) {

            int r = tx.prod(i, N + 1);

            // printf("x: %d %d\n", i, r);

            ans -= r - 2;

            ty.set(r, op(ty.get(r), i));

        } else {

            int r = ty.prod(i, N + 1);

            // printf("y: %d %d\n", i, r);

            ans -= r - 2;

            tx.set(r, op(tx.get(r), i));

        }

    }



    cout<< ans << endl;

    return 0;

}