#[allow(unused_imports)]
use proconio::{input, marker::*};

#[allow(unused_imports)]
use std::collections::{BTreeMap, BTreeSet, BinaryHeap, HashMap, HashSet, VecDeque};

#[allow(unused_imports)]
use std::io::Write;

#[allow(unused_macros)]
macro_rules! debug {
    ($($a:expr),*) => {
        #[cfg(debug_assertions)]
        writeln!(&mut std::io::stderr(), concat!("[DEBUG] ", $(stringify!($a), "={:?} "),*), $($a),*).unwrap();
    }
}

pub trait Monoid<T>: SemiGroup<T> {
    fn identity() -> T;
}
pub trait SemiGroup<T>: Magma<T> {}
pub trait Magma<T> {
    fn operate(lhs: T, rhs: T) -> T;
}
use self::lazysegtree::{Effection, LazySegmentTree, MultiOperator};
mod lazysegtree {
    use super::Monoid;
    use std;
    use std::marker::PhantomData;
    pub trait Effection<T, E> {
        fn operate(element: T, effector: E) -> T;
    }
    pub trait MultiOperator<E> {
        fn multi_operate(element: E, num: usize) -> E;
    }
    #[derive(Debug)]
    pub struct LazySegmentTree<T, MT, E, ME, A, P> {
        n: usize,
        data: Vec<T>,
        lazy_data: Vec<E>,
        value_monoid: PhantomData<fn() -> MT>,
        effector_monoid: PhantomData<fn() -> ME>,
        effection: PhantomData<fn() -> A>,
        multi_operator: PhantomData<fn() -> P>,
    }
    impl<T, MT, E, ME, A, P> LazySegmentTree<T, MT, E, ME, A, P>
    where
        MT: Monoid<T>,
        T: Copy + Clone + std::fmt::Debug,
        ME: Monoid<E>,
        E: Copy + Clone + std::fmt::Debug + Eq,
        A: Effection<T, E>,
        P: MultiOperator<E>,
    {
        pub fn new(nt: usize) -> Self {
            let mut n = 1;
            while n < nt {
                n *= 2;
            }
            LazySegmentTree {
                n: n,
                data: vec![MT::identity(); 2 * n - 1],
                lazy_data: vec![ME::identity(); 2 * n - 1],
                value_monoid: PhantomData,
                effector_monoid: PhantomData,
                effection: PhantomData,
                multi_operator: PhantomData,
            }
        }
        fn evaluate(&mut self, len: usize, index: usize) {
            if self.lazy_data[index] == ME::identity() {
                return;
            }
            if 2 * index + 1 < 2 * self.n - 1 {
                self.lazy_data[2 * index + 1] =
                    ME::operate(self.lazy_data[2 * index + 1], self.lazy_data[index]);
                self.lazy_data[2 * index + 2] =
                    ME::operate(self.lazy_data[2 * index + 2], self.lazy_data[index]);
            }
            self.data[index] = A::operate(
                self.data[index],
                P::multi_operate(self.lazy_data[index], len),
            );
            self.lazy_data[index] = ME::identity();
        }
        pub fn update(&mut self, l: usize, r: usize, val: E) {
            let n = self.n;
            self._update(l, r, 0, 0, n, val);
        }
        fn _update(&mut self, ql: usize, qr: usize, index: usize, l: usize, r: usize, val: E) -> T {
            self.evaluate(r - l, index);
            if r <= ql || qr <= l {
                return self.data[index];
            }
            if ql <= l && r <= qr {
                self.lazy_data[index] = ME::operate(self.lazy_data[index], val);
                return A::operate(self.data[index], self.lazy_data[index]);
            }
            self.data[index] = MT::operate(
                self._update(ql, qr, 2 * index + 1, l, (l + r) / 2, val),
                self._update(ql, qr, 2 * index + 2, (l + r) / 2, r, val),
            );
            self.data[index]
        }
        pub fn get(&mut self, l: usize, r: usize) -> T {
            let n = self.n;
            self._get(l, r, 0, 0, n)
        }
        fn _get(&mut self, ql: usize, qr: usize, index: usize, l: usize, r: usize) -> T {
            self.evaluate(r - l, index);
            if r <= ql || qr <= l {
                return MT::identity();
            }
            if ql <= l && r <= qr {
                return self.data[index];
            }
            let vl = self._get(ql, qr, 2 * index + 1, l, (l + r) / 2);
            let vr = self._get(ql, qr, 2 * index + 2, (l + r) / 2, r);
            MT::operate(vl, vr)
        }
    }
}

struct IMonoidT;
impl Monoid<usize> for IMonoidT {
    fn identity() -> usize {
        std::usize::MAX
    }
}
impl Magma<usize> for IMonoidT {
    fn operate(lhs: usize, rhs: usize) -> usize {
        std::cmp::min(lhs, rhs)
    }
}
impl SemiGroup<usize> for IMonoidT {}

struct IMonoidE;
impl Monoid<usize> for IMonoidE {
    fn identity() -> usize {
        std::usize::MAX
    }
}
impl Magma<usize> for IMonoidE {
    fn operate(lhs: usize, rhs: usize) -> usize {
        std::cmp::min(lhs, rhs)
    }
}
impl SemiGroup<usize> for IMonoidE {}

struct IEffection {}
impl Effection<usize, usize> for IEffection {
    fn operate(element: usize, effector: usize) -> usize {
        std::cmp::min(element, effector)
    }
}
struct IMultiOperator;
impl MultiOperator<usize> for IMultiOperator {
    fn multi_operate(element: usize, num: usize) -> usize {
        element
    }
}

fn main() {
    input! {
        n: usize,
        q: usize,
        queries: [(Chars, usize); q],
    }

    let mut tree_h =
        LazySegmentTree::<usize, IMonoidT, usize, IMonoidE, IEffection, IMultiOperator>::new(n);
    let mut tree_w =
        LazySegmentTree::<usize, IMonoidT, usize, IMonoidE, IEffection, IMultiOperator>::new(n);

    tree_h.update(0, n, n - 2);
    tree_w.update(0, n, n - 2);

    let mut total = (n - 2) * (n - 2);
    for (q, x) in queries {
        if q[0] == '1' {
            let val = tree_h.get(x - 2, x - 1);
            total -= val;
            tree_w.update(0, val, x - 2);
        } else {
            let val = tree_w.get(x - 2, x - 1);
            total -= val;
            tree_h.update(0, val, x - 2);
        }
    }
    println!("{}", total);
}


Measured memory_bytes: 32612