AtCoder Beginner Contest 179 - Simplified Reversi

There is a grid with N rows and N columns of squares. Let (i, j) be the square at the i-th row from the top and the j-th column from the left.
Each of the central (N-2) \times (N-2) squares in the grid has a black stone on it.
Each of the 2N - 1 squares on the bottom side and the right side has a white stone on it.
Q queries are given. We ask you to process them in order.
There are two kinds of queries. Their input format and description are as follows:
 - 1 x: Place a white stone on (1, x). After that, for each black stone between (1, x) and the first white stone you hit if you go down from (1, x), replace it with a white stone.
 - 2 x: Place a white stone on (x, 1). After that, for each black stone between (x, 1) and the first white stone you hit if you go right from (x, 1), replace it with a white stone.
How many black stones are there on the grid after processing all Q queries?

-----Constraints-----
 - 3 \leq N \leq 2\times 10^5
 - 0 \leq Q \leq \min(2N-4,2\times 10^5)
 - 2 \leq x \leq N-1
 - Queries are pairwise distinct.

-----Input-----
Input is given from Standard Input in the following format:
N Q
Query_1
\vdots
Query_Q

-----Output-----
Print how many black stones there are on the grid after processing all Q queries.

-----Sample Input-----
5 5
1 3
2 3
1 4
2 2
1 2

-----Sample Output-----
1

After each query, the grid changes in the following way:

Difficulty: MEDIUM_HARD

Starter code:

Solutions:
(n, q) = list(map(int, input().split()))
n -= 2
X = [[n] * n, [n] * n]
H = [n, n]
ans = n ** 2
for _ in range(q):
	(a, b) = list(map(int, input().split()))
	a -= 1
	b -= 2
	for i in range(b, H[a]):
		X[a][i] = H[a ^ 1]
	H[a] = min(H[a], b)
	ans -= X[a][b]
print(ans)


INF = 10 ** 18

class BITmin:

	def __init__(self, max):
		self.max = max
		self.data = [self.max - 1] * (self.max + 1)

	def query_min(self, i):
		s = INF
		while i <= self.max:
			if s > self.data[i]:
				s = self.data[i]
			i += i & -i
		return s

	def update(self, i, x):
		while i > 0:
			if x < self.data[i]:
				self.data[i] = x
			i -= i & -i
import sys
input = sys.stdin.buffer.readline
(N, Q) = map(int, input().split())
Query = [list(map(int, input().split())) for _ in range(Q)]
BitX = BITmin(N)
BitY = BITmin(N)
ans = (N - 2) * (N - 2)
for (a, b) in Query:
	b -= 1
	if a == 1:
		loc = BitX.query_min(b)
		ans -= loc - 1
		BitY.update(loc, b)
	else:
		loc = BitY.query_min(b)
		ans -= loc - 1
		BitX.update(loc, b)
print(ans)


printn = lambda x: print(x, end='')
inn = lambda : int(input())
inl = lambda : list(map(int, input().split()))
inm = lambda : map(int, input().split())
ins = lambda : input().strip()
DBG = True
BIG = 10 ** 18
R = 10 ** 9 + 7

def ddprint(x):
	if DBG:
		print(x)

class Segtree:

	def __init__(s, l, unit, oper):
		s.unit = unit
		s.oper = oper
		s.n = 1
		while s.n < l:
			s.n *= 2
		s.ary = [s.unit for i in range(2 * s.n - 1)]

	def get(s, i):
		return s.ary[i + s.n - 1]

	def set(s, i, v):
		k = i + s.n - 1
		s.ary[k] = v
		while k > 0:
			k = (k - 1) // 2
			s.ary[k] = s.oper(s.ary[2 * k + 1], s.ary[2 * k + 2])

	def setary(s, a):
		for (i, v) in enumerate(a):
			s.ary[i + s.n - 1] = v
		for k in range(s.n - 2, -1, -1):
			s.ary[k] = s.oper(s.ary[2 * k + 1], s.ary[2 * k + 2])

	def query(s, x, y):
		l = x + s.n - 1
		r = y + s.n - 1
		res = s.unit
		while l < r:
			if not l % 2:
				res = s.oper(res, s.ary[l])
				l += 1
			if not r % 2:
				r -= 1
				res = s.oper(res, s.ary[r])
			l >>= 1
			r >>= 1
		return res
(n, q) = inm()
b = (n - 2) ** 2
minx = x = n - 1
miny = y = n - 1
sx = Segtree(n, n - 1, lambda x, y: min(x, y))
sy = Segtree(n, n - 1, lambda x, y: min(x, y))
z = [n - 1] * n
sx.setary(z)
sy.setary(z)
for i in range(q):
	(t, k) = inm()
	k -= 1
	if t == 1:
		b -= sy.query(k, n) - 1
		if k < minx:
			sx.set(miny, k)
			minx = k
	else:
		b -= sx.query(k, n) - 1
		if k < miny:
			sy.set(minx, k)
			miny = k
print(b)


(N, Q) = map(int, input().split())
HW = [N, N]
ans = (N - 2) ** 2
L_HW = [[N - 2 for i in range(N)] for j in range(2)]
for _ in range(Q):
	(vh, x) = map(int, input().split())
	vh -= 1
	if x > HW[1 - vh]:
		ans -= L_HW[1 - vh][x]
	else:
		L_HW[1 - vh][x + 1:HW[1 - vh]] = [HW[vh] - 2] * (HW[1 - vh] - x - 1)
		HW[1 - vh] = x
		ans -= HW[vh] - 2
print(ans)


import sys
input = sys.stdin.readline
(N, Q) = list(map(int, input().split()))

class RUQ:

	def __init__(self, N, default=None):
		self.N0 = 2 ** (N - 1).bit_length()
		self.data = [(-1, N - 1)] * (2 * self.N0)
		self.INF = (-1, default)

	def update(self, l, r, v):
		L = l + self.N0
		R = r + self.N0
		while L < R:
			if R & 1:
				R -= 1
				self.data[R - 1] = v
			if L & 1:
				self.data[L - 1] = v
				L += 1
			L >>= 1
			R >>= 1

	def _query(self, k):
		k += self.N0 - 1
		s = self.INF
		while k >= 0:
			if self.data[k]:
				s = max(s, self.data[k])
			k = (k - 1) // 2
		return s

	def query(self, k):
		return self._query(k)[1]
TATE = RUQ(N - 1, N - 2)
YOKO = RUQ(N - 1, N - 2)
hidari = N
ue = N
ans = (N - 2) ** 2
for t in range(Q):
	(c, x) = list(map(int, input().split()))
	if c == 1:
		ans -= TATE.query(x - 2)
		if x < hidari:
			hidari = x
			YOKO.update(0, TATE.query(x - 2), (t, x - 2))
	else:
		ans -= YOKO.query(x - 2)
		if x < ue:
			ue = x
			TATE.update(0, YOKO.query(x - 2), (t, x - 2))
print(ans)


class LazySegmentTree:

	def __init__(self, init_val, segfunc, ide_ele):
		n = len(init_val)
		self.segfunc = segfunc
		self.ide_ele = ide_ele
		self.num = 1 << (n - 1).bit_length()
		self.data = [ide_ele] * 2 * self.num
		self.lazy = [None] * 2 * self.num
		for i in range(n):
			self.data[self.num + i] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.data[i] = self.segfunc(self.data[2 * i], self.data[2 * i + 1])

	def gindex(self, l, r):
		l += self.num
		r += self.num
		lm = l >> (l & -l).bit_length()
		rm = r >> (r & -r).bit_length()
		while r > l:
			if l <= lm:
				yield l
			if r <= rm:
				yield r
			r >>= 1
			l >>= 1
		while l:
			yield l
			l >>= 1

	def propagates(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i]
			if v is None:
				continue
			self.lazy[2 * i] = v
			self.lazy[2 * i + 1] = v
			self.data[2 * i] = v
			self.data[2 * i + 1] = v
			self.lazy[i] = None

	def update(self, l, r, x):
		(*ids,) = self.gindex(l, r)
		self.propagates(*ids)
		l += self.num
		r += self.num
		while l < r:
			if l & 1:
				self.lazy[l] = x
				self.data[l] = x
				l += 1
			if r & 1:
				self.lazy[r - 1] = x
				self.data[r - 1] = x
			r >>= 1
			l >>= 1
		for i in ids:
			self.data[i] = self.segfunc(self.data[2 * i], self.data[2 * i + 1])

	def query(self, l, r):
		(*ids,) = self.gindex(l, r)
		self.propagates(*ids)
		res = self.ide_ele
		l += self.num
		r += self.num
		while l < r:
			if l & 1:
				res = self.segfunc(res, self.data[l])
				l += 1
			if r & 1:
				res = self.segfunc(res, self.data[r - 1])
			l >>= 1
			r >>= 1
		return res

def segfunc(x, y):
	return min(x, y)
ide_ele = 10 ** 9
(N, Q) = map(int, input().split())
ans = (N - 2) * (N - 2)
R = [N] * (N + 1)
W = [N] * (N + 1)
seg_r = LazySegmentTree(R, segfunc, ide_ele)
seg_w = LazySegmentTree(W, segfunc, ide_ele)
for i in range(Q):
	(a, b) = map(int, input().split())
	if a == 1:
		t = seg_r.query(b, b + 1)
		ans -= max(0, t - 2)
		if b <= seg_w.query(1, 2):
			seg_w.update(1, t + 1, b)
		seg_r.update(b, b + 1, 0)
	else:
		t = seg_w.query(b, b + 1)
		ans -= max(0, t - 2)
		if b <= seg_r.query(1, 2):
			seg_r.update(1, t + 1, b)
		seg_w.update(b, b + 1, 0)
print(ans)


import bisect, copy, heapq, math, sys
from collections import *
from functools import lru_cache
from itertools import accumulate, combinations, permutations, product

def input():
	return sys.stdin.readline()[:-1]

def ruiseki(lst):
	return [0] + list(accumulate(lst))

def celi(a, b):
	return -(-a // b)
sys.setrecursionlimit(5000000)
mod = pow(10, 9) + 7
al = [chr(ord('a') + i) for i in range(26)]
direction = [[1, 0], [0, 1], [-1, 0], [0, -1]]
(n, q) = map(int, input().split())
query = [list(map(int, input().split())) for i in range(q)]
tate = deque([(n, n - 2)])
yoko = deque([(n, n - 2)])
ans = (n - 2) * (n - 2)
for (i, j) in query:
	if i == 1:
		(a, b) = (tate, yoko)
	else:
		(b, a) = (tate, yoko)
	tmp = bisect.bisect_left(a, (j, 0))
	ans -= a[tmp][1]
	if tmp == 0:
		b.appendleft((a[tmp][1] + 2, j - 2))
		a.appendleft((j, a[tmp][1]))
print(ans)


import sys

class SegmentTree:

	def __init__(self, A, dot, e):
		n = 2 ** (len(A) - 1).bit_length()
		self.__n = n
		self.__dot = dot
		self.__e = e
		self.__node = [e] * (2 * n)
		for i in range(len(A)):
			self.__node[i + n] = A[i]
		for i in range(n - 1, 0, -1):
			self.__node[i] = self.__dot(self.__node[2 * i], self.__node[2 * i + 1])

	def update(self, i, c):
		i += self.__n
		node = self.__node
		node[i] = self.__dot(node[i], c)
		while i > 1:
			i //= 2
			node[i] = self.__dot(node[2 * i], node[2 * i + 1])

	def get(self, l, r):
		(vl, vr) = (self.__e, self.__e)
		l += self.__n
		r += self.__n
		while l < r:
			if l & 1:
				vl = self.__dot(vl, self.__node[l])
				l += 1
			l //= 2
			if r & 1:
				r -= 1
				vr = self.__dot(vr, self.__node[r])
			r //= 2
		return self.__dot(vl, vr)
(N, Q) = map(int, input().split())
query = [tuple(map(int, sys.stdin.readline().split())) for _ in range(Q)]
flagH = [N - 1] * N
flagW = [N - 1] * N
stH = SegmentTree([N - 1] * N, min, N - 1)
stW = SegmentTree([N - 1] * N, min, N - 1)
cnt = 0
for (t, x) in query:
	if t == 1:
		(flagX, flagY) = (flagW, flagH)
		(stX, stY) = (stW, stH)
	else:
		(flagX, flagY) = (flagH, flagW)
		(stX, stY) = (stH, stW)
	cnt += max(0, min(stX.get(x - 1, N), flagX[x - 1]) - 1)
	flagX[x - 1] = 0
	stY.update(stX.get(x - 1, N), x - 1)
print(pow(N - 2, 2) - cnt)


(n, q) = map(int, input().split())
c = [(n - 1, -1)]
r = [(n - 1, -1)]
t = 0
for i in range(q):
	(k, x) = map(int, input().split())
	if k == 1:
		c.append((x - 1, t))
	else:
		r.append((x - 1, t))
		t += 1
c.sort()
r.sort()
idx = 0
ans = (len(c) - 1) * r[0][0]
for i in range(len(r) - 1):
	(x, t) = r[i]
	tmp = idx
	while idx < len(c) and c[idx][1] > t:
		idx += 1
	ans += c[idx][0]
	ans += (len(c) - idx - 1) * (r[i + 1][0] - x)
print((n - 2) * (n - 2) - ans + len(c) + len(r) - 2)


(n, q) = map(int, input().split())
kuro = (n - 2) ** 2
nowy = n - 1
nowt = n - 1
yoko = [n - 1 for i in range(n - 1)]
tate = [n - 1 for i in range(n - 1)]
for _ in range(q):
	p = list(map(lambda x: int(x) - 1, input().split()))
	if p[0] == 0:
		if p[1] < nowt:
			kuro -= nowy - 1
			for i in range(p[1], nowt):
				yoko[i] = nowy
			nowt = p[1]
		elif p[1] > nowt:
			kuro -= yoko[p[1]] - 1
	elif p[0] == 1:
		if p[1] < nowy:
			kuro -= nowt - 1
			for i in range(p[1], nowy):
				tate[i] = nowt
			nowy = p[1]
		elif p[1] > nowy:
			kuro -= tate[p[1]] - 1
print(kuro)


(N, Q) = list(map(int, input().split()))
area_W = N - 2
area_H = N - 2
walls_H = []
walls_V = []
count = (N - 2) * (N - 2)

def bisearch_smallest(f, s, e=None):
	if e == None:
		e = s - 1
		s = 0
	else:
		e -= 1
	while s < e:
		m = (s + e) // 2
		if f(m):
			e = m
		else:
			s = m + 1
	if s == e and f(s):
		return s
	else:
		return -1
for _ in range(Q):
	(q, i) = input().split()
	i = int(i) - 2
	if q == '1':
		if i < area_W:
			area_W = i
			count -= area_H
			walls_H.append((i, area_H))
		else:
			j = bisearch_smallest(lambda j: walls_H[j][0] < i, 0, len(walls_H))
			count -= walls_H[j][1]
	elif i < area_H:
		area_H = i
		count -= area_W
		walls_V.append((i, area_W))
	else:
		j = bisearch_smallest(lambda j: walls_V[j][0] < i, 0, len(walls_V))
		count -= walls_V[j][1]
print(count)


(N, Q) = map(int, input().split())
q = [0] * Q
for i in range(Q):
	q[i] = list(map(int, input().split()))
ans = (N - 2) ** 2
b1 = [0] * (N - 2)
b2 = [0] * (N - 2)
l = N - 2
u = N - 2
for i in range(Q):
	x = q[i][1] - 2
	if q[i][0] == 1:
		if x < l:
			ans -= u
			for j in range(x + 1, l):
				b2[j] = u
			l = x
		else:
			ans -= b2[x]
	elif x < u:
		ans -= l
		for j in range(x + 1, u):
			b1[j] = l
		u = x
	else:
		ans -= b1[x]
print(ans)


import sys
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 18
MOD = 10 ** 9 + 7
input = lambda : sys.stdin.readline().rstrip()
YesNo = lambda b: bool([print('Yes')] if b else print('No'))
YESNO = lambda b: bool([print('YES')] if b else print('NO'))
int1 = lambda x: int(x) - 1
(N, Q) = map(int, input().split())

class RangeBIT:

	def __init__(self, n):
		self.p = self.BIT(n + 1)
		self.q = self.BIT(n + 1)

	def add(self, s, t, x):
		self.p.add(s, -x * s)
		self.p.add(t, x * t)
		self.q.add(s, x)
		self.q.add(t, -x)

	def sum(self, s, t):
		return self.p.sum(t) + self.q.sum(t) * t - self.p.sum(s) - self.q.sum(s) * s

	def f(self, i):
		return self.sum(i, i + 1)

	class BIT:

		def __init__(self, n):
			self.num = n
			self.dat = [0] * (self.num + 1)

		def add(self, i, x):
			i += 1
			while i <= self.num:
				self.dat[i] += x
				i += i & -i

		def sum(self, i):
			i += 1
			s = 0
			while i > 0:
				s += self.dat[i]
				i -= i & -i
			return s
(ly, lx) = (N - 1, N - 1)
(by, bx) = (RangeBIT(N), RangeBIT(N))
ans = 0
for _ in range(Q):
	(a, x) = map(int1, input().split())
	if a == 0:
		if x > lx:
			res = bx.f(x)
			ans += res
		else:
			ans += ly - 1
			bx.add(x, lx, ly - 1)
			lx = x
	elif x > ly:
		res = by.f(x)
		ans += res
	else:
		ans += lx - 1
		by.add(x, ly, lx - 1)
		ly = x
print((N - 2) ** 2 - ans)


(n, q) = map(int, input().split())
query = [list(map(int, input().split())) for _ in range(q)]
ans = (n - 2) ** 2
(c, wh) = ([n - 2, n - 2], [[None] * (n - 2), [None] * (n - 2)])
for (num, x) in query:
	(num, x) = (num - 1, x - 2)
	if c[num] > x:
		ans -= c[1 - num]
		for i in range(x, c[num]):
			wh[num][i] = c[1 - num]
		c[num] = x
	elif c[num] <= x:
		ans -= wh[num][x]
	wh[num][x] = 0
print(ans)


class SegmentTree:

	def __init__(self, data, default=0, func=max):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __delitem__(self, idx):
		self[idx] = self._default

	def __getitem__(self, idx):
		return self.data[idx + self._size]

	def __setitem__(self, idx, value):
		idx += self._size
		self.data[idx] = value
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self.data[2 * idx], self.data[2 * idx + 1])
			idx >>= 1

	def __len__(self):
		return self._len

	def query(self, start, stop):
		start += self._size
		stop += self._size
		res_left = res_right = self._default
		while start < stop:
			if start & 1:
				res_left = self._func(res_left, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res_right = self._func(self.data[stop], res_right)
			start >>= 1
			stop >>= 1
		return self._func(res_left, res_right)

	def __repr__(self):
		return 'SegmentTree({0})'.format(self.data)
import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
out = 0
stl = SegmentTree([n] * (n + 1), default=n, func=min)
st_r = SegmentTree([n] * (n + 1), default=n, func=min)
for _ in range(q):
	(t, x) = map(int, input().split())
	if t == 1:
		rFin = st_r.query(x, n + 1)
		out += rFin - 2
		stl[rFin] = min(stl[rFin], x)
	else:
		lFin = stl.query(x, n + 1)
		out += lFin - 2
		st_r[lFin] = min(st_r[lFin], x)
print((n - 2) * (n - 2) - out)


from bisect import bisect
(N, Q) = map(int, input().split())
ans = (N - 2) * (N - 2)
wx = wy = 0
Ax = []
Ay = []
for _ in range(Q):
	(t, p) = map(int, input().split())
	p = N - p
	if t == 1:
		i = bisect(Ax, (p, 0))
		if i == len(Ax):
			Ax.append((p, wy))
			wx = p
			rev = N - 2 - wy
		else:
			rev = N - 2 - Ax[i][1]
	else:
		i = bisect(Ay, (p, 0))
		if i == len(Ay):
			Ay.append((p, wx))
			wy = p
			rev = N - 2 - wx
		else:
			rev = N - 2 - Ay[i][1]
	ans -= rev
print(ans)


class F:

	def __init__(self, x):
		self.bit = x
		for i in range(len(x)):
			j = i | i + 1
			if j < len(x):
				x[j] += x[i]

	def update(self, idx, x):
		while idx < len(self.bit):
			self.bit[idx] += x
			idx |= idx + 1

	def query(self, end):
		x = 0
		while end:
			x += self.bit[end - 1]
			end &= end - 1
		return x

	def findkth(self, k):
		idx = -1
		for d in reversed(range(len(self.bit).bit_length())):
			right_idx = idx + (1 << d)
			if right_idx < len(self.bit) and k >= self.bit[right_idx]:
				idx = right_idx
				k -= self.bit[idx]
		return idx + 1
import sys
z = sys.stdin.readline
y = lambda : map(int, z().split())
(n, q) = y()
v = F([0] * (n - 2))
h = F([0] * (n - 2))
w = j = n - 2
s = 0
for _ in range(q):
	(a, b) = y()
	if a < 2:
		if b - 2 < w:
			h.update(n - 2 - j, w - b + 2)
			w = b - 2
		s += n - 2 - v.query(n - b)
	else:
		if b - 2 < j:
			v.update(n - 2 - w, j - b + 2)
			j = b - 2
		s += n - 2 - h.query(n - b)
print((n - 2) * (n - 2) - s)


(N, Q) = map(int, input().split())
ans = (N - 2) ** 2
H = [N for i in range(N + 1)]
W = [N for i in range(N + 1)]
last_ignored_H = N
last_ignored_W = N
ignoredH = [False for i in range(N + 1)]
ignoredH[N] = True
ignoredW = [False for i in range(N + 1)]
ignoredW[N] = True
for i in range(Q):
	(command, where) = map(int, input().split())
	if command == 1:
		if ignoredH[where] == True:
			ans -= H[where] - 2
			continue
		elif ignoredH[where] == False:
			H[where] = last_ignored_W
			ans -= H[where] - 2
			for j in range(where, last_ignored_H):
				ignoredH[j] = True
				H[j] = H[where]
			last_ignored_H = where
	elif ignoredW[where] == True:
		ans -= W[where] - 2
		continue
	elif ignoredW[where] == False:
		W[where] = last_ignored_H
		ans -= W[where] - 2
		for j in range(where, last_ignored_W):
			ignoredW[j] = True
			W[j] = W[where]
		last_ignored_W = where
print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip()

class LazySegmentTree:
	__slots__ = ['n', 'seg', 'x_unit', 'm_unit', 'f', 'g', 'h', 'lazy']

	def __init__(self, n, p, x_unit, m_unit, f, g, h):
		self.n = n
		self.seg = p * 2
		self.x_unit = x_unit
		self.m_unit = m_unit
		self.f = f
		self.g = g
		self.h = h
		for i in range(self.n - 1, 0, -1):
			self.seg[i] = self.f(self.seg[i << 1], self.seg[(i << 1) + 1])
		self.lazy = [m_unit] * (self.n * 2)

	def update(self, l, r, x):
		l += self.n
		r += self.n
		ll = l // (l & -l)
		rr = r // (r & -r) - 1
		for shift in range(ll.bit_length() - 1, 0, -1):
			i = ll >> shift
			self.lazy[i << 1] = self.h(self.lazy[i << 1], self.lazy[i])
			self.lazy[(i << 1) + 1] = self.h(self.lazy[(i << 1) + 1], self.lazy[i])
			self.seg[i] = self.g(self.seg[i], self.lazy[i])
			self.lazy[i] = self.m_unit
		for shift in range(rr.bit_length() - 1, 0, -1):
			i = rr >> shift
			self.lazy[i << 1] = self.h(self.lazy[i << 1], self.lazy[i])
			self.lazy[(i << 1) + 1] = self.h(self.lazy[(i << 1) + 1], self.lazy[i])
			self.seg[i] = self.g(self.seg[i], self.lazy[i])
			self.lazy[i] = self.m_unit
		while l < r:
			if l & 1:
				self.lazy[l] = self.h(self.lazy[l], x)
				l += 1
			if r & 1:
				r -= 1
				self.lazy[r] = self.h(self.lazy[r], x)
			l >>= 1
			r >>= 1
		while ll > 1:
			ll >>= 1
			self.seg[ll] = self.f(self.g(self.seg[ll << 1], self.lazy[ll << 1]), self.g(self.seg[(ll << 1) + 1], self.lazy[(ll << 1) + 1]))
			self.lazy[ll] = self.m_unit
		while rr > 1:
			rr >>= 1
			self.seg[rr] = self.f(self.g(self.seg[rr << 1], self.lazy[rr << 1]), self.g(self.seg[(rr << 1) + 1], self.lazy[(rr << 1) + 1]))
			self.lazy[rr] = self.m_unit

	def query(self, l, r):
		l += self.n
		r += self.n
		ll = l // (l & -l)
		rr = r // (r & -r) - 1
		for shift in range(ll.bit_length() - 1, 0, -1):
			i = ll >> shift
			self.lazy[i << 1] = self.h(self.lazy[i << 1], self.lazy[i])
			self.lazy[(i << 1) + 1] = self.h(self.lazy[(i << 1) + 1], self.lazy[i])
			self.seg[i] = self.g(self.seg[i], self.lazy[i])
			self.lazy[i] = self.m_unit
		for shift in range(rr.bit_length() - 1, 0, -1):
			i = rr >> shift
			self.lazy[i << 1] = self.h(self.lazy[i << 1], self.lazy[i])
			self.lazy[(i << 1) + 1] = self.h(self.lazy[(i << 1) + 1], self.lazy[i])
			self.seg[i] = self.g(self.seg[i], self.lazy[i])
			self.lazy[i] = self.m_unit
		ans_l = ans_r = self.x_unit
		while l < r:
			if l & 1:
				ans_l = self.f(ans_l, self.g(self.seg[l], self.lazy[l]))
				l += 1
			if r & 1:
				r -= 1
				ans_r = self.f(self.g(self.seg[r], self.lazy[r]), ans_r)
			l >>= 1
			r >>= 1
		return self.f(ans_l, ans_r)
(n, q) = map(int, input().split())

def f(x, y):
	return min(x, y)

def g(x, y):
	return min(x, y)

def h(x, y):
	return min(x, y)
up_seg = LazySegmentTree(n - 2, [n - 2] * (n - 2), n - 2, n - 2, f, g, h)
left_seg = LazySegmentTree(n - 2, [n - 2] * (n - 2), n - 2, n - 2, f, g, h)
ans = (n - 2) ** 2
for _ in range(q):
	(i, x) = map(int, input().split())
	x -= 2
	if i == 1:
		m = up_seg.query(x, x + 1)
		ans -= m
		left_seg.update(0, m, x)
	else:
		m = left_seg.query(x, x + 1)
		ans -= m
		up_seg.update(0, m, x)
print(ans)


class LazySegTree:

	def __init__(self, init_val, seg_ide, lazy_ide, segfunc):
		self.n = len(init_val)
		self.num = 2 ** (self.n - 1).bit_length()
		self.seg_ide = seg_ide
		self.lazy_ide = lazy_ide
		self.segfunc = segfunc
		self.seg = [seg_ide] * 2 * self.num
		for i in range(self.n):
			self.seg[i + self.num] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.seg[i] = self.segfunc(self.seg[2 * i], self.seg[2 * i + 1])
		self.lazy = [lazy_ide] * 2 * self.num

	def gindex(self, l, r):
		L = l + self.num
		R = r + self.num
		lm = L // (L & -L) >> 1
		rm = R // (R & -R) >> 1
		while L < R:
			if R <= rm:
				yield R
			if L <= lm:
				yield L
			L = L >> 1
			R = R >> 1
		while L:
			yield L
			L = L >> 1

	def propagate(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i]
			if v is None:
				continue
			self.lazy[2 * i] = self.lazy[2 * i + 1] = self.seg[2 * i] = self.seg[2 * i + 1] = v
			self.lazy[i] = None

	def update(self, l, r, x):
		(*ids,) = self.gindex(l, r)
		self.propagate(*ids)
		L = l + self.num
		R = r + self.num
		while L < R:
			if R & 1:
				R -= 1
				self.lazy[R] = self.seg[R] = x
			if L & 1:
				self.lazy[L] = self.seg[L] = x
				L += 1
			L = L >> 1
			R = R >> 1
		for i in ids:
			self.seg[i] = self.segfunc(self.seg[2 * i], self.seg[2 * i + 1])

	def query(self, l, r):
		if r <= l:
			return self.seg_ide
		self.propagate(*self.gindex(l, r))
		L = l + self.num
		R = r + self.num
		res = self.seg_ide
		while L < R:
			if R & 1:
				R -= 1
				res = self.segfunc(res, self.seg[R])
			if L & 1:
				res = self.segfunc(res, self.seg[L])
				L += 1
			L = L >> 1
			R = R >> 1
		return res

def segfunc(x, y):
	if x <= y:
		return x
	else:
		return y
INF = 10 ** 18
import sys
import io, os
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline

def main():
	(n, q) = map(int, input().split())
	R = LazySegTree([n - 1] * n, INF, None, segfunc)
	C = LazySegTree([n - 1] * n, INF, None, segfunc)
	ans = (n - 2) ** 2
	l = n
	u = n
	for i in range(q):
		(t, x) = map(int, input().split())
		x -= 1
		if t == 1:
			r = R.query(x, x + 1)
			ans -= r - 1
			if x < l:
				C.update(0, r + 1, x)
				l = x
		else:
			c = C.query(x, x + 1)
			ans -= c - 1
			if x < u:
				R.update(0, c + 1, x)
				u = x
	print(ans)
main()


import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
MOD = 1000000007

def main():
	(N, Q, *queries) = map(int, read().split())
	queries = [(q, x) for (q, x) in zip(*[iter(queries)] * 2)]
	N -= 2
	N0 = 2 ** (N - 1).bit_length()
	data1 = [None] * (2 * N0)
	data2 = [None] * (2 * N0)
	INF = (-1, 2 ** 31 - 1)

	def update(l, r, v, data):
		L = l + N0
		R = r + N0
		while L < R:
			if R & 1:
				R -= 1
				data[R - 1] = v
			if L & 1:
				data[L - 1] = v
				L += 1
			L >>= 1
			R >>= 1

	def _query(k, data):
		k += N0 - 1
		s = INF
		while k >= 0:
			if data[k]:
				s = max(s, data[k])
			k = (k - 1) // 2
		return s

	def query(k, data):
		return _query(k, data)[1]
	update(0, N, (0, N), data1)
	update(0, N, (0, N), data2)
	min1 = min2 = N + 10
	ans = N * N
	for (i, (q, x)) in enumerate(queries, 1):
		x -= 2
		if q == 1:
			data = data1
			this_min = min1
		else:
			data = data2
			this_min = min2
		n = query(x, data)
		ans -= n
		if x > this_min:
			continue
		if q == 1:
			min1 = x
			update(0, n, (i, x), data2)
		else:
			min2 = x
			update(0, n, (i, x), data1)
	print(ans)
	return
main()


import sys
input = sys.stdin.readline
(N, Q) = map(int, input().split())
row = [-1 for i in range(N + 1)]
column = [-1 for i in range(N + 1)]
R = N
C = N
res = (N - 2) ** 2
for _ in range(Q):
	(t, x) = map(int, input().split())
	if t == 1:
		if column[x] == -1:
			for i in range(x, N + 1):
				if column[i] == -1:
					column[i] = R
				else:
					break
			res -= column[x] - 2
		else:
			res -= column[x] - 2
		if x <= C:
			C = x
	else:
		if row[x] == -1:
			for i in range(x, N + 1):
				if row[i] == -1:
					row[i] = C
				else:
					break
			res -= row[x] - 2
		else:
			res -= row[x] - 2
		if x <= R:
			R = x
print(res)


import sys
import math
from collections import defaultdict, deque, Counter
from copy import deepcopy
from bisect import bisect, bisect_right, bisect_left
from heapq import heapify, heappop, heappush
input = sys.stdin.readline

def RD():
	return input().rstrip()

def F():
	return float(input().rstrip())

def I():
	return int(input().rstrip())

def MI():
	return map(int, input().split())

def MF():
	return map(float, input().split())

def LI():
	return list(map(int, input().split()))

def TI():
	return tuple(map(int, input().split()))

def LF():
	return list(map(float, input().split()))

def Init(H, W, num):
	return [[num for i in range(W)] for j in range(H)]

class BIT:

	def __init__(self, n):
		self.n = n
		self.bit = [0] * (n + 1)

	def add(self, i, x):
		while i <= self.n:
			self.bit[i] += x
			i += i & -i

	def sum(self, i):
		s = 0
		while i > 0:
			s += self.bit[i]
			i -= i & -i
		return s

	def rangesum(self, i, k):
		return self.sum(k) - self.sum(i)

	def lower_bound(self, x):
		if x <= 0:
			return 0
		else:
			i = 0
			r = 1
			while r < self.n:
				r = r << 1
			len = r
			while len > 0:
				if i + len < self.n and self.bit[i + len] < x:
					x -= self.bit[i + len]
					i += len
				len = len >> 1
			return i + 1

def main():
	(N, Q) = MI()
	(X, Y) = (BIT(N), BIT(N))
	xmin = N - 2
	ymin = N - 2
	X.add(1, N - 2)
	X.add(N - 1, -(N - 2))
	Y.add(1, N - 2)
	Y.add(N - 1, -(N - 2))
	res = (N - 2) ** 2
	for i in range(Q):
		(a, b) = MI()
		if a == 1:
			x = X.sum(b - 1)
			if ymin > b - 2:
				temp = Y.sum(1)
				Y.add(1, b - 2 - temp)
				Y.add(xmin + 1, -(b - 2 - temp))
				ymin = b - 2
			res -= x
		else:
			y = Y.sum(b - 1)
			if xmin > b - 2:
				temp = X.sum(1)
				X.add(1, b - 2 - temp)
				X.add(ymin + 1, -(b - 2 - temp))
				xmin = b - 2
			res -= y
	print(res)
main()


import sys
input = sys.stdin.readline

def func(x, y):
	return min(x, y)

class LazySegmentTree:

	def __init__(self, n):
		self.lv = (n - 1).bit_length()
		self.n = 2 ** self.lv
		self.arr = [2 ** 31 - 1] * (2 * self.n - 1)
		self.lazy = [None] * (2 * self.n - 1)

	def getidx(self, l, r):
		L = l + self.n >> 1
		R = r + self.n >> 1
		lc = 0 if l & 1 else (L & -L).bit_length()
		rc = 0 if r & 1 else (R & -R).bit_length()
		for i in range(self.lv):
			if rc <= i:
				yield R
			if L < R and lc <= i:
				yield L
			L >>= 1
			R >>= 1

	def propagate(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i - 1]
			if v is None:
				continue
			self.lazy[2 * i - 1] = self.arr[2 * i - 1] = self.lazy[2 * i] = self.arr[2 * i] = v
			self.lazy[i - 1] = None

	def update(self, l, r, x):
		r += 1
		(*ids,) = self.getidx(l, r)
		self.propagate(*ids)
		L = self.n + l
		R = self.n + r
		while L < R:
			if R & 1:
				R -= 1
				self.lazy[R - 1] = self.arr[R - 1] = x
			if L & 1:
				self.lazy[L - 1] = self.arr[L - 1] = x
				L += 1
			L >>= 1
			R >>= 1
		for i in ids:
			self.arr[i - 1] = func(self.arr[2 * i - 1], self.arr[2 * i])

	def query(self, l, r):
		r += 1
		self.propagate(*self.getidx(l, r))
		L = self.n + l
		R = self.n + r
		s = 2 ** 31 - 1
		while L < R:
			if R & 1:
				R -= 1
				s = func(s, self.arr[R - 1])
			if L & 1:
				s = func(s, self.arr[L - 1])
				L += 1
			L >>= 1
			R >>= 1
		return s

def main():
	(n, q) = map(int, input().split())
	row = LazySegmentTree(n - 2)
	col = LazySegmentTree(n - 2)
	row.update(0, n - 3, n - 2)
	col.update(0, n - 3, n - 2)
	ans = (n - 2) ** 2
	for _ in range(q):
		que = list(map(int, input().split()))
		pos = que[1] - 2
		if que[0] == 1:
			num = row.query(pos, pos)
			ans -= num
			num2 = col.query(0, 0)
			if num2 > pos:
				col.update(0, num - 1, pos)
		else:
			num = col.query(pos, pos)
			ans -= num
			num2 = row.query(0, 0)
			if num2 > pos:
				row.update(0, num - 1, pos)
	print(ans)
main()


import sys
input = sys.stdin.buffer.readline

class LazySegmentTree:

	def __init__(self, n, unitX, unitA, X_f, A_f, XA_map):
		self.n = n
		self.unitX = unitX
		self.unitA = unitA
		self.X_f = X_f
		self.A_f = A_f
		self.XA_map = XA_map
		self.X = [unitX] * (n + n)
		self.A = [unitA] * (n + n)

	def __getitem__(self, i):
		i += self.n
		self._propagate_above(i)
		return self.X[i]

	def __setitem__(self, i, x):
		i += self.n
		self._propagate_above(i)
		self.X[i] = x
		self._calc_above(i)

	def build(self, array):
		for (i, val) in enumerate(array, self.n):
			self.X[i] = val
		for i in range(self.n - 1, 0, -1):
			self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])

	def _calc_above(self, i):
		while i > 1:
			i >>= 1
			self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])

	def _propagate_above(self, i):
		k = i >> 1
		H = k.bit_length() - 1
		for h in range(H, -1, -1):
			i = k >> h
			if self.A[i] == self.unitA:
				continue
			self.X[i << 1] = self.XA_map(self.X[i << 1], self.A[i])
			self.X[i << 1 | 1] = self.XA_map(self.X[i << 1 | 1], self.A[i])
			self.A[i << 1] = self.A_f(self.A[i << 1], self.A[i])
			self.A[i << 1 | 1] = self.A_f(self.A[i << 1 | 1], self.A[i])
			self.A[i] = self.unitA

	def fold(self, l, r):
		l += self.n
		r += self.n
		(l0, r0) = (l // (l & -l), r // (r & -r) - 1)
		self._propagate_above(l0)
		self._propagate_above(r0)
		xl = self.unitX
		xr = self.unitX
		while l < r:
			if l & 1:
				xl = self.X_f(xl, self.X[l])
				l += 1
			if r & 1:
				r -= 1
				xr = self.X_f(self.X[r], xr)
			l >>= 1
			r >>= 1
		return self.X_f(xl, xr)

	def apply(self, i, a):
		i += self.n
		self._propagate_above(i)
		self.X[i] = self.XA_map(self.X[i], a)
		self.A[i] = self.A_f(self.A[i], a)
		self._calc_above(i)

	def apply_range(self, l, r, a):
		l += self.n
		r += self.n
		(l0, r0) = (l // (l & -l), r // (r & -r) - 1)
		self._propagate_above(l0)
		self._propagate_above(r0)
		while l < r:
			if l & 1:
				self.X[l] = self.XA_map(self.X[l], a)
				self.A[l] = self.A_f(self.A[l], a)
				l += 1
			if r & 1:
				r -= 1
				self.X[r] = self.XA_map(self.X[r], a)
				self.A[r] = self.A_f(self.A[r], a)
			l >>= 1
			r >>= 1
		self._calc_above(l0)
		self._calc_above(r0)
(n, q) = map(int, input().split())
queries = [list(map(int, input().split())) for i in range(q)]
INF = 10 ** 18
nokori_1 = LazySegmentTree(n, INF, INF, min, min, min)
nokori_2 = LazySegmentTree(n, INF, INF, min, min, min)
nokori_1.build([n - 2] * n)
nokori_2.build([n - 2] * n)
ans = (n - 2) * (n - 2)
for (flag, x) in queries:
	x -= 1
	if flag == 1:
		ans -= nokori_1[x]
		nokori_2.apply_range(0, nokori_1[x] + 1, x - 1)
		nokori_1[x] = 0
	else:
		ans -= nokori_2[x]
		nokori_1.apply_range(0, nokori_2[x] + 1, x - 1)
		nokori_2[x] = 0
print(ans)


import os
import io
input = io.BytesIO(os.read(0, os.fstat(0).st_size)).readline
(n, q) = list(map(int, input().split()))
count = (n - 2) ** 2
c = [n] * (n + 1)
r = [n] * (n + 1)
mc = n
mr = n
for _ in range(q):
	(m, q) = list(map(int, input().split()))
	if m == 1:
		if q <= mc:
			count -= mr - 2
			for p in range(q + 1, mc):
				c[p] = mr
			c[q] = 0
			mc = q
		else:
			count -= c[q] - 2
	elif q <= mr:
		count -= mc - 2
		for p in range(q + 1, mr):
			r[p] = mc
		r[q] = 0
		mr = q
	else:
		count -= r[q] - 2
print(count)


(n, q) = list(map(int, input().split()))
black = (n - 2) ** 2
left_most = n - 1
down_most = n - 1
L = [n - 2] * n
D = [n - 2] * n
for _ in range(q):
	(x, c) = list(map(int, input().split()))
	c -= 1
	if x == 1:
		if c < left_most:
			for j in range(c, left_most):
				D[j] = down_most - 1
			left_most = c
		black -= D[c]
	if x == 2:
		if c < down_most:
			for j in range(c, down_most):
				L[j] = left_most - 1
			down_most = c
		black -= L[c]
print(black)


import sys
input = sys.stdin.readline
(N, Q) = map(int, input().split())

class SegTree:

	def segfunc(self, x, y):
		return min(x, y)

	def __init__(self, n, ide_ele, init_val):
		self.ide_ele = ide_ele
		self.num = 2 ** (n - 1).bit_length()
		self.seg = [self.ide_ele] * 2 * self.num
		for i in range(n):
			self.seg[i + self.num - 1] = init_val[i]
		for i in range(self.num - 2, -1, -1):
			self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

	def update(self, k, x):
		k += self.num - 1
		self.seg[k] = x
		while k + 1:
			k = (k - 1) // 2
			self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

	def query(self, p, q):
		if q <= p:
			return self.ide_ele
		p += self.num - 1
		q += self.num - 2
		res = self.ide_ele
		while q - p > 1:
			if p & 1 == 0:
				res = self.segfunc(res, self.seg[p])
			if q & 1 == 1:
				res = self.segfunc(res, self.seg[q])
				q -= 1
			p = p // 2
			q = (q - 1) // 2
		if p == q:
			res = self.segfunc(res, self.seg[p])
		else:
			res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
		return res
lseg = SegTree(N, N, [N] * N)
useg = SegTree(N, N, [N] * N)
res = (N - 2) * (N - 2)
for _ in range(Q):
	(q, x) = map(int, input().split())
	x -= 1
	if q == 1:
		u = useg.query(x, N)
		res -= u - 2
		l = lseg.query(u - 1, u)
		lseg.update(u - 1, min(l, x + 1))
	else:
		l = lseg.query(x, N)
		res -= l - 2
		u = useg.query(l - 1, l)
		useg.update(l - 1, min(u, x + 1))
print(res)


import sys
readline = sys.stdin.readline

class Dualsegtree:

	def __init__(self, A, intv, initialize=True):
		self.N = len(A)
		self.N0 = 2 ** (self.N - 1).bit_length()
		self.intv = intv
		if initialize:
			self.data = [intv] * self.N0 + A + [intv] * (self.N0 - self.N)
			for i in range(self.N0 - 1, 0, -1):
				self.data[i] = self.segf(self.data[2 * i], self.data[2 * i + 1])
		else:
			self.data = [intv] * (2 * self.N0)

	def segf(self, a, b):
		return min(a, b)

	def query(self, k):
		k += self.N0
		s = self.data[k]
		while k > 0:
			k >>= 1
			s = self.segf(s, self.data[k])
		return s

	def update(self, l, r, x):
		(L, R) = (l + self.N0, r + self.N0)
		while L < R:
			if R & 1:
				R -= 1
				self.data[R] = x
			if L & 1:
				self.data[L] = x
				L += 1
			L >>= 1
			R >>= 1
(N, Q) = map(int, readline().split())
INF = 10 ** 9 + 7
(H, W) = (Dualsegtree([N - 1] * (N - 1), INF, initialize=True), Dualsegtree([N - 1] * (N - 1), INF, initialize=True))
ans = 0
mw = N
mb = N
for _ in range(Q):
	(t, x) = map(int, readline().split())
	x -= 1
	if t == 1:
		st = H.query(x)
		ans += st - 1
		if mw > x:
			mw = x
			W.update(0, st, x)
	else:
		st = W.query(x)
		ans += st - 1
		if mb > x:
			mb = x
			H.update(0, st, x)
print((N - 2) * (N - 2) - ans)


import sys
input = sys.stdin.buffer.readline
(n, q) = map(int, input().split())

class SegmentTree:
	ele = 10 ** 10
	func = min

	def __init__(self, n):
		self.n = n
		self.num = 2 ** (self.n - 1).bit_length()
		self.SEG = [self.ele] * (2 * self.num)

	def search(self, idx):
		return self.SEG[idx + self.num]

	def initialize(self, A):
		for i in range(self.n):
			self.SEG[i + self.num] = A[i]
		for i in range(self.num - 1, 0, -1):
			self.SEG[i] = self.func(self.SEG[2 * i], self.SEG[2 * i + 1])

	def update(self, idx, val):
		idx += self.num
		self.SEG[idx] = val
		idx //= 2
		while idx:
			self.SEG[idx] = self.func(self.SEG[2 * idx], self.SEG[2 * idx + 1])
			idx //= 2

	def query(self, left, right):
		resleft = self.ele
		resright = self.ele
		left += self.num
		right += self.num
		while right - left > 0:
			if left % 2 == 1:
				resleft = self.func(resleft, self.SEG[left])
				left += 1
			if right % 2 == 1:
				right -= 1
				resright = self.func(resright, self.SEG[right])
			left //= 2
			right //= 2
		return self.func(resleft, resright)
ans = 0
tate = SegmentTree(n)
yoko = SegmentTree(n)
for i in range(q):
	(s, x) = map(int, input().split())
	x -= 1
	if s == 1:
		temp = tate.query(x, n)
		if temp == 10 ** 10:
			temp = n - 1
		now = yoko.search(temp)
		now = min(now, x)
		yoko.update(temp, now)
		ans += max(0, temp - 1)
	else:
		temp = yoko.query(x, n)
		if temp == 10 ** 10:
			temp = n - 1
		now = tate.search(temp)
		now = min(now, x)
		tate.update(temp, now)
		ans += max(0, temp - 1)
print((n - 2) ** 2 - ans)


import math
import itertools
from collections import deque
from collections import Counter
import heapq
import bisect
(n, q) = map(int, input().split())
tate = [n] * (n + 1)
yoko = [n] * (n + 1)
black = (n - 2) * (n - 2)
h = n
w = n
for i in range(q):
	(ty, x) = map(int, input().split())
	if ty == 1:
		if x <= w:
			black -= h - 2
			for j in range(w - 1, x, -1):
				tate[j] = h
			w = x
			tate[x] = 0
		else:
			black -= tate[x] - 2
	elif x <= h:
		black -= w - 2
		for j in range(h - 1, x, -1):
			yoko[j] = w
		h = x
		yoko[x] = 0
	else:
		black -= yoko[x] - 2
print(black)


class SegmentTree:

	def __init__(self, N):
		self.N0 = 2 ** (N - 1).bit_length()
		self.data = [None] * (2 * self.N0)
		self.INF = (-1, 2 ** 31 - 1)

	def update(self, l, r, v):
		L = l + self.N0
		R = r + self.N0
		while L < R:
			if R & 1:
				R -= 1
				self.data[R - 1] = v
			if L & 1:
				self.data[L - 1] = v
				L += 1
			L >>= 1
			R >>= 1

	def _query(self, k):
		k += self.N0 - 1
		s = self.INF
		while k >= 0:
			if self.data[k]:
				s = max(s, self.data[k])
			k = (k - 1) // 2
		return s

	def query(self, k):
		return self._query(k)[1]
(N, Q) = map(int, input().split())
row = SegmentTree(N - 2)
col = SegmentTree(N - 2)
ans = (N - 2) * (N - 2)
row.update(0, N - 2, (0, N - 2))
col.update(0, N - 2, (0, N - 2))
min_row = N
min_col = N
for i in range(1, Q + 1):
	(t, x) = map(int, input().split())
	if t == 1:
		num = col.query(x - 2)
		ans -= num
		if x < min_col:
			row.update(0, num, (i, x - 2))
			min_col = x
	else:
		num = row.query(x - 2)
		ans -= num
		if x < min_row:
			col.update(0, num, (i, x - 2))
			min_row = x
print(ans)


(n, Q) = [int(i) for i in input().split(' ')]
deepx = [-1] * (n - 2)
deepy = [-1] * (n - 2)
queries = [[0, 0] for i in range(Q)]
for i in range(Q):
	queries[i] = [int(j) for j in input().split(' ')]
curx = n - 2
cury = n - 2
ans = 0
for q in queries:
	d = q[0]
	pos = q[1] - 2
	if d == 1:
		if curx < pos:
			ans += deepx[pos]
		else:
			ans += cury
			for i in range(pos + 1, curx):
				deepx[i] = cury
			curx = pos
	elif cury < pos:
		ans += deepy[pos]
	else:
		ans += curx
		for i in range(pos + 1, cury):
			deepy[i] = curx
		cury = pos
print((n - 2) ** 2 - ans)


def segfunc(x, y):
	return min(x, y)
ide_ele = 10 ** 18

class segtree:

	def __init__(self, init_val, segfunc=segfunc, ide_ele=ide_ele):
		n = len(init_val)
		self.segfunc = segfunc
		self.ide_ele = ide_ele
		self.num = 1 << (n - 1).bit_length()
		self.tree = [ide_ele] * 2 * self.num
		for i in range(n):
			self.tree[self.num + i] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

	def update(self, k, x):
		k += self.num
		self.tree[k] = x
		while k > 1:
			self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
			k >>= 1

	def query(self, l, r):
		res = self.ide_ele
		l += self.num
		r += self.num + 1
		while l < r:
			if l & 1:
				res = self.segfunc(res, self.tree[l])
				l += 1
			if r & 1:
				res = self.segfunc(res, self.tree[r - 1])
			l >>= 1
			r >>= 1
		return res
(n, q) = map(int, input().split())
stx = segtree([ide_ele] * n)
sty = segtree([ide_ele] * n)
stx.update(n - 1, n - 2)
sty.update(n - 1, n - 2)
ans = (n - 2) * (n - 2)
for _ in range(q):
	(x, y) = map(int, input().split())
	if x == 1:
		x = stx.query(y - 1, n)
		ans -= x
		sty.update(x, min(y - 2, sty.query(x, n)))
	else:
		x = sty.query(y - 1, n)
		ans -= x
		stx.update(x, min(y - 2, stx.query(x, n)))
print(ans)


(n, q) = map(int, input().split())
ans = (n - 2) ** 2
rm = n
um = n
ruse = [-1] * (n + 1)
uuse = [-1] * (n + 1)
for _ in range(q):
	(a, x) = map(int, input().split())
	if a == 1:
		if uuse[x] >= 0:
			ans -= uuse[x] - 2
		else:
			dif = um - 2
			ans -= dif
			for i in range(x, n + 1):
				if uuse[i] >= 0:
					break
				uuse[i] = um
			rm = min(rm, x)
	elif ruse[x] >= 0:
		ans -= ruse[x] - 2
	else:
		dif = rm - 2
		ans -= dif
		for i in range(x, n + 1):
			if ruse[i] >= 0:
				break
			ruse[i] = rm
		um = min(um, x)
print(ans)


ma = lambda : map(int, input().split())
lma = lambda : list(map(int, input().split()))
tma = lambda : tuple(map(int, input().split()))
ni = lambda : int(input())
yn = lambda fl: print('Yes') if fl else print('No')
ips = lambda : input().split()
import collections
import math
import itertools
import heapq as hq
(n, q) = ma()
black = [[n - 2] * (n + 1) for i in range(2)]
inner = [n, n]
innerbl = [n - 2, n - 2]
ans = (n - 2) ** 2
for _ in range(q):
	(t, x) = ma()
	t -= 1
	if x > inner[t]:
		ans -= black[t][x]
	elif x < inner[t]:
		ans -= innerbl[t]
		innerbl[1 - t] = x - 2
		for i in range(x, inner[t]):
			black[t][i] = innerbl[t]
		inner[t] = x
print(ans)


import sys
sysread = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
printout = sys.stdout.write
sprint = sys.stdout.flush
sys.setrecursionlimit(10 ** 7)
import math
INF = 1 << 50
EPS = 1e-08
mod = 998244353

def intread():
	return int(sysread())

def mapline(t=int):
	return map(t, sysread().split())

def mapread(t=int):
	return map(t, read().split())

class segtree:

	def __init__(self, n, init=0, init_val=None):
		self.n = n
		self.init = init
		self.k = math.ceil(math.log2(n))
		self.add_val = 1 << self.k
		self.bins = [self.init] * (1 << self.k + 1)
		if init_val != None:
			self.update_set(init_val)
		self.caliculate()

	def __getitem__(self, idx):
		return self.bins[idx + self.add_val]

	def update_set(self, vals):
		for (idx, i) in enumerate(range(self.add_val, self.add_val * 2)):
			if len(vals) > idx:
				self.bins[i] = vals[idx]
			else:
				continue

	def compare(self, l, r):
		return min(l, r)

	def caliculate(self):
		k = self.k
		while k:
			for i in range(1 << k, 1 << k + 1):
				if not i % 2:
					self.bins[i // 2] = self.compare(self.bins[i], self.bins[i + 1])
				else:
					continue
			k -= 1

	def update(self, idx, val, by=True):
		k = (1 << self.k) + idx
		if by:
			self.bins[k] += val
		else:
			self.bins[k] = val
		while k > 1:
			self.bins[k // 2] = self.compare(self.bins[k // 2 * 2], self.bins[k // 2 * 2 + 1])
			k = k // 2

	def eval(self, l, r):
		if l == r:
			return self.bins[l + self.add_val]
		ret = self.init
		l = (1 << self.k) + l
		r = (1 << self.k) + r
		while True:
			if r - l == 1:
				ret = self.compare(ret, self.bins[l])
				ret = self.compare(ret, self.bins[r])
				break
			elif l == r:
				ret = self.compare(ret, self.bins[l])
				break
			else:
				done = False
				if l % 2:
					ret = self.compare(ret, self.bins[l])
					l += 1
					done = True
				if not r % 2:
					ret = self.compare(ret, self.bins[r])
					r -= 1
					done = True
				if not done:
					l = l // 2
					r = r // 2
		return ret

def run():
	(N, Q) = mapline()
	X = segtree(N + 1, init=INF)
	Y = segtree(N + 1, init=INF)
	sub = 0
	for _ in range(Q):
		(q, x) = mapline()
		x -= 1
		if q == 1:
			v = X.eval(x, N - 2)
			if v == INF:
				sub += N - 2
				if Y[N - 2] > x:
					Y.update(N - 2, x, by=False)
			else:
				sub += v - 1
				if Y[v] > x:
					Y.update(v, x, by=False)
		else:
			v = Y.eval(x, N - 2)
			if v == INF:
				sub += N - 2
				if X[N - 2] > x:
					X.update(N - 2, x, by=False)
			else:
				sub += v - 1
				if X[v] > x:
					X.update(v, x, by=False)
	print((N - 2) ** 2 - sub)
run()


(n, q) = list(map(int, input().split()))
n -= 2
(R, C) = ([None] * n, [None] * n)
(h, w) = (n, n)
a = n ** 2
for _ in range(q):
	(t, x) = list(map(int, input().split()))
	x -= 2
	if t == 1:
		for i in range(x, h):
			R[i] = w
		h = min(h, x)
		a -= R[x]
	if t == 2:
		for j in range(x, w):
			C[j] = h
		w = min(w, x)
		a -= C[x]
print(a)


(n, q) = list(map(int, input().split()))
query = [list(map(int, input().split())) for _ in range(q)]
INF = 10 ** 9
keys = ['verticle', 'horizion']
become_white = {key: [-1] * (n + 1) for key in keys}
for key in keys:
	become_white[key][-1] = INF
base = {key: n - 1 for key in keys}
white = 2 * n - 1
for (num, x) in query:
	if num == 1:
		(i, j) = keys
	else:
		(j, i) = keys
	if become_white[i][x] == -1:
		white += base[i]
		k = x
		while become_white[i][k] == -1:
			become_white[i][k] = base[i]
			k += 1
	else:
		white += become_white[i][x]
	base[j] = min(base[j], x - 1)
stone_sum = (n - 2) * (n - 2) + 2 * n - 1 + q
ans = stone_sum - white
print(ans)


import bisect, collections, copy, heapq, itertools, math, string
import sys

def I():
	return int(sys.stdin.readline().rstrip())

def MI():
	return map(int, sys.stdin.readline().rstrip().split())

def LI():
	return list(map(int, sys.stdin.readline().rstrip().split()))

def S():
	return sys.stdin.readline().rstrip()

def LS():
	return list(sys.stdin.readline().rstrip().split())
from collections import deque
from collections import Counter
import bisect
from collections import defaultdict
import itertools

def main():
	(N, Q) = MI()
	line_right = deque([(N, N)])
	line_right_keys = deque([N])
	column_under = deque([(N, N)])
	column_under_keys = deque([N])
	bla = pow(N - 2, 2)
	x_min = N
	y_min = N
	for i in range(Q):
		query = LI()
		if query[0] == 1:
			w = query[1]
			x = bisect.bisect_left(column_under_keys, w)
			bla -= column_under[x][1] - 2
			if w < x_min:
				line_right.appendleft((column_under[x][1], w))
				line_right_keys.appendleft(column_under[x][1])
				x_min = w
		else:
			y = query[1]
			z = bisect.bisect_left(line_right_keys, y)
			bla -= line_right[z][1] - 2
			if y < y_min:
				column_under.appendleft((line_right[z][1], y))
				column_under_keys.appendleft(line_right[z][1])
				y_min = y
	print(bla)
main()


class SegTree:
	X_unit = 1 << 30
	X_f = min

	def __init__(self, N):
		self.N = N
		self.X = [self.X_unit] * (N + N)

	def build(self, seq):
		for (i, x) in enumerate(seq, self.N):
			self.X[i] = x
		for i in range(self.N - 1, 0, -1):
			self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])

	def set_val(self, i, x):
		i += self.N
		self.X[i] = x
		while i > 1:
			i >>= 1
			self.X[i] = self.X_f(self.X[i << 1], self.X[i << 1 | 1])

	def fold(self, L, R):
		L += self.N
		R += self.N
		vL = self.X_unit
		vR = self.X_unit
		while L < R:
			if L & 1:
				vL = self.X_f(vL, self.X[L])
				L += 1
			if R & 1:
				R -= 1
				vR = self.X_f(self.X[R], vR)
			L >>= 1
			R >>= 1
		return self.X_f(vL, vR)
(N, Q) = map(int, input().split())
S1 = SegTree(N)
S2 = SegTree(N)
S1.build([N] * N)
S2.build([N] * N)
ans = (N - 2) ** 2
for i in range(Q):
	(j, x) = map(int, input().split())
	if j == 1:
		l = S2.fold(x - 1, N)
		ans -= l - 2
		S1.set_val(l - 1, min(x, S1.X[l - 1 + N]))
	if j == 2:
		l = S1.fold(x - 1, N)
		ans -= l - 2
		S2.set_val(l - 1, min(x, S2.X[l - 1 + N]))
print(ans)


from collections import deque
from bisect import bisect_left

def main():
	(N, Q) = map(int, input().split())
	Query = [tuple(map(int, input().split())) for _ in range(Q)]
	LX = 1
	X = deque([N])
	VX = deque([N])
	LY = 1
	Y = deque([N])
	VY = deque([N])
	mx = N
	my = N
	ans = 0
	for (i, x) in Query:
		if i == 1:
			if x < my:
				ans += mx - 2
				X.appendleft(x)
				VX.appendleft(mx)
				my = x
			else:
				ans += VX[bisect_left(X, x) - 1] - 2
		elif x < mx:
			ans += my - 2
			Y.appendleft(x)
			VY.appendleft(my)
			mx = x
		else:
			ans += VY[bisect_left(Y, x) - 1] - 2
	print((N - 2) ** 2 - ans)
main()


from functools import reduce
from fractions import gcd
import math
import bisect
import itertools
import sys
input = sys.stdin.readline
INF = float('inf')

def main():
	(N, Q) = map(int, input().split())
	h = N
	w = N
	a = [N] * N
	b = [N] * N
	ans = (N - 2) ** 2
	for _ in range(Q):
		(q, x) = map(int, input().split())
		if q == 1:
			if x < w:
				for i in range(x, w):
					b[i] = h
				w = x
			ans -= b[x] - 2
		elif q == 2:
			if x < h:
				for i in range(x, h):
					a[i] = w
				h = x
			ans -= a[x] - 2
	print(ans)
main()


import sys

def input():
	return sys.stdin.readline().strip()

class SegTree:

	def __init__(self, N):
		self.id_elem = 10 ** 10
		self.func = min
		self.num_max = 2 ** (N - 1).bit_length()
		self.x = [self.id_elem] * (2 * self.num_max - 1)

	def get_elem(self, i):
		return self.x[self.num_max + i - 1]

	def update(self, i, x):
		i += self.num_max - 1
		self.x[i] = x
		while i > 0:
			i = (i - 1) // 2
			self.x[i] = self.func(self.x[i * 2 + 1], self.x[i * 2 + 2])

	def query(self, i=0, j=-1, k=0, l=0, r=-1):
		if j == -1:
			j = self.num_max
		if r == -1:
			r = self.num_max
		if r <= i or j <= l:
			return self.id_elem
		if i <= l and r <= j:
			return self.x[k]
		vl = self.query(i, j, k * 2 + 1, l, (l + r) // 2)
		vr = self.query(i, j, k * 2 + 2, (l + r) // 2, r)
		return self.func(vl, vr)

def main():
	(N, Q) = map(int, input().split())
	black = (N - 2) * (N - 2)
	tree_width = SegTree(N)
	tree_height = SegTree(N)
	tree_width.update(N - 2, N - 2)
	tree_height.update(N - 2, N - 2)
	reversed = 0
	for _ in range(Q):
		(q, x) = map(int, input().split())
		x -= 1
		if q == 1:
			new_reversed = tree_width.query(x, N)
			if tree_height.query(new_reversed, N) > x - 1:
				tree_height.update(new_reversed, x - 1)
		else:
			new_reversed = tree_height.query(x, N)
			if tree_width.query(new_reversed, N) > x - 1:
				tree_width.update(new_reversed, x - 1)
		reversed += new_reversed
	print((N - 2) * (N - 2) - reversed)
main()


from bisect import bisect_left, bisect_right
(N, Q) = map(int, input().split())
ans = 0
tate = [[-N, N - 2]]
tateL = 1
yoko = [[-N, N - 2]]
yokoL = 1
ans = (N - 2) * (N - 2)
for _ in range(Q):
	(s, x) = input().split()
	x = int(x)
	if s == '1':
		idx = bisect_left(tate, [-x, 0])
		ans -= tate[idx - 1][1]
		if idx == tateL:
			tate.append([-x, tate[idx - 1][1]])
			tateL += 1
			yoko[-1][1] = x - 2
	else:
		idx = bisect_left(yoko, [-x, 0])
		ans -= yoko[idx - 1][1]
		if idx == yokoL:
			yoko.append([-x, yoko[idx - 1][1]])
			yokoL += 1
			tate[-1][1] = x - 2
print(ans)


import sys
from math import factorial
MOD = 10 ** 9 + 7
INF = 10000000000

def binary_search(list, item):
	mode = 2
	low = 0
	high = len(list) - 1
	upper = len(list) - 1
	lower = 0
	while low <= high:
		mid = (low + high) // 2
		guess = list[mid]
		if guess == item:
			return mid
		if guess > item:
			high = mid - 1
			upper = mid
		else:
			low = mid + 1
			lower = mid
	if mode == 1:
		return upper
	elif mode == 2:
		return lower

def main():
	(N, Q) = list(map(int, input().split()))
	queList = [list(map(int, input().split())) for _ in range(Q)]
	black = (N - 2) ** 2
	m = [N, N]
	chList = [[-1] * N for _ in range(2)]
	for que in queList:
		x = que[1]
		y = que[0] - 1
		ch = chList[y][x]
		if ch == -1:
			ch = m[1 - y] - 2
			m[y] = x
			i = 0
			while x + i <= N - 1 and chList[y][x + i] == -1:
				chList[y][x + i] = m[1 - y] - 2
				i = i + 1
		black -= ch
	print('{}'.format(black))
main()


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
C = [list(map(int, input().split())) for i in range(q)]

class Bit:

	def __init__(self, n):
		self.size = n
		self.tree = [0] * (n + 1)

	def sum(self, l, r):
		s = 0
		while r > 0:
			s += self.tree[r]
			r -= r & -r
		while l > 0:
			s -= self.tree[l]
			l -= l & -l
		return s

	def add(self, i, x):
		i += 1
		while i <= self.size:
			self.tree[i] += x
			i += i & -i

def print_bit(B):
	n = B.size
	ANS = []
	for i in range(n):
		ANS.append(B.sum(i, i + 1))
	print(*ANS)
A = Bit(n)
B = Bit(n)
A.add(0, n - 2)
B.add(0, n - 2)
AC = [0] * n
BC = [0] * n
ans = 0
minac = n - 1
minbc = n - 1
for i in range(q):
	c1 = C[i][1] - 1
	if C[i][0] == 1:
		BC[c1] = 1
		if minbc > c1:
			minbc = c1
			oku = B.sum(0, c1 + 1)
			a0 = A.sum(0, 1)
			aoku = A.sum(0, oku + 1)
			A.add(0, -a0 + c1 - 1)
			A.add(oku + 1, aoku - A.sum(0, 1))
	elif C[i][0] == 2:
		AC[c1] = 1
		if minac > c1:
			minac = c1
			oku = A.sum(0, c1 + 1)
			a0 = B.sum(0, 1)
			aoku = B.sum(0, oku + 1)
			B.add(0, -a0 + c1 - 1)
			B.add(oku + 1, aoku - B.sum(0, 1))
for i in range(1, n - 1):
	if AC[i] == 0:
		ans += A.sum(0, i + 1)
for i in range(1, n - 1):
	if BC[i] == 0:
		ans += B.sum(0, i + 1)
for i in range(1, minac):
	ans -= A.sum(0, i + 1)
print(ans)


(n, q) = map(int, input().split())
yoko = [-n]
yoko2 = [-n]
yokol = 1
tate = [-n]
tate2 = [-n]
tatel = 1
last = [n, n]
import bisect
ans = (n - 2) ** 2
for _ in range(q):
	(a, c) = map(int, input().split())
	if a == 1:
		b = bisect.bisect_left(yoko, -c)
		if b == yokol:
			yoko.append(-c)
			yoko2.append(-last[0])
			yokol += 1
			last[1] = c
			ans -= last[0] - 2
		else:
			ans -= -yoko2[b] - 2
	if a == 2:
		b = bisect.bisect_left(tate, -c)
		if b == tatel:
			tate.append(-c)
			tate2.append(-last[1])
			tatel += 1
			last[0] = c
			ans -= last[1] - 2
		else:
			ans -= -tate2[b] - 2
print(ans)


def bisect_descending(lst, x):
	(l, r) = (-1, len(lst))
	while r - l > 1:
		m = (r + l) // 2
		if lst[m] > x:
			l = m
		else:
			r = m
	return r
(N, Q) = list(map(int, input().split()))
(row, col) = ([N], [N])
ans = (N - 2) ** 2
for _ in range(Q):
	(n, x) = list(map(int, input().split()))
	if n == 1:
		if x < col[-1]:
			col.append(x)
			row.append(row[-1])
		idx = bisect_descending(col, x)
		ans -= row[idx] - 2
	else:
		if x < row[-1]:
			row.append(x)
			col.append(col[-1])
		idx = bisect_descending(row, x)
		ans -= col[idx] - 2
print(ans)


import sys

def input():
	return sys.stdin.buffer.readline()[:-1]
(n, q) = map(int, input().split())
ans = (n - 2) * (n - 2)
(v, h) = ([(n, n)], [(n, n)])
for _ in range(q):
	(k, x) = map(int, input().split())
	if k == 1:
		(l, r) = (0, len(h))
		while r - l > 1:
			m = (l + r) // 2
			if h[m][0] >= x:
				l = m
			else:
				r = m
		ans -= h[l][1] - 2
		if x < v[-1][1]:
			v.append((h[l][1] - 1, x))
	else:
		(l, r) = (0, len(v))
		while r - l > 1:
			m = (l + r) // 2
			if v[m][0] >= x:
				l = m
			else:
				r = m
		ans -= v[l][1] - 2
		if x < h[-1][1]:
			h.append((v[l][1] - 1, x))
print(ans)


class lazy_segtree:

	def __init__(s, op, e, mapping, composition, id, v):
		if type(v) is int:
			v = [e()] * v
		s._n = len(v)
		s.log = s.ceil_pow2(s._n)
		s.size = 1 << s.log
		s.d = [e()] * (2 * s.size)
		s.lz = [id()] * s.size
		s.e = e
		s.op = op
		s.mapping = mapping
		s.composition = composition
		s.id = id
		for i in range(s._n):
			s.d[s.size + i] = v[i]
		for i in range(s.size - 1, 0, -1):
			s.update(i)

	def set(s, p, x):
		p += s.size
		for i in range(s.log, 0, -1):
			s.push(p >> i)
		s.d[p] = x
		for i in range(1, s.log + 1):
			s.update(p >> i)

	def get(s, p):
		p += s.size
		for i in range(s.log, 0, -1):
			s.push(p >> i)
		return s.d[p]

	def prod(s, l, r):
		if l == r:
			return s.e()
		l += s.size
		r += s.size
		for i in range(s.log, 0, -1):
			if l >> i << i != l:
				s.push(l >> i)
			if r >> i << i != r:
				s.push(r >> i)
		(sml, smr) = (s.e(), s.e())
		while l < r:
			if l & 1:
				sml = s.op(sml, s.d[l])
				l += 1
			if r & 1:
				r -= 1
				smr = s.op(s.d[r], smr)
			l >>= 1
			r >>= 1
		return s.op(sml, smr)

	def all_prod(s):
		return s.d[1]

	def apply(s, p, f):
		p += s.size
		for i in range(s.log, 0, -1):
			s.push(p >> i)
		s.d[p] = s.mapping(f, s.d[p])
		for i in range(1, s.log + 1):
			s.update(p >> i)

	def apply(s, l, r, f):
		if l == r:
			return
		l += s.size
		r += s.size
		for i in range(s.log, 0, -1):
			if l >> i << i != l:
				s.push(l >> i)
			if r >> i << i != r:
				s.push(r - 1 >> i)
		(l2, r2) = (l, r)
		while l < r:
			if l & 1:
				sml = s.all_apply(l, f)
				l += 1
			if r & 1:
				r -= 1
				smr = s.all_apply(r, f)
			l >>= 1
			r >>= 1
		(l, r) = (l2, r2)
		for i in range(1, s.log + 1):
			if l >> i << i != l:
				s.update(l >> i)
			if r >> i << i != r:
				s.update(r - 1 >> i)

	def update(s, k):
		s.d[k] = s.op(s.d[2 * k], s.d[2 * k + 1])

	def all_apply(s, k, f):
		s.d[k] = s.mapping(f, s.d[k])
		if k < s.size:
			s.lz[k] = s.composition(f, s.lz[k])

	def push(s, k):
		s.all_apply(2 * k, s.lz[k])
		s.all_apply(2 * k + 1, s.lz[k])
		s.lz[k] = s.id()

	def ceil_pow2(s, n):
		x = 0
		while 1 << x < n:
			x += 1
		return x
import sys

def e():
	return N - 1

def op(s, t):
	return min(s, t)

def mapping(f, a):
	return min(f, a)

def composition(f, g):
	return min(f, g)

def id():
	return N - 1
(N, Q) = list(map(int, input().split()))
Query = [list(map(int, input().split())) for _ in range(Q)]
v = [N - 2] * ((N - 2) * 2)
ans = (N - 2) * (N - 2)
seg = lazy_segtree(op, e, mapping, composition, id, v)
for (q, x) in Query:
	x -= 2
	l = 0
	r = 0
	t = 0
	if q == 1:
		t = N - 2
	if q == 2:
		l += N - 2
		r += N - 2
	g = seg.get(x + t)
	ans -= g
	r += g
	seg.apply(l, r, x)
print(ans)


(n, q) = map(int, input().split())
ans = (n - 2) ** 2
h = n - 2
r = n - 2
l_h = [-1] * (n - 2)
l_r = [-1] * (n - 2)
for _ in range(q):
	(a, x) = map(int, input().split())
	if a == 1:
		if x - 1 > r:
			ans -= l_r[x - 2]
		else:
			r = x - 2
			ans -= h
			for i in range(x - 1, n - 2):
				if l_r[i] == -1:
					l_r[i] = h
				else:
					break
	elif x - 1 > h:
		ans -= l_h[x - 2]
	else:
		h = x - 2
		ans -= r
		for i in range(x - 1, n - 2):
			if l_h[i] == -1:
				l_h[i] = r
			else:
				break
print(ans)


(N, Q) = map(int, input().split())
N -= 2
BIT = [[0 for i in range(N + 1)] for _ in range(2)]
n = N

def BIT_query(idx, BIT):
	res_sum = 0
	while idx > 0:
		res_sum += BIT[idx]
		idx -= idx & -idx
	return res_sum

def BIT_update(idx, x, BIT):
	while idx <= n:
		BIT[idx] += x
		idx += idx & -idx
	return
now = N * N
max_x = [0, 0]
for _ in range(Q):
	(s, x) = map(int, input().split())
	s -= 1
	x -= 1
	x = N + 1 - x
	depth = N + BIT_query(x, BIT[s])
	now -= depth
	if x > max_x[s]:
		BIT_update(N - depth + 1, max_x[s] - x, BIT[1 - s])
		max_x[s] = x
print(now)


import sys
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7

def resolve():
	(n, q) = list(map(int, input().split()))
	query = [list(map(int, input().split())) for _ in range(q)]
	res = (n - 2) * (n - 2)
	Y = n - 1
	T = n - 1
	yoko = [n - 1] * (n - 1)
	tate = [n - 1] * (n - 1)
	for (num, x) in query:
		x -= 1
		if num == 1:
			if x > Y:
				res -= tate[x] - 1
			else:
				res -= T - 1
				for i in range(x, Y):
					tate[i] = T
				Y = x
			tate[x] = 0
		else:
			if x > T:
				res -= yoko[x] - 1
			else:
				res -= Y - 1
				for i in range(x, T):
					yoko[i] = Y
				T = x
			yoko[x] = 0
	print(res)

def __starting_point():
	resolve()
__starting_point()


(n, q) = map(int, input().split())
que = [list(map(int, input().split())) for i in range(q)]
ide_ele = 2000000000

def segfunc(x, y):
	return min(x, y)

class SegTree:

	def __init__(self, init_val, segfunc, ide_ele):
		n = len(init_val)
		self.segfunc = segfunc
		self.ide_ele = ide_ele
		self.num = 1 << (n - 1).bit_length()
		self.tree = [ide_ele] * 2 * self.num
		for i in range(n):
			self.tree[self.num + i] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

	def update(self, k, x):
		k += self.num
		self.tree[k] = x
		while k > 1:
			self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
			k >>= 1

	def query(self, l, r):
		res = self.ide_ele
		l += self.num
		r += self.num
		while l < r:
			if l & 1:
				res = self.segfunc(res, self.tree[l])
				l += 1
			if r & 1:
				res = self.segfunc(res, self.tree[r - 1])
			l >>= 1
			r >>= 1
		return res
al = [n for i in range(n)]
seg1 = SegTree(al, segfunc, ide_ele)
seg2 = SegTree(al, segfunc, ide_ele)
sm = 0
for q in que:
	x = q[1]
	if q[0] == 1:
		num = seg1.query(x, n + 1)
		sm += num - 2
		if x < seg2.query(num, num + 1):
			seg2.update(num, x)
	else:
		num = seg2.query(x, n + 1)
		sm += num - 2
		if x < seg1.query(num, num + 1):
			seg1.update(num, x)
print((n - 2) * (n - 2) - sm)


import sys
input = sys.stdin.readline

def I():
	return int(input())

def MI():
	return map(int, input().split())

def LI():
	return list(map(int, input().split()))

def main():

	class LazySegmentTree:
		__slots__ = ['n', 'data', 'lazy', 'me', 'oe', 'fmm', 'fmo', 'foo']

		def __init__(self, monoid_data, monoid_identity, operator_identity, func_monoid_monoid, func_monoid_operator, func_operator_operator):
			self.me = monoid_identity
			self.oe = operator_identity
			self.fmm = func_monoid_monoid
			self.fmo = func_monoid_operator
			self.foo = func_operator_operator
			self.n = len(monoid_data)
			self.data = monoid_data * 2
			for i in range(self.n - 1, 0, -1):
				self.data[i] = self.fmm(self.data[2 * i], self.data[2 * i + 1])
			self.lazy = [self.oe] * (self.n * 2)

		def replace(self, index, value):
			index += self.n
			for shift in range(index.bit_length() - 1, 0, -1):
				i = index >> shift
				self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
				self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
				self.data[i] = self.fmo(self.data[i], self.lazy[i])
				self.lazy[i] = self.oe
			self.data[index] = value
			self.lazy[index] = self.oe
			i = index
			while i > 1:
				i //= 2
				self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
				self.lazy[i] = self.oe

		def effect(self, l, r, operator):
			l += self.n
			r += self.n
			indices = []
			l0 = l // (l & -l) // 2
			r0 = (r // (r & -r) - 1) // 2
			while r0 > l0:
				indices.append(r0)
				r0 //= 2
			while l0 > r0:
				indices.append(l0)
				l0 //= 2
			while l0 and l0 != r0:
				indices.append(r0)
				r0 //= 2
				if l0 == r0:
					break
				indices.append(l0)
				l0 //= 2
			while r0:
				indices.append(r0)
				r0 //= 2
			for i in reversed(indices):
				self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
				self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
				self.data[i] = self.fmo(self.data[i], self.lazy[i])
				self.lazy[i] = self.oe
			while l < r:
				if l % 2:
					self.lazy[l] = self.foo(self.lazy[l], operator)
					l += 1
				if r % 2:
					r -= 1
					self.lazy[r] = self.foo(self.lazy[r], operator)
				l //= 2
				r //= 2
			for i in indices:
				self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
				self.lazy[i] = self.oe

		def folded(self, l, r):
			l += self.n
			r += self.n
			indices = []
			l0 = l // (l & -l) // 2
			r0 = (r // (r & -r) - 1) // 2
			while r0 > l0:
				indices.append(r0)
				r0 //= 2
			while l0 > r0:
				indices.append(l0)
				l0 //= 2
			while l0 and l0 != r0:
				indices.append(r0)
				r0 //= 2
				if l0 == r0:
					break
				indices.append(l0)
				l0 //= 2
			while r0:
				indices.append(r0)
				r0 //= 2
			for i in reversed(indices):
				self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
				self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
				self.data[i] = self.fmo(self.data[i], self.lazy[i])
				self.lazy[i] = self.oe
			left_folded = self.me
			right_folded = self.me
			while l < r:
				if l % 2:
					left_folded = self.fmm(left_folded, self.fmo(self.data[l], self.lazy[l]))
					l += 1
				if r % 2:
					r -= 1
					right_folded = self.fmm(self.fmo(self.data[r], self.lazy[r]), right_folded)
				l //= 2
				r //= 2
			return self.fmm(left_folded, right_folded)
	mod = 10 ** 9 + 7
	(N, Q) = MI()
	monoid_data = [N - 1] * N

	def fmm(m1, m2):
		return min(m1, m2)

	def fmo(m1, o1):
		return min(m1, o1)

	def foo(o1, o2):
		return min(o1, o2)
	inf = 10 ** 6
	seg_row = LazySegmentTree(monoid_data, inf, inf, fmm, fmo, foo)
	seg_col = LazySegmentTree(monoid_data, inf, inf, fmm, fmo, foo)
	bl = (N - 2) * (N - 2)
	for _ in range(Q):
		(q, x) = MI()
		x -= 1
		if q == 1:
			row = seg_row.folded(x, x + 1)
			bl -= row - 1
			seg_col.effect(0, row, x)
		else:
			col = seg_col.folded(x, x + 1)
			bl -= col - 1
			seg_row.effect(0, col, x)
	print(bl)
main()


f = lambda : map(int, input().split())
(N, Q) = f()
(a, b) = (N, N)
black = (N - 2) * (N - 2)
B = [-1] * (N + 1)
W = [-1] * (N + 1)
for _ in range(Q):
	(q, x) = f()
	if q == 1:
		if B[x] > 0:
			black -= B[x]
			B[x] = 0
		else:
			black -= b - 2
			a = x
			for j in range(a + 1, N + 1):
				if B[j] == -1:
					B[j] = b - 2
				else:
					break
				if j == N - 1:
					break
	elif W[x] > 0:
		black -= W[x]
		W[x] = 0
	else:
		black -= a - 2
		b = x
		for j in range(b + 1, N + 1):
			if W[j] == -1:
				W[j] = a - 2
			else:
				break
			if j == N - 1:
				break
print(black)


(N, Q) = map(int, input().split())
Min_x = [-1 for _ in range(N)]
Min_y = [-1 for _ in range(N)]
black = (N - 2) ** 2
a = N - 2
b = N - 2
for query in range(Q):
	temp = list(map(int, input().split()))
	if temp[0] == 1:
		w = temp[1] - 1
		if w <= b:
			black -= a
			for yoko in range(w, b + 1):
				Min_y[yoko] = a
			b = w - 1
		else:
			black -= Min_y[w]
	else:
		h = temp[1] - 1
		if h <= a:
			black -= b
			for tate in range(h, a + 1):
				Min_x[tate] = b
			a = h - 1
		else:
			black -= Min_x[h]
print(black)


def input_int_array():
	return map(int, input().split())

class Board:

	def __init__(self, w, h, parent):
		self.w = w
		self.h = h
		self.parent = parent

def answer(n, q):
	min_board = Board(n - 2, n - 2, None)
	black = (n - 2) * (n - 2)
	for i in range(q):
		(a, pos) = input_int_array()
		pos -= 1
		board = min_board
		use_min = True
		if a == 1:
			while pos > board.w:
				board = board.parent
				use_min = False
			black -= board.h
			if use_min:
				b = Board(pos - 1, board.h, board)
				min_board = b
		else:
			while pos > board.h:
				board = board.parent
				use_min = False
			black -= board.w
			if use_min:
				b = Board(board.w, pos - 1, board)
				min_board = b
	print(black)
(n, q) = input_int_array()
answer(n, q)


import sys
import re
import random
import math
import copy
from heapq import heappush, heappop, heapify
from functools import cmp_to_key
from bisect import bisect_left, bisect_right
from collections import defaultdict, deque, Counter
input = sys.stdin.readline
getS = lambda : input().strip()
getN = lambda : int(input())
getList = lambda : list(map(int, input().split()))
getZList = lambda : [int(x) - 1 for x in input().split()]
INF = float('inf')
MOD = 10 ** 9 + 7
divide = lambda x: pow(x, MOD - 2, MOD)

class Segtree_op:

	def __init__(self, n):
		self.n = n
		self.size = 1
		while n >= 1:
			self.size = self.size << 1
			n = n // 2
		self.arr = [self.unit() for i in range(self.size * 2)]

	def op(self, lch, rch):
		return min(lch, rch)

	def unit(self):
		return self.n

	def update(self, k, val):
		k += self.size - 1
		self.arr[k] = val
		while k:
			k = (k - 1) // 2
			self.arr[k] = self.op(self.arr[k * 2 + 1], self.arr[k * 2 + 2])

	def query(self, l, r):
		L = l + self.size
		R = r + self.size
		s = self.unit()
		while L < R:
			if R & 1:
				R -= 1
				s = self.op(s, self.arr[R - 1])
			if L & 1:
				s = self.op(s, self.arr[L - 1])
				L += 1
			L >>= 1
			R >>= 1
		return s

	def show(self):
		idx = 1
		while idx <= self.size:
			print(self.arr[idx - 1:idx * 2 - 1])
			idx *= 2

def solve():
	(n, q) = getList()
	st_tate = Segtree_op(n)
	st_yoko = Segtree_op(n)
	reversed = 0
	for _ in range(q):
		(op, idx) = getList()
		if op == 1:
			border = st_tate.query(idx, n + 1)
			reversed += border - 2
			val = min(st_yoko.query(border, border + 1), idx)
			st_yoko.update(border, val)
		else:
			border = st_yoko.query(idx, n + 1)
			reversed += border - 2
			val = min(st_tate.query(border, border + 1), idx)
			st_tate.update(border, val)
	print((n - 2) ** 2 - reversed)

def main():
	n = getN()
	for _ in range(n):
		solve()
	return
solve()


import sys
input = sys.stdin.readline
(N, Q) = map(int, input().split())
seg_el = 1 << (N + 1).bit_length()
SEG = [N - 2] * (2 * seg_el)
SEG2 = [N - 2] * (2 * seg_el)

def getvalue(n, seg_el):
	i = n + seg_el
	ANS = N - 2
	ANS = min(SEG[i], ANS)
	i >>= 1
	while i != 0:
		ANS = min(SEG[i], ANS)
		i >>= 1
	return ANS

def getvalue2(n, seg_el):
	i = n + seg_el
	ANS = N - 2
	ANS = min(SEG2[i], ANS)
	i >>= 1
	while i != 0:
		ANS = min(SEG2[i], ANS)
		i >>= 1
	return ANS

def updates(l, r, x):
	L = l + seg_el
	R = r + seg_el
	while L < R:
		if L & 1:
			SEG[L] = min(x, SEG[L])
			L += 1
		if R & 1:
			R -= 1
			SEG[R] = min(x, SEG[R])
		L >>= 1
		R >>= 1

def updates2(l, r, x):
	L = l + seg_el
	R = r + seg_el
	while L < R:
		if L & 1:
			SEG2[L] = min(x, SEG2[L])
			L += 1
		if R & 1:
			R -= 1
			SEG2[R] = min(x, SEG2[R])
		L >>= 1
		R >>= 1
ANS = (N - 2) * (N - 2)
MINX = N
MINY = N
for queries in range(Q):
	(t, x) = map(int, input().split())
	if t == 1:
		v = getvalue(x, seg_el)
		ANS -= v
		updates2(1, MINY, x - 2)
		MINX = min(MINX, x)
	else:
		v = getvalue2(x, seg_el)
		ANS -= v
		updates(1, MINX, x - 2)
		MINY = min(MINY, x)
print(ANS)


class Binary_Indexed_Tree:

	def __init__(self, n):
		self.n = n
		self.data = [0] * (n + 1)

	def add(self, i, x):
		i += 1
		while i <= self.n:
			self.data[i] += x
			i += i & -i

	def sum(self, i):
		i += 1
		ret = 0
		while i:
			ret += self.data[i]
			i &= i - 1
		return ret

	def sum_range(self, l, r):
		return self.sum(r) - self.sum(l - 1)
(n, q) = map(int, input().split())
yoko = Binary_Indexed_Tree(n - 2)
tate = Binary_Indexed_Tree(n - 2)
query = [list(map(int, input().split())) for i in range(q)]
for (a, b) in query:
	if a == 1:
		yoko.add(b - 2, 1)
	else:
		tate.add(b - 2, 1)
ans = (n - 2) ** 2
yoko_rem = n - 2
tate_rem = n - 2
yoko_minimum = n - 3
tate_minimum = n - 3
for (a, b) in query:
	pos = b - 2
	goodbye = 0
	f = False
	if a == 1:
		if yoko_minimum < pos:
			yoko.add(pos, -1)
			f = True
			continue
		goodbye = yoko_rem * yoko.sum_range(pos, yoko_minimum)
		ans -= goodbye
		tate_rem = pos
		yoko.add(pos, -1)
		yoko_minimum = pos
	else:
		if tate_minimum < pos:
			tate.add(pos, -1)
			f = True
			continue
		goodbye = tate_rem * tate.sum_range(pos, tate_minimum)
		ans -= goodbye
		yoko_rem = pos
		tate.add(pos, -1)
		tate_minimum = pos
print(ans)


(N, Q) = map(int, input().split())
(a, b) = ([N] * (N + 1), [N] * (N + 1))
(H, W) = (N, N)
black = (N - 2) ** 2
for _ in range(Q):
	(t, x) = map(int, input().split())
	if t == 1:
		if x < W:
			for i in range(x, W):
				b[i] = H
			W = x
		black -= b[x] - 2
	else:
		if x < H:
			for i in range(x, H):
				a[i] = W
			H = x
		black -= a[x] - 2
print(black)


def f_simplified_reversi():
	(N, Q) = [int(i) for i in input().split()]
	Queries = [[int(i) for i in input().split()] for j in range(Q)]
	(a, b) = ([N] * N, [N] * N)
	black_stone = (N - 2) ** 2
	(row, col) = (N, N)
	for (type, x) in Queries:
		if type == 1:
			if x < col:
				for i in range(x, col):
					b[i] = row
				col = x
			black_stone -= b[x] - 2
		else:
			if x < row:
				for i in range(x, row):
					a[i] = col
				row = x
			black_stone -= a[x] - 2
	return black_stone
print(f_simplified_reversi())


mod = 1000000007
eps = 10 ** (-9)

def main():
	import sys
	input = sys.stdin.buffer.readline

	class SegmentTree:

		def __init__(self, A, initialize=True, segfunc=min, ident=2000000000):
			self.N = len(A)
			self.LV = (self.N - 1).bit_length()
			self.N0 = 1 << self.LV
			self.segfunc = segfunc
			self.ident = ident
			if initialize:
				self.data = [self.ident] * self.N0 + A + [self.ident] * (self.N0 - self.N)
				for i in range(self.N0 - 1, 0, -1):
					self.data[i] = segfunc(self.data[i * 2], self.data[i * 2 + 1])
			else:
				self.data = [self.ident] * (self.N0 * 2)

		def update(self, i, x):
			i += self.N0 - 1
			self.data[i] = x
			for _ in range(self.LV):
				i >>= 1
				self.data[i] = self.segfunc(self.data[i * 2], self.data[i * 2 + 1])

		def query(self, l, r):
			l += self.N0 - 1
			r += self.N0 - 1
			ret_l = self.ident
			ret_r = self.ident
			while l < r:
				if l & 1:
					ret_l = self.segfunc(ret_l, self.data[l])
					l += 1
				if r & 1:
					ret_r = self.segfunc(self.data[r - 1], ret_r)
					r -= 1
				l >>= 1
				r >>= 1
			return self.segfunc(ret_l, ret_r)

		def binsearch(self, l, r, check):
			if not check(self.query(l, r)):
				return r
			l += self.N0 - 1
			val = self.ident
			while True:
				if check(self.segfunc(val, self.data[l])):
					break
				if l & 1:
					val = self.segfunc(val, self.data[l])
					l += 1
				l >>= 1
			while l < self.N0:
				newval = self.segfunc(val, self.data[l * 2])
				if not check(newval):
					val = newval
					l = (l << 1) + 1
				else:
					l <<= 1
			return l - self.N0 + 1
	(N, Q) = map(int, input().split())
	ST1 = SegmentTree([N] * N)
	ST2 = SegmentTree([N] * N)
	ans = (N - 2) * (N - 2)
	for _ in range(Q):
		(t, x) = map(int, input().split())
		if t == 1:
			k = ST1.query(x, N + 1)
			ans -= k - 2
			if x < ST2.query(k, k + 1):
				ST2.update(k, x)
		else:
			k = ST2.query(x, N + 1)
			ans -= k - 2
			if x < ST1.query(k, k + 1):
				ST1.update(k, x)
	print(ans)
main()


import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
(N, Q) = map(int, input().split())
ans = (N - 2) * (N - 2)
n = N - 2
fixed1 = [-1] * (N + 1)
fixed2 = [-1] * (N + 1)
cand1 = n
cand2 = n
ans = 0
for _ in range(Q):
	(x, y) = map(int, input().split())
	y -= 1
	if x == 1:
		if fixed1[y] != -1:
			ans += fixed1[y]
		else:
			ans += cand1
			for i in range(y + 1, n + 1):
				if fixed1[i] != -1:
					break
				fixed1[i] = cand1
			cand2 = min(cand2, y - 1)
	elif fixed2[y] != -1:
		ans += fixed2[y]
	else:
		ans += cand2
		for i in range(y + 1, n + 1):
			if fixed2[i] != -1:
				break
			fixed2[i] = cand2
		cand1 = min(cand1, y - 1)
print(n * n - ans)


import sys
import math
from bisect import bisect_right as br
from bisect import bisect_left as bl
sys.setrecursionlimit(2147483647)
from heapq import heappush, heappop, heappushpop
from collections import defaultdict
from itertools import accumulate
from collections import Counter
from collections import deque
from operator import itemgetter
from itertools import permutations
mod = 10 ** 9 + 7
inf = float('inf')

def I():
	return int(sys.stdin.readline())

def LI():
	return list(map(int, sys.stdin.readline().split()))
(n, q) = LI()
ans = (n - 2) * (n - 2)
min_x_list = [-n]
min_x_idx = [0]
min_y_list = [-n]
min_y_idx = [0]
idx = 1
for _ in range(q):
	(a, b) = LI()
	min_x = -min_x_list[-1]
	min_y = -min_y_list[-1]
	if a == 1:
		if min_x > b:
			min_x_list.append(-b)
			min_x_idx.append(idx)
			idx += 1
			ans -= min_y - 2
		else:
			r = br(min_x_list, -b)
			i = min_x_idx[r]
			r = br(min_y_idx, i)
			ans -= -min_y_list[r - 1] - 2
	elif a == 2:
		if min_y > b:
			min_y_list.append(-b)
			min_y_idx.append(idx)
			idx += 1
			ans -= min_x - 2
		else:
			r = br(min_y_list, -b)
			i = min_y_idx[r]
			r = br(min_x_idx, i)
			ans -= -min_x_list[r - 1] - 2
print(ans)


import sys
from copy import *
from bisect import *
from math import gcd, ceil, sqrt
from itertools import permutations as prm, product

def eprint(*args):
	print(*args, file=sys.stderr)
zz = 1
if zz:
	input = sys.stdin.readline
else:
	sys.stdin = open('input.txt', 'r')
	sys.stdout = open('all.txt', 'w')
di = [[-1, 0], [1, 0], [0, 1], [0, -1]]

def inc(d, c, x=1):
	d[c] = d[c] + x if c in d else x

def bo(i):
	return ord(i) - ord('A')

def li():
	return [int(xx) for xx in input().split()]

def fli():
	return [float(x) for x in input().split()]

def comp(a, b):
	if a > b:
		return 2
	return 2 if a == b else 0

def gi():
	return [xx for xx in input().split()]

def fi():
	return int(input())

def pro(a):
	return reduce(lambda a, b: a * b, a)

def swap(a, i, j):
	(a[i], a[j]) = (a[j], a[i])

def si():
	return list(input().rstrip())

def mi():
	return map(int, input().split())

def gh():
	sys.stdout.flush()

def isvalid(i, j):
	return 0 <= i < n and 0 <= j < m and (a[i][j] != '.')

def bo(i):
	return ord(i) - ord('a')

def graph(n, m):
	for i in range(m):
		(x, y) = mi()
		a[x].append(y)
		a[y].append(x)
t = 1

def updatepoint(point, val, bit):
	while point <= 4 * n:
		bit[point] += val
		point += point & -point

def query(point, bit):
	ans = 0
	while point > 0:
		ans += bit[point]
		point -= point & -point
	return ans

def update(l, r, val, bit):
	updatepoint(l, val, bit)
	updatepoint(r + 1, -val, bit)
while t > 0:
	t -= 1
	(n, q) = mi()
	ans = (n - 2) ** 2
	bitc = [0] * (4 * n)
	bitr = [0] * (4 * n)
	r = {}
	c = {}
	for i in range(q):
		(x, y) = mi()
		if x == 1 and y not in c:
			c[y] = 1
			p = query(y, bitc)
			ans -= n - 1 + p - 1
			if n - 1 + bitr[2] >= y:
				update(2, n - 1 + bitc[2], y - 1 - (n - 1 + bitr[2]), bitr)
		elif x == 2 and y not in r:
			r[y] = 1
			p = query(y, bitr)
			ans -= n - 1 + p - 1
			if n - 1 + bitc[2] >= y:
				update(2, n - 1 + bitr[2], y - 1 - (n - 1 + bitc[2]), bitc)
	print(ans)


import sys
sys.setrecursionlimit(10 ** 7)
rl = sys.stdin.readline

def solve():
	(N, Q) = map(int, rl().split())
	left = top = N
	(row, col) = ([N] * (N + 1), [N] * (N + 1))
	ans = (N - 2) ** 2
	for _ in range(Q):
		(com, x) = map(int, rl().split())
		if com == 1:
			if x < left:
				for i in range(x, left):
					col[i] = top
				left = x
			ans -= col[x] - 2
		else:
			if x < top:
				for i in range(x, top):
					row[i] = left
				top = x
			ans -= row[x] - 2
	print(ans)
solve()


class BinaryIndexedTree:

	def __init__(self, size):
		self.size = size
		self.dat = [0] * (size + 1)
		self.depth = size.bit_length()

	def init(self, a):
		for (i, x) in enumerate(a):
			self.add(i, x)

	def add(self, i, x):
		i += 1
		while i <= self.size:
			self.dat[i] += x
			i += i & -i

	def sum(self, r):
		r += 1
		ret = 0
		while r > 0:
			ret += self.dat[r]
			r -= r & -r
		return ret

	def lower_bound(self, x):
		sum_ = 0
		pos = 0
		for i in range(self.depth, -1, -1):
			k = pos + (1 << i)
			if k <= self.size and sum_ + self.dat[k] < x:
				sum_ += self.dat[k]
				pos += 1 << i
		return pos

	def get_original_sequence(self):
		ret = self.get_aggrigate_sequence()
		for i in range(self.size - 1, 0, -1):
			ret[i] -= ret[i - 1]
		return ret

	def get_aggrigate_sequence(self):
		return [self.sum(i) for i in range(self.size)]

	def __str__(self):
		seq = self.get_original_sequence()
		ret = 'original :' + ' '.join(map(str, seq))
		ret += '\n'
		seq = self.get_aggrigate_sequence()
		ret += 'aggrigate:' + ' '.join(map(str, seq))
		return ret
(n, q) = list(map(int, input().split()))
cx = BinaryIndexedTree(n + 1)
cy = BinaryIndexedTree(n + 1)
cx.add(1, n - 2)
cy.add(1, n - 2)
(mx, my) = (n, n)
ret = pow(n - 2, 2)
for _ in range(q):
	(u, v) = list(map(int, input().split()))
	if u == 1:
		ret -= cx.sum(v)
		if mx > v:
			cy.add(1, v - mx)
			cy.add(my, mx - v)
			mx = v
	else:
		ret -= cy.sum(v)
		if my > v:
			cx.add(1, v - my)
			cx.add(mx, my - v)
			my = v
print(ret)


def search(L, x):
	(low, high) = (0, len(L) - 1)
	while low < high:
		mid = (low + high) // 2
		if L[mid + 1] < x < L[mid]:
			return mid
		elif x < L[mid + 1]:
			low = mid + 1
		else:
			high = mid
	return low
(N, Q) = map(int, input().split())
query = [list(map(int, input().split())) for _ in range(Q)]
B = [N - 1]
Bv = [N - 2]
R = [N - 1]
Rv = [N - 2]
ans = (N - 2) ** 2
for (f, x) in query:
	x -= 1
	if f == 1:
		a = search(R, x)
		ans -= Rv[a]
		if R[-1] >= x:
			Bv[-1] = x - 1
			R.append(x)
			Rv.append(Rv[-1])
	else:
		a = search(B, x)
		ans -= Bv[a]
		if B[-1] >= x:
			Rv[-1] = x - 1
			B.append(x)
			Bv.append(Bv[-1])
print(ans)


class LazyPropSegmentTree:

	def __init__(self, a):
		self.padding = float('inf')
		self.n = len(a)
		self.N = 1 << (self.n - 1).bit_length()
		self.seg_data = [self.padding] * (self.N - 1) + a + [self.padding] * (self.N - self.n)
		self.lazy = [None] * (2 * self.N - 1)
		for i in range(2 * self.N - 2, 0, -2):
			self.seg_data[i - 1 >> 1] = min(self.seg_data[i], self.seg_data[i - 1])

	def __len__(self):
		return self.n

	def indices_generator(self, i, j):
		idx1 = self.N + i
		idx2 = self.N + j
		lm = idx1 // (idx1 & -idx1) >> 1
		rm = idx2 // (idx2 & -idx2) >> 1
		while 0 < idx1 < idx2:
			if idx2 <= rm:
				yield (idx2 - 1)
			if idx1 <= lm:
				yield (idx1 - 1)
			idx1 >>= 1
			idx2 >>= 1
		while idx1:
			yield (idx1 - 1)
			idx1 >>= 1

	def propagate_down(self, indices):
		for idx in indices:
			v = self.lazy[idx]
			if v is not None:
				(idx1, idx2) = (2 * idx + 1, 2 * idx + 2)
				if self.lazy[idx1] is None:
					self.lazy[idx1] = v
				else:
					self.lazy[idx1] = min(self.lazy[idx1], v)
				if self.lazy[idx2] is None:
					self.lazy[idx2] = v
				else:
					self.lazy[idx2] = min(self.lazy[idx2], v)
				self.seg_data[idx1] = min(self.seg_data[idx1], v)
				self.seg_data[idx2] = min(self.seg_data[idx2], v)
				self.lazy[idx] = None

	def propagate_up(self, indices):
		for idx in indices:
			(idx1, idx2) = (2 * idx + 1, 2 * idx + 2)
			self.seg_data[idx] = min(self.seg_data[idx1], self.seg_data[idx2])

	def propagate_all(self):
		indices = [i for i in range(self.N - 1)]
		self.propagate_down(indices)
		self.propagate_up(indices[::-1])

	def update(self, i, j, x):
		(*should_prop,) = self.indices_generator(i, j)
		self.propagate_down(should_prop[::-1])
		idx1 = self.N - 1 + i
		idx2 = self.N - 2 + j
		while idx1 < idx2 + 1:
			if idx1 & 1 == 0:
				self.seg_data[idx1] = min(x, self.seg_data[idx1])
				if self.lazy[idx1] is None:
					self.lazy[idx1] = x
				else:
					self.lazy[idx1] = min(x, self.lazy[idx1])
			if idx2 & 1 == 1:
				self.seg_data[idx2] = min(x, self.seg_data[idx2])
				if self.lazy[idx2] is None:
					self.lazy[idx2] = x
				else:
					self.lazy[idx2] = min(x, self.lazy[idx2])
			idx1 >>= 1
			idx2 >>= 1
			idx2 -= 1
		self.propagate_up(should_prop)

	def query(self, i, j):
		(*should_prop,) = self.indices_generator(i, j)
		self.propagate_down(should_prop[::-1])
		idx1 = self.N - 1 + i
		idx2 = self.N - 2 + j
		result = self.padding
		while idx1 < idx2 + 1:
			if idx1 & 1 == 0:
				result = min(result, self.seg_data[idx1])
			if idx2 & 1 == 1:
				result = min(result, self.seg_data[idx2])
			idx1 >>= 1
			idx2 >>= 1
			idx2 -= 1
		return result
(N, Q) = map(int, input().split())
query = [tuple(map(int, input().split())) for i in range(Q)]
row = LazyPropSegmentTree([N] * (N + 1))
column = LazyPropSegmentTree([N] * (N + 1))
ans = (N - 2) ** 2
for (t, x) in query:
	if t == 1:
		n = row.query(x, x + 1)
		ans -= n - 2
		column.update(2, n + 1, x)
	else:
		n = column.query(x, x + 1)
		ans -= n - 2
		row.update(2, n + 1, x)
print(ans)


from collections import deque
(n, q) = map(int, input().split())
query = []
for _ in range(q):
	(t, x) = map(int, input().split())
	query.append((t - 1, x))
black = (n - 2) ** 2
rc = [deque([(n, n)]), deque([(n, n)])]
mrc = [n, n]

def bisect(li, x):
	ok = -1
	ng = len(li)
	while abs(ok - ng) > 1:
		mid = (ok + ng) // 2
		if li[mid][0] < x:
			ok = mid
		else:
			ng = mid
	return ok + 1
for (t, x) in query:
	tmp = rc[t][bisect(rc[t], x)][1]
	black -= tmp - 2
	if x < mrc[t]:
		mrc[t] = x
		rc[1 - t].appendleft((tmp, x))
print(black)


from bisect import bisect_left as bl
(N, Q) = map(int, input().split())
ans = 0
q1 = []
q2 = []
query = []
for _ in range(Q):
	(n, p) = map(int, input().split())
	query.append((n, p))
	if n == 1:
		q1.append(p)
	else:
		q2.append(p)
q1.sort()
q2.sort()
board = [N - 2, N - 2]
count1 = len(q1)
count2 = len(q2)
for (n, p) in query:
	if n == 1:
		if p > board[1] + 1:
			continue
		index = bl(q1, p)
		ans += board[0] * (count1 - index)
		board[1] = p - 2
		count1 = index
	else:
		if p > board[0] + 1:
			continue
		index = bl(q2, p)
		ans += board[1] * (count2 - index)
		board[0] = p - 2
		count2 = index
print((N - 2) ** 2 - ans)


import sys
from collections import deque
import bisect
import copy
import heapq
import itertools
import math
input = sys.stdin.readline
sys.setrecursionlimit(1000000)
mod = 10 ** 9 + 7

def read_values():
	return map(int, input().split())

def read_index():
	return map(lambda x: int(x) - 1, input().split())

def read_list():
	return list(read_values())

def read_lists(N):
	return [read_list() for n in range(N)]

def main():
	(N, M) = read_values()
	Q = [tuple(read_index()) for _ in range(M)]
	S = [N - 1] * N
	T = [N - 1] * N
	(W, H) = (N - 1, N - 1)
	res = (N - 2) ** 2
	for (d, x) in Q:
		if d == 0:
			if x < W:
				for i in range(x, W):
					S[i] = H
				W = x
			res -= S[x] - 1
		if d == 1:
			if x < H:
				for i in range(x, H):
					T[i] = W
				H = x
			res -= T[x] - 1
	print(res)
main()


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
left = n
up = n
ans = (n - 2) * (n - 2)
fixed_yoko = [0] * (n + 1)
fixed_tate = [0] * (n + 1)
post_process = []
for _ in range(q):
	(t, x) = map(int, input().split())
	if t == 1:
		if x > left:
			post_process.append((t, x))
		else:
			fixed_yoko[left] += -up
			fixed_yoko[x + 1] += up
			ans -= up - 2
			left = x
	elif t == 2:
		if x > up:
			post_process.append((t, x))
		else:
			fixed_tate[up] += -left
			fixed_tate[x + 1] += left
			ans -= left - 2
			up = x
for i in range(1, n + 1):
	fixed_yoko[i] += fixed_yoko[i - 1]
	fixed_tate[i] += fixed_tate[i - 1]
for (t, x) in post_process:
	if t == 1:
		ans -= fixed_yoko[x] - 2
	elif t == 2:
		ans -= fixed_tate[x] - 2
print(ans)


(n, q) = list(map(int, input().split()))
query = [list(map(int, input().split())) for _ in range(q)]
INF = 10 ** 9
ver = [-1] * (n + 1)
hor = [-1] * (n + 1)
ver[-1] = INF
hor[-1] = INF
ver_base = n - 1
hor_base = n - 1
white = 2 * n - 1
for (num, x) in query:
	if num == 1:
		if ver[x] == -1:
			white += ver_base
			i = x
			while ver[i] == -1:
				ver[i] = ver_base
				i += 1
		else:
			white += ver[x]
		hor_base = min(hor_base, x - 1)
	else:
		if hor[x] == -1:
			white += hor_base
			i = x
			while hor[i] == -1:
				hor[i] = hor_base
				i += 1
		else:
			white += hor[x]
		ver_base = min(ver_base, x - 1)
stone_sum = (n - 2) * (n - 2) + 2 * n - 1 + q
ans = stone_sum - white
print(ans)


import sys
sys.setrecursionlimit(10 ** 6)
INF = 10 ** 9 + 1
MOD = 10 ** 9 + 7

def debug(*x):
	print(*x, file=sys.stderr)

def solve(SOLVE_PARAMS):
	pass

def main():
	from bisect import bisect_left
	(N, Q) = map(int, input().split())
	ret = (N - 2) ** 2
	xs = [-N]
	xvals = [N - 2]
	ys = [-N]
	yvals = [N - 2]
	for _q in range(Q):
		(q, x) = map(int, input().split())
		if q == 1:
			i = bisect_left(xs, -x)
			ret -= xvals[i - 1]
			if i == len(xs) and yvals[-1] > x - 2:
				ys.append(-xvals[i - 1] - 2)
				yvals.append(x - 2)
		else:
			y = x
			i = bisect_left(ys, -y)
			ret -= yvals[i - 1]
			if i == len(ys) and xvals[-1] > y - 2:
				xs.append(-yvals[i - 1] - 2)
				xvals.append(y - 2)
	print(ret)
T1 = '\n5 5\n1 3\n2 3\n1 4\n2 2\n1 2\n'
TEST_T1 = '\n>>> as_input(T1)\n>>> main()\n1\n'
T2 = '\n200000 0\n'
TEST_T2 = '\n>>> as_input(T2)\n>>> main()\n39999200004\n'
T3 = '\n176527 15\n1 81279\n2 22308\n2 133061\n1 80744\n2 44603\n1 170938\n2 139754\n2 15220\n1 172794\n1 159290\n2 156968\n1 56426\n2 77429\n1 97459\n2 71282\n'
_TEST_T3 = '\n>>> as_input(T3)\n>>> main()\n31159505795\n'

def _test():
	import doctest
	doctest.testmod()
	g = globals()
	for k in sorted(g):
		if k.startswith('TEST_'):
			doctest.run_docstring_examples(g[k], g, name=k)

def as_input(s):
	import io
	f = io.StringIO(s.strip())
	g = globals()
	g['input'] = lambda : bytes(f.readline(), 'ascii')
	g['read'] = lambda : bytes(f.read(), 'ascii')
input = sys.stdin.buffer.readline
read = sys.stdin.buffer.read
if sys.argv[-1] == '-t':
	print('testing')
	_test()
	sys.exit()
main()


def main():
	(N, Q) = [int(v) for v in input().split()]
	Query = [[int(v) - 1 for v in input().split()] for _ in range(Q)]
	rows = [N - 1] * (N - 1)
	cols = [N - 1] * (N - 1)
	black = (N - 2) * (N - 2)
	min_row = N - 1
	min_col = N - 1
	for (ty, x) in Query:
		if ty == 0:
			if x < min_col:
				rows[x:min_col] = [min_row] * (min_col - x)
				min_col = x
			black -= rows[x] - 1
		else:
			if x < min_row:
				cols[x:min_row] = [min_col] * (min_row - x)
				min_row = x
			black -= cols[x] - 1
	print(black)
main()


from copy import *
from bisect import *
(N, Q) = map(int, input().split())
P = (N - 2) * (N - 2)
X = [N - 2]
Y = [N - 2]
V = []
W = []
(a, b, c) = (0, 0, 0)
for i in range(Q):
	(a, b) = map(int, input().split())
	b = N - b
	if a == 1:
		c = bisect_left(V, b)
		if c == len(V):
			P -= Y[c]
			Y.append(Y[-1])
			X[-1] = N - b - 2
			V.append(b)
		else:
			P -= Y[c]
	else:
		c = bisect_left(W, b)
		if c == len(W):
			P -= X[c]
			X.append(X[-1])
			Y[-1] = N - b - 2
			W.append(b)
		else:
			P -= X[c]
print(P)


(N, Q) = list(map(int, input().split()))
Query = [list(map(int, input().split())) for _ in range(Q)]
ans = 0
for T in range(1, 3):
	Depth = [N - 2] * N
	left = N
	up = N - 2
	for (t, x) in Query:
		if t == T:
			if left < x:
				ans += Depth[x]
			else:
				for i in range(x, left):
					Depth[i] = up
				left = x
				ans += up
		else:
			up = min(up, x - 2)
print((N - 2) ** 2 - ans)


(n, q) = (int(x) for x in input().split())
queries = [tuple((int(x) for x in input().split())) for _ in range(q)]
ans = (n - 2) ** 2
t1 = [n] * (n + 1)
t2 = [n] * (n + 1)
(h, w) = (n, n)
for (t, x) in queries:
	if t == 1:
		if x < w:
			tmp = h
			for i in range(x, w + 1):
				t1[i] = h
			w = x
		else:
			tmp = t1[x]
		ans -= tmp - 2
	else:
		if x < h:
			tmp = w
			for i in range(x, h + 1):
				t2[i] = w
			h = x
		else:
			tmp = t2[x]
		ans -= tmp - 2
print(ans)


def segfunc(x, y):
	return min(x, y)
ide_ele = 10 ** 9

class SegTree:

	def __init__(self, init_val, segfunc, ide_ele):
		n = len(init_val)
		self.segfunc = segfunc
		self.ide_ele = ide_ele
		self.num = 1 << (n - 1).bit_length()
		self.tree = [ide_ele] * 2 * self.num
		for i in range(n):
			self.tree[self.num + i] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

	def update(self, k, x):
		k += self.num
		self.tree[k] = x
		while k > 1:
			self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
			k >>= 1

	def query(self, l, r):
		res = self.ide_ele
		l += self.num
		r += self.num
		while l < r:
			if l & 1:
				res = self.segfunc(res, self.tree[l])
				l += 1
			if r & 1:
				res = self.segfunc(res, self.tree[r - 1])
			l >>= 1
			r >>= 1
		return res
(N, Q) = map(int, input().split())
ans = (N - 2) ** 2
yoko = [N - 2 for _ in range(N - 2)]
tate = [N - 2 for _ in range(N - 2)]
yoko = SegTree(yoko, segfunc, ide_ele)
tate = SegTree(tate, segfunc, ide_ele)
miny = N - 2
minx = N - 2
for k in range(Q):
	(n, x) = map(int, input().split())
	if n == 1:
		y = x - 2
		if y < miny:
			ans -= minx
			miny = y
			yoko.update(min(minx, N - 3), miny)
		else:
			ans -= tate.query(y, N - 1)
	else:
		x = x - 2
		if x < minx:
			ans -= miny
			minx = x
			tate.update(min(miny, N - 3), minx)
		else:
			ans -= yoko.query(x, N - 1)
print(ans)


from collections import deque

def bisect(arr, x):
	(l, r) = (-1, len(arr))
	while r - l > 1:
		mid = (l + r) // 2
		if x > arr[mid][0]:
			l = mid
		else:
			r = mid
	return arr[l]
(N, Q) = map(int, input().split())
h = deque([(N - 1, N - 1)])
w = deque([(N - 1, N - 1)])
Black = (N - 2) ** 2
for i in range(Q):
	(t, x) = map(int, input().split())
	x -= 1
	if t == 1:
		if x < h[0][0]:
			h.appendleft((x, w[0][0]))
			Black -= w[0][0] - 1
		else:
			b = bisect(h, x)
			Black -= b[1] - 1
	elif x < w[0][0]:
		w.appendleft((x, h[0][0]))
		Black -= h[0][0] - 1
	else:
		b = bisect(w, x)
		Black -= b[1] - 1
print(Black)


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
hor = [0] * (n - 2)
ver = [0] * (n - 2)
a = n - 2
b = n - 2
ans = (n - 2) ** 2
for _ in range(q):
	(y, x) = map(int, input().split())
	if y == 1:
		if x - 1 > b:
			ans -= ver[x - 2]
		else:
			ans -= a
			for i in range(x - 2, b):
				ver[i] = a
			b = x - 2
	elif x - 1 > a:
		ans -= hor[x - 2]
	else:
		ans -= b
		for i in range(x - 2, a):
			hor[i] = b
		a = x - 2
print(ans)


import sys
read = sys.stdin.read
readline = sys.stdin.readline
readlines = sys.stdin.readlines
sys.setrecursionlimit(10 ** 9)
INF = 1 << 60
MOD = 1000000007

def main():
	(N, Q, *query) = map(int, read().split())
	N -= 2
	row = [N] * N
	col = [N] * N
	R = C = N
	ans = N * N
	for (q, x) in zip(*[iter(query)] * 2):
		x -= 2
		if q == 1:
			if x < C:
				ans -= R
				for i in range(x + 1, C):
					col[i] = R
				C = x
			else:
				ans -= col[x]
		elif x < R:
			ans -= C
			for i in range(x + 1, R):
				row[i] = C
			R = x
		else:
			ans -= row[x]
	print(ans)
	return
main()


import sys
import bisect
input = sys.stdin.readline

def main():
	(n, q) = map(int, input().split())
	ans = 0
	(min1, min2) = (n - 2, n - 2)
	judge1 = [-n - 1]
	judge2 = [-n - 1]
	dict1 = dict()
	dict2 = dict()
	dict1[-n - 1] = n - 2
	dict2[-n - 1] = n - 2
	for i in range(q):
		(query, x) = map(int, input().split())
		if query == 1:
			index = bisect.bisect(judge1, -x) - 1
			key = dict1[judge1[index]]
			ans += key
			if min1 > x - 2:
				min1 = x - 2
				judge1.append(-x)
				dict1[-x] = key
				dict2[judge2[-1]] = min1
		else:
			index = bisect.bisect(judge2, -x) - 1
			key = dict2[judge2[index]]
			ans += key
			if min2 > x - 2:
				min2 = x - 2
				judge2.append(-x)
				dict2[-x] = key
				dict1[judge1[-1]] = min2
	print((n - 2) ** 2 - ans)
main()


from math import inf, log2

class SegmentTree:

	def __init__(self, array, func=max):
		self.n = len(array)
		self.size = 2 ** (int(log2(self.n - 1)) + 1) if self.n != 1 else 1
		self.func = func
		self.default = 0 if self.func != min else inf
		self.data = [self.default] * (2 * self.size)
		self.process(array)

	def process(self, array):
		self.data[self.size:self.size + self.n] = array
		for i in range(self.size - 1, -1, -1):
			self.data[i] = self.func(self.data[2 * i], self.data[2 * i + 1])

	def query(self, alpha, omega):
		if alpha == omega:
			return self.data[alpha + self.size]
		res = self.default
		alpha += self.size
		omega += self.size + 1
		while alpha < omega:
			if alpha & 1:
				res = self.func(res, self.data[alpha])
				alpha += 1
			if omega & 1:
				omega -= 1
				res = self.func(res, self.data[omega])
			alpha >>= 1
			omega >>= 1
		return res

	def update(self, index, value):
		index += self.size
		self.data[index] = value
		index >>= 1
		while index:
			self.data[index] = self.func(self.data[2 * index], self.data[2 * index + 1])
			index >>= 1
import os
import sys
from io import BytesIO, IOBase
BUFSIZE = 8192

class FastIO(IOBase):
	newlines = 0

	def __init__(self, file):
		self._fd = file.fileno()
		self.buffer = BytesIO()
		self.writable = 'x' in file.mode or 'r' not in file.mode
		self.write = self.buffer.write if self.writable else None

	def read(self):
		while True:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			if not b:
				break
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines = 0
		return self.buffer.read()

	def readline(self):
		while self.newlines == 0:
			b = os.read(self._fd, max(os.fstat(self._fd).st_size, BUFSIZE))
			self.newlines = b.count(b'\n') + (not b)
			ptr = self.buffer.tell()
			(self.buffer.seek(0, 2), self.buffer.write(b), self.buffer.seek(ptr))
		self.newlines -= 1
		return self.buffer.readline()

	def flush(self):
		if self.writable:
			os.write(self._fd, self.buffer.getvalue())
			(self.buffer.truncate(0), self.buffer.seek(0))

class IOWrapper(IOBase):

	def __init__(self, file):
		self.buffer = FastIO(file)
		self.flush = self.buffer.flush
		self.writable = self.buffer.writable
		self.write = lambda s: self.buffer.write(s.encode('ascii'))
		self.read = lambda : self.buffer.read().decode('ascii')
		self.readline = lambda : self.buffer.readline().decode('ascii')
(sys.stdin, sys.stdout) = (IOWrapper(sys.stdin), IOWrapper(sys.stdout))
input = lambda : sys.stdin.readline().rstrip('\r\n')
from math import gcd, ceil

def pre(s):
	n = len(s)
	pi = [0] * n
	for i in range(1, n):
		j = pi[i - 1]
		while j and s[i] != s[j]:
			j = pi[j - 1]
		if s[i] == s[j]:
			j += 1
		pi[i] = j
	return pi

def prod(a):
	ans = 1
	for each in a:
		ans = ans * each
	return ans

def lcm(a, b):
	return a * b // gcd(a, b)

def binary(x, length=16):
	y = bin(x)[2:]
	return y if len(y) >= length else '0' * (length - len(y)) + y
from math import log2

class SegmentTree:

	def __init__(self, array):
		self.n = len(array)
		self.size = 2 ** (int(log2(self.n - 1)) + 1) if self.n != 1 else 1
		self.default = 10 ** 18
		self.data = [self.default] * (2 * self.size)
		self.process(array)

	def process(self, array):
		self.data[self.size:self.size + self.n] = array

	def query(self, index):
		res = self.default
		index += self.size
		while index:
			res = min(res, self.data[index])
			index >>= 1
		return res

	def update(self, alpha, omega, value):
		alpha += self.size
		omega += self.size + 1
		while alpha < omega:
			if alpha & 1:
				self.data[alpha] = min(self.data[alpha], value)
				alpha += 1
			if omega & 1:
				omega -= 1
				self.data[omega] = min(self.data[omega], value)
			alpha >>= 1
			omega >>= 1
for _ in range(int(input()) if not True else 1):
	(n, q) = map(int, input().split())
	black = (n - 2) * (n - 2)
	first_in_row = [n - 1] * n
	first_in_row[n - 1] = 0
	first_in_column = [n - 1] * n
	first_in_column[n - 1] = 0
	first_in_row = SegmentTree(first_in_row)
	first_in_column = SegmentTree(first_in_column)
	for __ in range(q):
		(x, y) = map(int, input().split())
		if x == 1:
			col_first = first_in_column.query(y - 1)
			black -= max(col_first - 1, 0)
			first_in_row.update(0, col_first - 1, y - 1)
			first_in_column.update(y - 1, y - 1, 0)
		else:
			row_first = first_in_row.query(y - 1)
			black -= max(row_first - 1, 0)
			first_in_column.update(0, row_first - 1, y - 1)
			first_in_row.update(y - 1, y - 1, 0)
	print(black)


class MinSegTree:

	def __init__(self, size):
		self.size = 1 << size.bit_length()
		self.data = [INF] * (2 * self.size - 1)

	def build(self, rawData):
		self.data[self.size - 1:self.size - 1 + len(rawData)] = rawData
		for i in range(self.size - 1)[::-1]:
			self.data[i] = min(self.data[2 * i + 1], self.data[2 * i + 2])

	def update(self, index, value):
		index += self.size - 1
		if self.data[index] <= value:
			return
		self.data[index] = value
		while index >= 0:
			index = (index - 1) // 2
			self.data[index] = min(self.data[2 * index + 1], self.data[2 * index + 2])

	def query(self, left, right):
		L = left + self.size
		R = right + self.size
		ret = INF
		while L < R:
			if R & 1:
				R -= 1
				ret = min(ret, self.data[R - 1])
			if L & 1:
				ret = min(ret, self.data[L - 1])
				L += 1
			L >>= 1
			R >>= 1
		return ret
(N, Q) = map(int, input().split())
INF = N - 2
treeRow = MinSegTree(N + 2)
treeCol = MinSegTree(N + 2)
miRow = N - 1
miCol = N - 1
ans = (N - 2) ** 2
for q in range(Q):
	(q, x) = map(int, input().split())
	if q == 1:
		col = x
		ans -= treeRow.query(col, N)
		miCol = min(col, miCol)
		treeCol.update(miRow, col - 2)
	if q == 2:
		row = x
		ans -= treeCol.query(row, N)
		miRow = min(row, miRow)
		treeRow.update(miCol, row - 2)
print(ans)


(N, Q, *QX) = map(int, open(0).read().split())
A = [N] * (N + 1)
B = [N] * (N + 1)
ans = (N - 2) ** 2
h = w = N
for (q, x) in zip(*[iter(QX)] * 2):
	if q == 1:
		if x < w:
			B[x:w] = [h] * (w - x)
			w = x
		ans -= B[x] - 2
	else:
		if x < h:
			A[x:h] = [w] * (h - x)
			h = x
		ans -= A[x] - 2
print(ans)


(n, q) = map(int, input().split())
yoko = [0 for i in range(n + 1)]
tate = [0 for i in range(n + 1)]
yokobig = n
tatebig = n
ans = 0
for _ in range(q):
	(a, b) = map(int, input().split())
	if a == 1:
		if b < yokobig:
			ans += tatebig - 2
			for i in range(b, yokobig):
				yoko[i] = tatebig
			yokobig = b
		else:
			ans += yoko[b] - 2
	if a == 2:
		if b < tatebig:
			ans += yokobig - 2
			for i in range(b, tatebig):
				tate[i] = yokobig
			tatebig = b
		else:
			ans += tate[b] - 2
print((n - 2) ** 2 - ans)


import sys

def input():
	return sys.stdin.readline().rstrip()

class LazySegmentTree:

	def __init__(self, init, unitX, unitA, f, g, h):
		self.f = f
		self.g = g
		self.h = h
		self.unitX = unitX
		self.unitA = unitA
		self.f = f
		if type(init) == int:
			self.n = init
			self.X = [unitX] * (self.n * 2)
			self.size = [1] * (self.n * 2)
		else:
			self.n = len(init)
			self.X = [unitX] * self.n + init + [unitX] * (self.n - len(init))
			self.size = [0] * self.n + [1] * len(init) + [0] * (self.n - len(init))
			for i in range(self.n - 1, 0, -1):
				self.X[i] = self.f(self.X[i * 2], self.X[i * 2 | 1])
		for i in range(self.n - 1, 0, -1):
			self.size[i] = self.size[i * 2] + self.size[i * 2 | 1]
		self.A = [unitA] * (self.n * 2)

	def update(self, i, x):
		i += self.n
		self.X[i] = x
		i >>= 1
		while i:
			self.X[i] = self.f(self.X[i * 2], self.X[i * 2 | 1])
			i >>= 1

	def calc(self, i):
		return self.g(self.X[i], self.A[i], self.size[i])

	def calc_above(self, i):
		i >>= 1
		while i:
			self.X[i] = self.f(self.calc(i * 2), self.calc(i * 2 | 1))
			i >>= 1

	def propagate(self, i):
		self.X[i] = self.g(self.X[i], self.A[i], self.size[i])
		self.A[i * 2] = self.h(self.A[i * 2], self.A[i])
		self.A[i * 2 | 1] = self.h(self.A[i * 2 | 1], self.A[i])
		self.A[i] = self.unitA

	def propagate_above(self, i):
		H = i.bit_length()
		for h in range(H, 0, -1):
			self.propagate(i >> h)

	def propagate_all(self):
		for i in range(1, self.n):
			self.propagate(i)

	def getrange(self, l, r):
		l += self.n
		r += self.n
		(l0, r0) = (l // (l & -l), r // (r & -r) - 1)
		self.propagate_above(l0)
		self.propagate_above(r0)
		al = self.unitX
		ar = self.unitX
		while l < r:
			if l & 1:
				al = self.f(al, self.calc(l))
				l += 1
			if r & 1:
				r -= 1
				ar = self.f(self.calc(r), ar)
			l >>= 1
			r >>= 1
		return self.f(al, ar)

	def getvalue(self, i):
		i += self.n
		self.propagate_above(i)
		return self.calc(i)

	def operate_range(self, l, r, a):
		l += self.n
		r += self.n
		(l0, r0) = (l // (l & -l), r // (r & -r) - 1)
		self.propagate_above(l0)
		self.propagate_above(r0)
		while l < r:
			if l & 1:
				self.A[l] = self.h(self.A[l], a)
				l += 1
			if r & 1:
				r -= 1
				self.A[r] = self.h(self.A[r], a)
			l >>= 1
			r >>= 1
		self.calc_above(l0)
		self.calc_above(r0)

	def max_right(self, l, z):
		if l >= self.n:
			return self.n
		l += self.n
		s = self.unitX
		while 1:
			while l % 2 == 0:
				l >>= 1
			if not z(self.f(s, self.calc(l))):
				while l < self.n:
					l *= 2
					if z(self.f(s, self.calc(l))):
						s = self.f(s, self.calc(l))
						l += 1
				return l - self.n
			s = self.f(s, self.calc(l))
			l += 1
			if l & -l == l:
				break
		return self.n

	def min_left(self, r, z):
		if r <= 0:
			return 0
		r += self.n
		s = self.unitX
		while 1:
			r -= 1
			while r > 1 and r % 2:
				r >>= 1
			if not z(self.f(self.calc(r), s)):
				while r < self.n:
					r = r * 2 + 1
					if z(self.f(self.calc(r), s)):
						s = self.f(self.calc(r), s)
						r -= 1
				return r + 1 - self.n
			s = self.f(self.calc(r), s)
			if r & -r == r:
				break
		return 0
f = lambda x, y: x + y
g = lambda x, a, s: min(x, a)
h = lambda a, b: min(a, b)
unitX = 0
unitA = 10 ** 10
(N, Q) = map(int, input().split())
A = [N - 2] * (N - 2)
sttate = LazySegmentTree(A, unitX, unitA, f, g, h)
styoko = LazySegmentTree(A, unitX, unitA, f, g, h)
ans = (N - 2) ** 2
for _ in range(Q):
	(q1, q2) = map(int, input().split())
	if q1 == 1:
		horu = sttate.getrange(q2 - 2, q2 - 1)
		ans -= horu
		sttate.operate_range(q2 - 2, q2 - 1, 0)
		styoko.operate_range(0, horu, q2 - 2)
	if q1 == 2:
		horu = styoko.getrange(q2 - 2, q2 - 1)
		ans -= horu
		styoko.operate_range(q2 - 2, q2 - 1, 0)
		sttate.operate_range(0, horu, q2 - 2)
print(ans)


import sys
import math
from collections import defaultdict
from bisect import bisect_left, bisect_right
sys.setrecursionlimit(10 ** 7)

def input():
	return sys.stdin.readline()[:-1]
mod = 10 ** 9 + 7

def I():
	return int(input())

def LI():
	return list(map(int, input().split()))

def LIR(row, col):
	if row <= 0:
		return [[] for _ in range(col)]
	elif col == 1:
		return [I() for _ in range(row)]
	else:
		read_all = [LI() for _ in range(row)]
		return map(list, zip(*read_all))
(N, Q) = LI()
a = [N - 1] * N
b = [N - 1] * N
a[-1] = 0
b[-1] = 0
x1 = N - 1
x2 = N - 1
ans = (N - 2) ** 2
for i in range(Q):
	(j, k) = LI()
	k -= 1
	if j == 1:
		if k > x2:
			ans -= b[k] - 1
		else:
			for n in range(k + 1, x2):
				b[n] = x1
			ans -= max(0, x1 - 1)
			x2 = k
	elif k > x1:
		ans -= a[k] - 1
	else:
		for n in range(k + 1, x1):
			a[n] = x2
		ans -= max(0, x2 - 1)
		x1 = k
print(ans)


from collections import defaultdict, deque
from heapq import heappush, heappop
from itertools import permutations, accumulate
import sys
import math
import bisect

def LI():
	return [int(x) for x in sys.stdin.readline().split()]

def I():
	return int(sys.stdin.readline())

def LS():
	return [list(x) for x in sys.stdin.readline().split()]

def S():
	res = list(sys.stdin.readline())
	if res[-1] == '\n':
		return res[:-1]
	return res

def IR(n):
	return [I() for _ in range(n)]

def LIR(n):
	return [LI() for _ in range(n)]

def SR(n):
	return [S() for _ in range(n)]

def LSR(n):
	return [LS() for _ in range(n)]
sys.setrecursionlimit(1000000)
mod = 1000000007
from math import log2, ceil

class SegmentTree:

	def __init__(self, n, default):
		self.n = n
		tn = 2 ** ceil(log2(n))
		self.a = [default] * (tn * 2)
		self.tn = tn

	def find(self, s, t):
		return self.__find(1, 0, self.tn - 1, s, t)

	def __find(self, c, l, r, s, t):
		if self.a[c] == -1:
			return self.a[c // 2]
		if s <= l and r <= t:
			return self.a[c]
		mid = (l + r) // 2
		if t <= mid:
			return self.__find(c * 2, l, mid, s, t)
		elif s > mid:
			return self.__find(c * 2 + 1, mid + 1, r, s, t)
		else:
			return min(self.__find(c * 2, l, mid, s, mid), self.__find(c * 2 + 1, mid + 1, r, mid + 1, t))

	def update(self, s, t, x):
		self.__update(1, 0, self.tn - 1, s, t, x)

	def __update(self, c, l, r, s, t, x, f=None):
		if f is None and self.a[c] == -1:
			f = self.a[c // 2]
		if l == s and r == t:
			return self.__set(c, x)
		mid = (l + r) // 2
		if t <= mid:
			(rv, f) = self.__get_child(c, c * 2 + 1, f)
			u = min(self.__update(c * 2, l, mid, s, t, x, f), rv)
		elif s > mid:
			(lv, f) = self.__get_child(c, c * 2, f)
			u = min(lv, self.__update(c * 2 + 1, mid + 1, r, s, t, x, f))
		else:
			u = min(self.__update(c * 2, l, mid, s, mid, x, f), self.__update(c * 2 + 1, mid + 1, r, mid + 1, t, x, f))
			if f is not None:
				u = min(f, u)
		self.a[c] = u
		return u

	def __set(self, c, x):
		self.a[c] = x
		if c < self.tn:
			self.a[c * 2] = self.a[c * 2 + 1] = -1
		return x

	def __get_child(self, c, child, f):
		if f is not None:
			return (self.__set(child, f), f)
		v = self.a[child]
		if v == -1:
			f = self.a[c]
			v = self.__set(child, f)
		return (v, f)

def solve():
	(n, q) = LI()
	ans = (n - 2) * (n - 2)
	right = SegmentTree(n + 1, n)
	down = SegmentTree(n + 1, n)
	for _ in range(q):
		(t, x) = LI()
		if t == 1:
			d = down.find(x, x)
			ans -= d - 2
			k = right.find(0, 0)
			if k > x:
				right.update(0, d, x)
		else:
			r = right.find(x, x)
			ans -= r - 2
			k = down.find(0, 0)
			if k > x:
				down.update(0, r, x)
	print(ans)
	return
solve()


(N, Q) = map(int, input().split())

class SegmentTree:

	def __init__(self, init_value: list, segfunc, ide_ele):
		n = len(init_value)
		self.N0 = 1 << (n - 1).bit_length()
		self.ide_ele = ide_ele
		self.data = [ide_ele] * (2 * self.N0)
		self.segfunc = segfunc
		for (i, x) in enumerate(init_value):
			self.data[i + self.N0 - 1] = x
		for i in range(self.N0 - 2, -1, -1):
			self.data[i] = self.segfunc(self.data[2 * i + 1], self.data[2 * i + 2])

	def update(self, k: int, x):
		k += self.N0 - 1
		self.data[k] = x
		while k:
			k = (k - 1) // 2
			self.data[k] = self.segfunc(self.data[k * 2 + 1], self.data[k * 2 + 2])

	def get(self, k):
		return self.query(k, k + 1)

	def query(self, left: int, right: int):
		L = left + self.N0
		R = right + self.N0
		res = self.ide_ele
		(a, b) = ([], [])
		while L < R:
			if L & 1:
				a.append(L - 1)
				L += 1
			if R & 1:
				R -= 1
				b.append(R - 1)
			L >>= 1
			R >>= 1
		for i in a + b[::-1]:
			res = self.segfunc(res, self.data[i])
		return res
segW = SegmentTree([N - 2] * N, min, 10 ** 18)
segH = SegmentTree([N - 2] * N, min, 10 ** 18)
ans = (N - 2) ** 2
for i in range(Q):
	(q, x) = map(int, input().split())
	if q == 1:
		res = segW.query(x - 1, N)
		segH.update(res, min(x - 2, segH.query(res, N)))
		ans -= res
	else:
		res = segH.query(x - 1, N)
		now = segW.get(res - 1)
		segW.update(res, min(x - 2, segW.query(res, N)))
		ans -= res
print(ans)


class SegmentTreeDual:

	def __init__(self, n, op, id, commutative=False):
		self.n = n
		self.op = op
		self.id = id
		self.commutative = commutative
		self.log = (n - 1).bit_length()
		self.size = 1 << self.log
		self.d = [id] * self.size
		self.lz = [id] * (2 * self.size)

	def build(self, arr):
		for (i, a) in enumerate(arr):
			self.d[i] = a

	def propagate(self, k):
		if self.lz[k] == self.id:
			return
		if k < self.size:
			self.lz[2 * k] = self.op(self.lz[k], self.lz[2 * k])
			self.lz[2 * k + 1] = self.op(self.lz[k], self.lz[2 * k + 1])
		else:
			self.d[k - self.size] = self.op(self.lz[k], self.d[k - self.size])
		self.lz[k] = self.id

	def get(self, p):
		res = self.d[p]
		p += self.size
		for i in range(self.log):
			res = self.op(self.lz[p >> i], res)
		return res

	def range_apply(self, l, r, f):
		if l == r:
			return
		l += self.size
		r += self.size
		if not self.commutative:
			for i in range(self.log)[::-1]:
				self.propagate(l >> i)
				self.propagate(r >> i)
		while l < r:
			if l & 1:
				self.lz[l] = self.op(f, self.lz[l])
				l += 1
			if r & 1:
				r -= 1
				self.lz[r] = self.op(f, self.lz[r])
			l >>= 1
			r >>= 1
import sys
input = sys.stdin.buffer.readline
(N, Q) = map(int, input().split())
stx = SegmentTreeDual(N, min, 10 ** 18, True)
sty = SegmentTreeDual(N, min, 10 ** 18, True)
x = [N - 1] * (N - 1) + [0]
y = [N - 1] * (N - 1) + [0]
stx.build(x)
sty.build(y)
res = (N - 2) * (N - 2)
for _ in range(Q):
	(q, k) = map(int, input().split())
	if q == 1:
		g = stx.get(k - 1)
		res -= g - 1
		sty.range_apply(1, g, k - 1)
	if q == 2:
		g = sty.get(k - 1)
		res -= g - 1
		stx.range_apply(1, g, k - 1)
print(res)


import bisect
(N, Q) = map(int, input().split())
L = [0] * Q
L1 = []
L2 = []
for i in range(Q):
	(a, b) = map(int, input().split())
	L[i] = (a, b)
	if a == 1:
		L1.append(b)
	else:
		L2.append(b)
L1.sort()
L2.sort()
M1 = len(L1)
M2 = len(L2)
ans = (N - 2) ** 2
up = N
left = N
for l in L:
	a = l[0]
	b = l[1]
	if a == 1:
		if b > left:
			continue
		idx = bisect.bisect_left(L1, b)
		ans -= (M1 - idx) * (up - 2)
		M1 = idx
		left = b
	else:
		if b > up:
			continue
		idx = bisect.bisect_left(L2, b)
		ans -= (M2 - idx) * (left - 2)
		M2 = idx
		up = b
print(ans)


(N, Q) = map(int, input().split())
row = [N - 2] * (N + 2)
col = [N - 2] * (N + 2)
ans = (N - 2) ** 2
miRow = N
miCol = N
for _ in range(Q):
	(q, x) = map(int, input().split())
	if q == 1:
		for i in range(x, miRow + 1):
			row[i] = min(row[i], miCol - 2)
		miRow = min(x, miRow)
		ans -= row[x]
	if q == 2:
		for i in range(x, miCol + 1):
			col[i] = min(col[i], miRow - 2)
		miCol = min(x, miCol)
		ans -= col[x]
print(ans)


import numpy as np
i8 = np.int64

def solve(n, qr):
	col = np.zeros(n - 1, i8)
	col[0] = 0
	col_min = n - 1
	row = np.zeros(n - 1, i8)
	row[0] = 0
	row_min = n - 1
	white = 0
	for i in range(qr.shape[0]):
		j = qr[i, 1] - 1
		if qr[i, 0] == 1:
			if j < col_min:
				white += row_min - 1
				for m in range(j + 1, col_min):
					col[m] = row_min - 1
				col_min = j
			else:
				white += col[j]
		elif j < row_min:
			white += col_min - 1
			for m in range(j + 1, row_min):
				row[m] = col_min - 1
			row_min = j
		else:
			white += row[j]
	return white

def main():
	f = open(0)
	(n, q) = [int(x) for x in f.readline().split()]
	qr = np.fromstring(f.read(), i8, sep=' ').reshape((-1, 2))
	white = solve(n, qr)
	print((n - 2) ** 2 - white)
main()


import sys, collections as cl, bisect as bs
sys.setrecursionlimit(100000)
input = sys.stdin.readline
mod = 10 ** 9 + 7
Max = sys.maxsize

def l():
	return list(map(int, input().split()))

def m():
	return map(int, input().split())

def onem():
	return int(input())

def s(x):
	a = []
	if len(x) == 0:
		return []
	aa = x[0]
	su = 1
	for i in range(len(x) - 1):
		if aa != x[i + 1]:
			a.append([aa, su])
			aa = x[i + 1]
			su = 1
		else:
			su += 1
	a.append([aa, su])
	return a

def jo(x):
	return ' '.join(map(str, x))

def max2(x):
	return max(map(max, x))

def In(x, a):
	k = bs.bisect_left(a, x)
	if k != len(a) and a[k] == x:
		return True
	else:
		return False

def pow_k(x, n):
	ans = 1
	while n:
		if n % 2:
			ans *= x
		x *= x
		n >>= 1
	return ans
(n, q) = m()
ans = (n - 2) ** 2
ta = n - 2
tate = [n - 2 for i in range(n - 2)]
ltate = [0 for i in range(n - 2)]
yo = n - 2
yoko = [n - 2 for i in range(n - 2)]
lyoko = [0 for i in range(n - 2)]
for i in range(q):
	(a, b) = m()
	b -= 2
	if a == 1:
		if ltate[b] == 0:
			ans -= ta
		else:
			ans -= tate[b]
		for j in range(b, n - 2):
			if ltate[j] == 0:
				tate[j] = ta
				ltate[j] = 1
				yo = b
			else:
				break
	else:
		if lyoko[b] == 0:
			ans -= yo
		else:
			ans -= yoko[b]
		for j in range(b, n - 2):
			if lyoko[j] == 0:
				yoko[j] = yo
				lyoko[j] = 1
				ta = b
			else:
				break
print(ans)


import bisect
import sys
input = sys.stdin.readline

def solve():
	(N, Q) = map(int, input().split())
	Qs = []
	for _ in range(Q):
		(i, q) = map(int, input().split())
		Qs.append((i - 1, q))
	M = (N - 2) ** 2
	current_mins = [[(-N, N)], [(-N, N)]]
	for (i, q) in Qs:
		other_min = -current_mins[not i][-1][0]
		j = bisect.bisect(current_mins[i], (-q, other_min))
		if j == 0:
			m = other_min - 2
		else:
			m = current_mins[i][j - 1][1] - 2
		if j == len(current_mins[i]):
			current_mins[i].append((-q, other_min))
			current_mins[not i][-1] = (current_mins[not i][-1][0], q)
		M -= m
	print(M)
solve()


(n, q) = map(int, input().split())
x = n - 2
y = n - 2
dx = {}
dy = {}
for _ in range(q):
	(a, b) = map(int, input().split())
	b -= 1
	if a == 1:
		if y < b:
			dy[b] = 0
			continue
		for i in range(b + 1, y + 1):
			dy[i] = x
		y = b - 1
	if a == 2:
		if x < b:
			dx[b] = 0
			continue
		for i in range(b + 1, x + 1):
			dx[i] = y
		x = b - 1
print(x * y + sum(dx.values()) + sum(dy.values()))


(N, Q) = map(int, input().split())
answer = (N - 2) ** 2
q1 = [(N, N - 2)]
q2 = [(N, N - 2)]

def binary_search(q, n):
	left = 0
	right = len(q) - 1
	while right > left:
		index = (left + right) // 2
		if q[index + 1][0] > n:
			left = index + 1
		else:
			right = index
	return left
for _ in range(Q):
	(n, x) = map(int, input().split())
	if n == 1:
		index = binary_search(q1, x)
		q = q1[index]
		answer -= q[1]
		if index == len(q1) - 1:
			q1.append((x, q[1]))
			q2_last = q2[-1]
			q2[-1] = (q2_last[0], x - 2)
	if n == 2:
		index = binary_search(q2, x)
		q = q2[index]
		answer -= q[1]
		if index == len(q2) - 1:
			q2.append((x, q[1]))
			q1_last = q1[-1]
			q1[-1] = (q1_last[0], x - 2)
print(answer)


def segfunc(x, y):
	return min(x, y)
ide_ele = float('inf')

class SegTree:

	def __init__(self, init_val, segfunc, ide_ele):
		n = len(init_val)
		self.segfunc = segfunc
		self.ide_ele = ide_ele
		self.num = 1 << (n - 1).bit_length()
		self.tree = [ide_ele] * 2 * self.num
		for i in range(n):
			self.tree[self.num + i] = init_val[i]
		for i in range(self.num - 1, 0, -1):
			self.tree[i] = self.segfunc(self.tree[2 * i], self.tree[2 * i + 1])

	def update(self, k, x):
		k += self.num
		self.tree[k] = x
		while k > 1:
			self.tree[k >> 1] = self.segfunc(self.tree[k], self.tree[k ^ 1])
			k >>= 1

	def query(self, l, r):
		res = self.ide_ele
		l += self.num
		r += self.num
		while l < r:
			if l & 1:
				res = self.segfunc(res, self.tree[l])
				l += 1
			if r & 1:
				res = self.segfunc(res, self.tree[r - 1])
			l >>= 1
			r >>= 1
		return res
(N, Q) = map(int, input().split())
black = (N - 2) * (N - 2)
tate = [N - 1] * N
yoko = [N - 1] * N
seg_t = SegTree(tate, segfunc, ide_ele)
seg_y = SegTree(yoko, segfunc, ide_ele)
for i in range(Q):
	(x, y) = map(int, input().split())
	if x == 1:
		xx = seg_t.query(y - 1, N)
		if seg_y.query(xx - 1, xx) > y - 1:
			seg_y.update(xx - 1, y - 1)
		black -= xx - 1
	else:
		xx = seg_y.query(y - 1, N)
		if seg_t.query(xx - 1, xx) > y - 1:
			seg_t.update(xx - 1, y - 1)
		black -= xx - 1
print(black)


(A, B, C, D) = (lambda : map(int, input().split()), range, min, max)
(n, q) = A()
(a, b) = ([n] * n, [n] * n)
(h, w) = (n, n)
E = (n - 2) ** 2
for _ in B(q):
	(Q, x) = A()
	if Q - 1:
		for i in B(x, D(x, h)):
			b[i - 1] = w
		h = C(h, x)
		E -= b[x - 1] - 2
	else:
		for i in B(x, D(x, w)):
			a[i - 1] = h
		w = C(w, x)
		E -= a[x - 1] - 2
print(E)


import sys

def solve():
	input = sys.stdin.readline
	(N, Q) = map(int, input().split())
	total = (N - 2) ** 2
	rb = N
	db = N
	D = [N] * (N + 1)
	R = [N] * (N + 1)
	for _ in range(Q):
		(a, b) = map(int, input().split())
		if a == 1:
			if b < db:
				total -= rb - 2
				for i in range(b, db):
					R[i] = rb
				db = b
			else:
				total -= R[b] - 2
		elif b < rb:
			total -= db - 2
			for i in range(b, rb):
				D[i] = db
			rb = b
		else:
			total -= D[b] - 2
	print(total)
	return 0
solve()


import sys

def input():
	return sys.stdin.readline().strip()

def mapint():
	return map(int, input().split())
sys.setrecursionlimit(10 ** 9)
(N, Q) = mapint()
verti = [N - 2] * (N - 1)
horiz = [N - 2] * (N - 1)
(left, top) = (N - 2, N - 2)
ans = (N - 2) ** 2
last_top = (N - 2, N - 2)
last_left = (N - 2, N - 2)
for _ in range(Q):
	(c, x) = mapint()
	x -= 1
	if c == 1:
		if x <= left:
			ans -= top
			left = x - 1
			for i in range(left, last_left[0] + 1):
				horiz[i] = last_top[1]
			last_left = (left, x - 1)
		else:
			ans -= horiz[x - 1]
	if c == 2:
		if x <= top:
			ans -= left
			top = x - 1
			for i in range(top, last_top[0] + 1):
				verti[i] = last_left[1]
			last_top = (top, x - 1)
		else:
			ans -= verti[x - 1]
print(ans)


(n, q) = map(int, input().split())
(*qu,) = [tuple(map(int, input().split())) for _ in range(q)]
w = n - 2
h = n - 2
wwh = [n - 2] * (n - 2)
hhw = [n - 2] * (n - 2)
b = 0
for (t, x) in qu:
	x -= 2
	if t == 1:
		if x < w:
			b += h
			for i in range(x, w):
				wwh[i] = h
			w = x
		else:
			b += wwh[x]
	elif x < h:
		b += w
		for i in range(x, h):
			hhw[i] = w
		h = x
	else:
		b += hhw[x]
ans = (n - 2) * (n - 2) - b
print(ans)


class LazySegmentTree:

	def __init__(self, op_X, e_X, mapping, compose, id_M, N, array=None):
		__slots__ = ['op_X', 'e_X', 'mapping', 'compose', 'id_M', 'N', 'log', 'N0', 'data', 'lazy']
		self.e_X = e_X
		self.op_X = op_X
		self.mapping = mapping
		self.compose = compose
		self.id_M = id_M
		self.N = N
		self.log = (N - 1).bit_length()
		self.N0 = 1 << self.log
		self.data = [e_X] * (2 * self.N0)
		self.lazy = [id_M] * self.N0
		if array is not None:
			assert N == len(array)
			self.data[self.N0:self.N0 + self.N] = array
			for i in range(self.N0 - 1, 0, -1):
				self.update(i)

	def point_set(self, p, x):
		p += self.N0
		for i in range(self.log, 0, -1):
			self.push(p >> i)
		self.data[p] = x
		for i in range(1, self.log + 1):
			self.update(p >> i)

	def point_get(self, p):
		p += self.N0
		for i in range(self.log, 0, -1):
			self.push(p >> i)
		return self.data[p]

	def prod(self, l, r):
		if l == r:
			return self.e_X
		l += self.N0
		r += self.N0
		for i in range(self.log, 0, -1):
			if l >> i << i != l:
				self.push(l >> i)
			if r >> i << i != r:
				self.push(r >> i)
		sml = smr = self.e_X
		while l < r:
			if l & 1:
				sml = self.op_X(sml, self.data[l])
				l += 1
			if r & 1:
				r -= 1
				smr = self.op_X(self.data[r], smr)
			l >>= 1
			r >>= 1
		return self.op_X(sml, smr)

	def all_prod(s):
		return self.data[1]

	def apply(self, p, f):
		p += self.N0
		for i in range(self.log, 0, -1):
			self.push(p >> i)
		self.data[p] = self.mapping(f, self.data[p])
		for i in range(1, self.log + 1):
			self.update(p >> i)

	def apply(self, l, r, f):
		if l == r:
			return
		l += self.N0
		r += self.N0
		for i in range(self.log, 0, -1):
			if l >> i << i != l:
				self.push(l >> i)
			if r >> i << i != r:
				self.push(r - 1 >> i)
		(l2, r2) = (l, r)
		while l < r:
			if l & 1:
				self.all_apply(l, f)
				l += 1
			if r & 1:
				r -= 1
				self.all_apply(r, f)
			l >>= 1
			r >>= 1
		(l, r) = (l2, r2)
		for i in range(1, self.log + 1):
			if l >> i << i != l:
				self.update(l >> i)
			if r >> i << i != r:
				self.update(r - 1 >> i)

	def max_right(self, l, g):
		if l == self.N:
			return self.N
		l += self.N0
		for i in range(self.log, 0, -1):
			self.push(l >> i)
		sm = self.e_X
		while True:
			while l & 1 == 0:
				l >>= 1
			if not g(self.op_X(sm, self.data[l])):
				while l < self.N0:
					self.push(l)
					l *= 2
					if g(self.op_X(sm, self.data[l])):
						sm = self.op_X(sm, self.data[l])
						l += 1
				return l - self.N0
			sm = self.op_X(sm, self.data[l])
			l += 1
			if l & -l == l:
				break
		return self.N

	def min_left(self, r, g):
		if r == 0:
			return 0
		r += self.N0
		for i in range(self.log, 0, -1):
			self.push(r - 1 >> i)
		sm = self.e_X
		while True:
			r -= 1
			while r > 1 and r & 1:
				r >>= 1
			if not g(self.op_X(self.data[r], sm)):
				while r < self.N0:
					self.push(r)
					r = 2 * r + 1
					if g(self.op_X(self.data[r], sm)):
						sm = self.op_X(self.data[r], sm)
						r -= 1
				return r + 1 - self.N0
			sm = self.op_X(self.data[r], sm)
			if r & -r == r:
				break
		return 0

	def update(self, k):
		self.data[k] = self.op_X(self.data[2 * k], self.data[2 * k + 1])

	def all_apply(self, k, f):
		self.data[k] = self.mapping(f, self.data[k])
		if k < self.N0:
			self.lazy[k] = self.compose(f, self.lazy[k])

	def push(self, k):
		if self.lazy[k] is self.id_M:
			return
		self.data[2 * k] = self.mapping(self.lazy[k], self.data[2 * k])
		self.data[2 * k + 1] = self.mapping(self.lazy[k], self.data[2 * k + 1])
		if 2 * k < self.N0:
			self.lazy[2 * k] = self.compose(self.lazy[k], self.lazy[2 * k])
			self.lazy[2 * k + 1] = self.compose(self.lazy[k], self.lazy[2 * k + 1])
		self.lazy[k] = self.id_M
e_X = 0
id_M = 1 << 32

def op_X(X, Y):
	return ((X + Y >> 32) % MOD << 32) + (X + Y & MASK)

def compose(D, C):
	a = C >> 32
	b = C & MASK
	c = D >> 32
	d = D & MASK
	return (a * c % MOD << 32) + (c * b + d) % MOD

def mapping(C, X):
	x = X >> 32
	v = X & MASK
	a = C >> 32
	b = C & MASK
	return ((x * a + v * b) % MOD << 32) + v
import sys
readline = sys.stdin.readline
read = sys.stdin.read
(n, q) = map(int, readline().split())
lr = [list(map(int, readline().split())) for _ in range(q)]
op_X = min
e_X = n - 1
mapping = min
compose = min
id_M = n - 1
sh = LazySegmentTree(op_X, e_X, mapping, compose, id_M, n, array=[n - 1] * (n - 1) + [0])
sw = LazySegmentTree(op_X, e_X, mapping, compose, id_M, n, array=[n - 1] * (n - 1) + [0])
ans = (n - 2) ** 2
for (t, x) in lr:
	x -= 1
	if t == 1:
		idx = sw.point_get(x)
		sh.apply(1, idx, x)
		ans -= idx - 1
	else:
		idx = sh.point_get(x)
		sw.apply(1, idx, x)
		ans -= idx - 1
print(ans)


import sys
input = sys.stdin.readline
(n, q) = map(int, input().split())
nm2 = n - 2
ans = nm2 ** 2
a = [-1] * nm2
b = [-1] * nm2
waku_h = nm2
waku_w = nm2
for _ in range(q):
	(t, x) = map(int, input().split())
	x -= 2
	if t == 1:
		if x < waku_w:
			ans -= waku_h
			for i in range(x + 1, waku_w):
				b[i] = waku_h
			waku_w = x
		else:
			ans -= b[x]
	elif x < waku_h:
		ans -= waku_w
		for i in range(x + 1, waku_h):
			a[i] = waku_w
		waku_h = x
	else:
		ans -= a[x]
print(ans)


(n, q) = map(int, input().split())
query = [list(map(int, input().split())) for _ in range(q)]
ans = (n - 2) ** 2
x = [n] * (n + 1)
y = [n] * (n + 1)
xm = ym = n
for (a, b) in query:
	if a == 1:
		if b < xm:
			y[b:xm] = [ym] * (xm - b)
			xm = b
		ans -= y[b] - 2
	else:
		if b < ym:
			x[b:ym] = [xm] * (ym - b)
			ym = b
		ans -= x[b] - 2
print(ans)


from collections import defaultdict, deque
from heapq import heappush, heappop
from bisect import bisect_left, bisect_right
import sys, random, itertools, math
sys.setrecursionlimit(10 ** 5)
input = sys.stdin.readline
sqrt = math.sqrt

def LI():
	return list(map(int, input().split()))

def LF():
	return list(map(float, input().split()))

def LI_():
	return list(map(lambda x: int(x) - 1, input().split()))

def II():
	return int(input())

def IF():
	return float(input())

def S():
	return input().rstrip()

def LS():
	return S().split()

def IR(n):
	return [II() for _ in range(n)]

def LIR(n):
	return [LI() for _ in range(n)]

def FR(n):
	return [IF() for _ in range(n)]

def LFR(n):
	return [LI() for _ in range(n)]

def LIR_(n):
	return [LI_() for _ in range(n)]

def SR(n):
	return [S() for _ in range(n)]

def LSR(n):
	return [LS() for _ in range(n)]
mod = 1000000007
inf = float('INF')

def solve():
	(n, q) = LI()
	v = [n] * n
	h = [n] * n
	c = n
	r = n
	ans = 0
	for _ in range(q):
		(q, x) = LI()
		if q == 1:
			if c < x:
				ans += v[x] - 2
			else:
				ans += r - 2
				for i in range(x, c):
					v[i] = r
				c = x
		elif r < x:
			ans += h[x] - 2
		else:
			ans += c - 2
			for i in range(x, r):
				h[i] = c
			r = x
	print((n - 2) ** 2 - ans)
	return
solve()


class LazySegmentTree:
	__slots__ = ['n', 'data', 'lazy', 'me', 'oe', 'fmm', 'fmo', 'foo']

	def __init__(self, monoid_data, monoid_identity, operator_identity, func_monoid_monoid, func_monoid_operator, func_operator_operator):
		self.me = monoid_identity
		self.oe = operator_identity
		self.fmm = func_monoid_monoid
		self.fmo = func_monoid_operator
		self.foo = func_operator_operator
		self.n = len(monoid_data)
		self.data = monoid_data * 2
		for i in range(self.n - 1, 0, -1):
			self.data[i] = self.fmm(self.data[2 * i], self.data[2 * i + 1])
		self.lazy = [self.oe] * (self.n * 2)

	def replace(self, index, value):
		index += self.n
		for shift in range(index.bit_length() - 1, 0, -1):
			i = index >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		self.data[index] = value
		self.lazy[index] = self.oe
		i = index
		while i > 1:
			i //= 2
			self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
			self.lazy[i] = self.oe

	def effect(self, l, r, operator):
		l += self.n
		r += self.n
		l0 = l
		r0 = r - 1
		while l0 % 2 == 0:
			l0 //= 2
		while r0 % 2 == 1:
			r0 //= 2
		for shift in range(l0.bit_length() - 1, 0, -1):
			i = l0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		for shift in range(r0.bit_length() - 1, 0, -1):
			i = r0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		while l < r:
			if l % 2:
				self.lazy[l] = self.foo(self.lazy[l], operator)
				l += 1
			if r % 2:
				r -= 1
				self.lazy[r] = self.foo(self.lazy[r], operator)
			l //= 2
			r //= 2
		i = l0
		while i > 1:
			i //= 2
			self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
			self.lazy[i] = self.oe
		i = r0
		while i > 1:
			i //= 2
			self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
			self.lazy[i] = self.oe

	def folded(self, l, r):
		l += self.n
		r += self.n
		l0 = l
		r0 = r - 1
		while l0 % 2 == 0:
			l0 //= 2
		while r0 % 2 == 1:
			r0 //= 2
		for shift in range(l0.bit_length() - 1, 0, -1):
			i = l0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		for shift in range(r0.bit_length() - 1, 0, -1):
			i = r0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		left_folded = self.me
		right_folded = self.me
		while l < r:
			if l % 2:
				left_folded = self.fmm(left_folded, self.fmo(self.data[l], self.lazy[l]))
				l += 1
			if r % 2:
				r -= 1
				right_folded = self.fmm(self.fmo(self.data[r], self.lazy[r]), right_folded)
			l //= 2
			r //= 2
		return self.fmm(left_folded, right_folded)

def yosupo():
	import sys
	input = sys.stdin.buffer.readline
	whitened = 0
	(N, Q) = map(int, input().split())
	xs = LazySegmentTree([N - 2] * (N - 2), N - 2, N - 2, min, min, min)
	ys = LazySegmentTree([N - 2] * (N - 2), N - 2, N - 2, min, min, min)
	for _ in range(Q):
		(t, x) = map(int, input().split())
		x -= 2
		if t == 1:
			tmp = xs.folded(x, x + 1)
			ys.effect(0, tmp, x)
			whitened += tmp
		else:
			tmp = ys.folded(x, x + 1)
			xs.effect(0, tmp, x)
			whitened += tmp
	print((N - 2) ** 2 - whitened)
yosupo()


import sys
input = sys.stdin.readline
(N, Q) = map(int, input().split())
row = [-1] * (N - 2)
col = [-1] * (N - 2)
a = b = N - 2
ans = (N - 2) ** 2
for _ in range(Q):
	(t, x) = map(int, input().split())
	x -= 2
	if t == 1:
		if col[x] == -1:
			ans -= b
		else:
			ans -= col[x]
		a = min(a, x)
		for i in range(x, N - 2):
			if col[i] != -1:
				break
			col[i] = b
	else:
		if row[x] == -1:
			ans -= a
		else:
			ans -= row[x]
		b = min(b, x)
		for i in range(x, N - 2):
			if row[i] != -1:
				break
			row[i] = a
print(ans)


def main():
	import sys
	input = sys.stdin.readline
	sys.setrecursionlimit(10 ** 7)
	from collections import Counter, deque
	from collections import defaultdict
	from itertools import combinations, permutations, accumulate, groupby, product
	from bisect import bisect_left, bisect_right
	from heapq import heapify, heappop, heappush
	from math import floor, ceil, pi, factorial
	from operator import itemgetter

	def I():
		return int(input())

	def MI():
		return map(int, input().split())

	def LI():
		return list(map(int, input().split()))

	def LI2():
		return [int(input()) for i in range(n)]

	def MXI():
		return [[LI()] for i in range(n)]

	def SI():
		return input().rstrip()

	def printns(x):
		print('\n'.join(x))

	def printni(x):
		print('\n'.join(list(map(str, x))))
	inf = 10 ** 17
	mod = 10 ** 9 + 7
	(n, q) = MI()
	ans = (n - 2) ** 2
	x = n
	y = n
	xlist = [n for i in range(n - 2)]
	ylist = [n for i in range(n - 2)]
	for i in range(q):
		(a, b) = MI()
		if a == 1:
			if b < x:
				ans -= y - 2
				for i in range(b, x):
					ylist[i - 2] = y
				x = b
			else:
				ans -= ylist[b - 2] - 2
		elif b < y:
			ans -= x - 2
			for i in range(b, y):
				xlist[i - 2] = x
			y = b
		else:
			ans -= xlist[b - 2] - 2
	print(ans)
main()


class LazySegmentTree:
	__slots__ = ['n', 'data', 'lazy', 'me', 'oe', 'fmm', 'fmo', 'foo']

	def __init__(self, monoid_data, monoid_identity, operator_identity, func_monoid_monoid, func_monoid_operator, func_operator_operator):
		self.me = monoid_identity
		self.oe = operator_identity
		self.fmm = func_monoid_monoid
		self.fmo = func_monoid_operator
		self.foo = func_operator_operator
		self.n = len(monoid_data)
		self.data = monoid_data * 2
		for i in range(self.n - 1, 0, -1):
			self.data[i] = self.fmm(self.data[2 * i], self.data[2 * i + 1])
		self.lazy = [self.oe] * (self.n * 2)

	def replace(self, index, value):
		index += self.n
		for shift in range(index.bit_length() - 1, 0, -1):
			i = index >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		self.data[index] = value
		self.lazy[index] = self.oe
		i = index
		while i > 1:
			i //= 2
			self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
			self.lazy[i] = self.oe

	def effect(self, l, r, operator):
		l += self.n
		r += self.n
		l0 = l
		r0 = r - 1
		while l0 % 2 == 0:
			l0 //= 2
		while r0 % 2 == 1:
			r0 //= 2
		for shift in range(l0.bit_length() - 1, 0, -1):
			i = l0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		for shift in range(r0.bit_length() - 1, 0, -1):
			i = r0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		while l < r:
			if l % 2:
				self.lazy[l] = self.foo(self.lazy[l], operator)
				l += 1
			if r % 2:
				r -= 1
				self.lazy[r] = self.foo(self.lazy[r], operator)
			l //= 2
			r //= 2
		i = l0
		while i > 1:
			i //= 2
			self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
			self.lazy[i] = self.oe
		i = r0
		while i > 1:
			i //= 2
			self.data[i] = self.fmm(self.fmo(self.data[2 * i], self.lazy[2 * i]), self.fmo(self.data[2 * i + 1], self.lazy[2 * i + 1]))
			self.lazy[i] = self.oe

	def folded(self, l, r):
		l += self.n
		r += self.n
		l0 = l
		r0 = r - 1
		while l0 % 2 == 0:
			l0 //= 2
		while r0 % 2 == 1:
			r0 //= 2
		for shift in range(l0.bit_length() - 1, 0, -1):
			i = l0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		for shift in range(r0.bit_length() - 1, 0, -1):
			i = r0 >> shift
			self.lazy[2 * i] = self.foo(self.lazy[2 * i], self.lazy[i])
			self.lazy[2 * i + 1] = self.foo(self.lazy[2 * i + 1], self.lazy[i])
			self.data[i] = self.fmo(self.data[i], self.lazy[i])
			self.lazy[i] = self.oe
		left_folded = self.me
		right_folded = self.me
		while l < r:
			if l % 2:
				left_folded = self.fmm(left_folded, self.fmo(self.data[l], self.lazy[l]))
				l += 1
			if r % 2:
				r -= 1
				right_folded = self.fmm(self.fmo(self.data[r], self.lazy[r]), right_folded)
			l //= 2
			r //= 2
		return self.fmm(left_folded, right_folded)
import sys
input = sys.stdin.readline

def fmo(m1, o1):
	if o1 == -1:
		return m1
	return o1

def foo(o1, o2):
	if o2 == -1:
		return o1
	return o2
(n, q) = map(int, input().split())
ans = (n - 2) * (n - 2)
h = n - 2
w = n - 2
LR = LazySegmentTree([-2] * n, h, -1, min, fmo, foo)
DU = LazySegmentTree([-2] * n, w, -1, min, fmo, foo)
for _ in range(q):
	(t, x) = map(int, input().split())
	x -= 1
	if t == 1:
		temp = LR.folded(x, x + 1)
		if temp == -2:
			ans -= h
			LR.effect(x + 1, w + 1, h)
			w = x - 1
		else:
			ans -= temp
	else:
		temp = DU.folded(x, x + 1)
		if temp == -2:
			ans -= w
			DU.effect(x + 1, h + 1, w)
			h = x - 1
		else:
			ans -= temp
print(ans)


from collections import deque
from bisect import bisect_left, bisect_right
(n, q) = map(int, input().split())
list_x = deque()
list_y = deque()
memo_x = deque()
memo_y = deque()
(x_now, y_now) = (n - 1, n - 1)
ans = (n - 2) ** 2
for i in range(q):
	(flg, x) = map(int, input().split())
	if flg == 1:
		if x_now >= x:
			ans -= y_now - 1
			x_now = x - 1
			list_x.appendleft(x)
			memo_x.appendleft(y_now - 1)
		else:
			tmp = bisect_left(list_x, x) - 1
			ans -= memo_x[tmp]
	else:
		y = x
		if y_now >= y:
			ans -= x_now - 1
			y_now = y - 1
			list_y.appendleft(y)
			memo_y.appendleft(x_now - 1)
		else:
			tmp = bisect_left(list_y, y) - 1
			ans -= memo_y[tmp]
print(ans)


class LazySegmentTree:

	def __init__(self, data, default=0, func=max):
		self._default = default
		self._func = func
		self._len = len(data)
		self._size = _size = 1 << (self._len - 1).bit_length()
		self._lazy = [0] * (2 * _size)
		self.data = [default] * (2 * _size)
		self.data[_size:_size + self._len] = data
		for i in reversed(range(_size)):
			self.data[i] = func(self.data[i + i], self.data[i + i + 1])

	def __len__(self):
		return self._len

	def _push(self, idx):
		(q, self._lazy[idx]) = (self._lazy[idx], 0)
		self._lazy[2 * idx] = self._func(self._lazy[2 * idx], q)
		self._lazy[2 * idx + 1] = self._func(self._lazy[2 * idx + 1], q)
		self.data[2 * idx] = self._func(self.data[2 * idx], q)
		self.data[2 * idx + 1] = self._func(self.data[2 * idx + 1], q)

	def _update(self, idx):
		for i in reversed(range(1, idx.bit_length())):
			self._push(idx >> i)

	def _build(self, idx):
		idx >>= 1
		while idx:
			self.data[idx] = self._func(self._func(self.data[2 * idx], self.data[2 * idx + 1]), self._lazy[idx])
			idx >>= 1

	def update(self, start, stop, value):
		start = start_copy = start + self._size
		stop = stop_copy = stop + self._size
		while start < stop:
			if start & 1:
				self._lazy[start] = self._func(self._lazy[start], value)
				self.data[start] = self._func(self.data[start], value)
				start += 1
			if stop & 1:
				stop -= 1
				self._lazy[stop] = self._func(self._lazy[stop], value)
				self.data[stop] = self._func(self.data[stop], value)
			start >>= 1
			stop >>= 1
		self._build(start_copy)
		self._build(stop_copy - 1)

	def query(self, start, stop, default=0):
		start += self._size
		stop += self._size
		self._update(start)
		self._update(stop - 1)
		res = default
		while start < stop:
			if start & 1:
				res = self._func(res, self.data[start])
				start += 1
			if stop & 1:
				stop -= 1
				res = self._func(res, self.data[stop])
			start >>= 1
			stop >>= 1
		return res

	def __repr__(self):
		return 'LazySegmentTree({0})'.format(self.data)

def solve(N, Q, queries):
	N -= 2
	total = N * N
	rows = LazySegmentTree([0] * N, 0, max)
	cols = LazySegmentTree([0] * N, 0, max)
	for (t, x) in queries:
		assert x >= 2
		x -= 2
		if t == 1:
			c = x
			removed = N - cols.query(c, c + 1)
			assert removed >= 0
			total -= removed
			assert total >= 0
			cols.update(c, c + 1, N)
			rows.update(0, removed, N - c)
		elif t == 2:
			r = x
			removed = N - rows.query(r, r + 1)
			assert removed >= 0
			total -= removed
			assert total >= 0
			rows.update(r, r + 1, N)
			cols.update(0, removed, N - r)
	return total
if False:
	import random
	random.seed(0)
	for _ in range(100):
		print(_)
		N = random.randint(3, 10)
		queries = []
		for i in range(2, N):
			queries.append((1, i))
			queries.append((2, i))
		random.shuffle(queries)
		Q = random.randint(0, min(2 * N - 4, 10))
		queries = queries[:Q]
		print(queries)
		solve(N, len(queries), queries)
(N, Q) = [int(x) for x in input().split()]
queries = [[int(x) for x in input().split()] for i in range(Q)]
print(solve(N, Q, queries))


import sys
iim = lambda : map(int, sys.stdin.readline().rstrip().split())

def resolve():
	(N, Q) = iim()
	it = map(int, sys.stdin.read().split())
	M = N + 1 if N & 1 else N
	NM = 1 << M.bit_length()
	ans = (N - 2) ** 2
	A = [[N - 2] * (NM + M) for i in range(2)]

	def set(a, i, j, x):
		i += NM
		j += NM
		while i < j:
			a[i] = min(a[i], x)
			if i & 1:
				i += 1
			a[j] = min(a[j], x)
			if j & 1 == 0:
				j -= 1
			i >>= 1
			j >>= 1
		a[i] = min(a[i], x)

	def get(a, i):
		i += NM
		ans = a[i]
		while i > 0:
			i >>= 1
			ans = min(ans, a[i])
		return ans
	for (q, i) in zip(it, it):
		q -= 1
		i -= 2
		val = get(A[q], i)
		ans -= val
		set(A[q ^ 1], 0, val, i)
	print(ans)
resolve()


import sys
input = lambda : sys.stdin.readline().rstrip()
sys.setrecursionlimit(max(1000, 10 ** 9))
write = lambda x: sys.stdout.write(x + '\n')

class LazySegmentTree:

	def __init__(self, n, a=None):
		num = 1
		while num <= n:
			num *= 2
		self.num = num
		self.seg = [ninf] * (2 * self.num - 1)
		self.lazy = [f0] * (2 * self.num - 1)
		self.ls = [0] * (2 * self.num - 1)
		self.rs = [0] * (2 * self.num - 1)
		self.ls[0] = 0
		self.rs[0] = self.num
		for i in range(self.num - 1):
			self.ls[2 * i + 1] = self.ls[i]
			self.rs[2 * i + 1] = (self.ls[i] + self.rs[i]) // 2
			self.ls[2 * i + 2] = (self.ls[i] + self.rs[i]) // 2
			self.rs[2 * i + 2] = self.rs[i]
		if a is not None:
			assert len(a) == n
			for i in range(n):
				self.seg[num - 1 + i] = a[i]
			for k in range(num - 2, -1, -1):
				self.seg[k] = op(self.seg[2 * k + 1], self.seg[2 * k + 2])

	def eval(self, k):
		if self.lazy[k] == f0:
			return
		if k < self.num - 1:
			self.lazy[k * 2 + 1] = composition(self.lazy[k], self.lazy[k * 2 + 1])
			self.lazy[k * 2 + 2] = composition(self.lazy[k], self.lazy[k * 2 + 2])
		self.seg[k] = mapping(self.lazy[k], self.seg[k])
		self.lazy[k] = f0

	def eval_all(self):
		for i in range(2 * self.num - 1):
			self.eval(i)

	def update(self, a, b, x=None, f=None):
		if f is None:
			f = lambda y: x
		k = 0
		q = [k]
		while q:
			k = q.pop()
			(l, r) = (self.ls[k], self.rs[k])
			if k >= 0:
				self.eval(k)
				if r <= a or b <= l:
					continue
				elif a <= l and r <= b:
					self.lazy[k] = composition(f, self.lazy[k])
					self.eval(k)
				else:
					q.append(~k)
					q.append(2 * k + 1)
					q.append(2 * k + 2)
			else:
				k = ~k
				self.seg[k] = op(self.seg[2 * k + 1], self.seg[2 * k + 2])

	def query(self, a, b):
		k = 0
		l = 0
		r = self.num
		q = [k]
		ans = ninf
		while q:
			k = q.pop()
			(l, r) = (self.ls[k], self.rs[k])
			self.eval(k)
			if r <= a or b <= l:
				continue
			elif a <= l and r <= b:
				ans = op(ans, self.seg[k])
			else:
				q.append(2 * k + 2)
				q.append(2 * k + 1)
		return ans
(n, q) = list(map(int, input().split()))
ninf = 10 ** 15
op = lambda x, y: min(x, y)
mapping = lambda f, x: min(f, x) if f is not None else x

def composition(f1, f2):
	if f1 is not None:
		if f2 is not None:
			return min(f1, f2)
		else:
			return f1
	else:
		return f2
f0 = None
sgr = LazySegmentTree(n - 2, [n] * (n - 2))
sgc = LazySegmentTree(n - 2, [n] * (n - 2))
ans = 0
for _ in range(q):
	(t, x) = map(int, input().split())
	x -= 2
	if t == 1:
		v = sgc.query(x, x + 1)
		ans += v - 2
		sgr.update(0, v - 2, f=x + 2)
	else:
		v = sgr.query(x, x + 1)
		ans += v - 2
		sgc.update(0, v - 2, f=x + 2)
ans = (n - 2) ** 2 - ans
print(ans)


def f(i, m, cnt):
	while True:
		if i > n or not cnt[i] == inf:
			return
		cnt[i] = m
		i += 1
(n, q) = map(int, input().split())
inf = n + 114514
ans = (n - 2) * (n - 2)
(cnt1, cnt2) = ([inf] * (n + 1), [inf] * (n + 1))
(max1, max2) = (n - 2, n - 2)
for _ in range(q):
	(t, x) = map(int, input().split())
	if t == 1:
		if cnt1[x] == inf:
			ans -= max2
			max1 = x - 2
			f(x, max2, cnt1)
		else:
			ans -= cnt1[x]
	elif cnt2[x] == inf:
		ans -= max1
		max2 = x - 2
		f(x, max1, cnt2)
	else:
		ans -= cnt2[x]
print(ans)


class SegTree:

	def __init__(self, initial, operation, identity):
		n = len(initial)
		self.initial = initial
		self.operation = operation
		self.identity = identity
		self.num = 1 << len(bin(n - 1)) - 2
		self.tree = [identity] * (2 * self.num - 1)
		for i in range(n):
			self.tree[i + self.num - 1] = self.initial[i]
		for i in reversed(range(self.num - 1)):
			self.tree[i] = min(self.tree[2 * i + 1], self.tree[2 * i + 2])

	def update(self, k, x):
		k += self.num - 1
		self.tree[k] = x
		while k >= 1:
			k = (k - 1) // 2
			self.tree[k] = self.operation(self.tree[2 * k + 1], self.tree[2 * k + 2])

	def query(self, l, r):
		res = self.identity
		l += self.num - 1
		r += self.num - 1
		while l < r:
			if l % 2 == 0:
				res = self.operation(res, self.tree[l])
				l += 1
			if r % 2 == 0:
				res = self.operation(res, self.tree[r - 1])
			l = (l - 1) // 2
			r = (r - 1) // 2
		return res
(N, Q) = [int(i) for i in input().split()]
(H, W) = (SegTree([N] * N, min, N), SegTree([N] * N, min, N))
revd = 0
for _ in range(Q):
	(t, x) = [int(i) for i in input().split()]
	if t == 1:
		h = H.query(x, N + 1)
		w = W.query(h, N + 1)
		revd += h - 2
		W.update(h, min(x, w))
	else:
		w = W.query(x, N + 1)
		h = H.query(w, N + 1)
		revd += w - 2
		H.update(w, min(x, h))
ans = (N - 2) * (N - 2) - revd
print(ans)


(N, Q) = map(int, input().split())
rcx = [tuple(map(int, input().split())) for _ in range(Q)]
(thres_1, thres_2) = (N - 2, N - 2)
nearest_white_1 = [0] * (N - 2)
nearest_white_2 = [0] * (N - 2)
reverse_count = 0
for (rc, x) in rcx:
	x = x - 2
	if rc == 1:
		if x < thres_1:
			for i in range(x + 1, thres_1):
				nearest_white_1[i] = thres_2
			thres_1 = x
			reverse_count += thres_2
		else:
			reverse_count += nearest_white_1[x]
	elif x < thres_2:
		for i in range(x + 1, thres_2):
			nearest_white_2[i] = thres_1
		reverse_count += thres_1
		thres_2 = x
	else:
		reverse_count += nearest_white_2[x]
print((N - 2) ** 2 - reverse_count)


import sys
import numpy as np

def main():
	(N, Q) = list(map(int, sys.stdin.readline().rstrip().split()))
	H = np.array([0] * (N - 1))
	W = np.array([0] * (N - 1))
	black = (N - 2) ** 2
	Hmin = N - 1
	Wmin = N - 1
	for i in range(Q):
		(n, x) = list(map(int, sys.stdin.readline().rstrip().split()))
		if n == 1:
			if x - 1 <= Wmin:
				W[x - 1:Wmin] = Hmin - 1
				Wmin = x - 1
			black -= W[x - 1]
		else:
			if x - 1 <= Hmin:
				H[x - 1:Hmin] = Wmin - 1
				Hmin = x - 1
			black -= H[x - 1]
	print(black)
main()


class LazySegmentTree:

	def __init__(self, op, e, mapping, composition, im, init_array):
		self.op = op
		self.e = e
		self.mapping = mapping
		self.composition = composition
		self.im = im
		l = len(init_array)

		def ceil_pow2(n):
			x = 0
			while 1 << x < n:
				x += 1
			return x
		self.log = ceil_pow2(l)
		self.size = 1 << self.log
		self.d = [e() for _ in range(2 * self.size)]
		self.lz = [im() for _ in range(self.size)]
		for (i, a) in enumerate(init_array):
			self.d[i + self.size] = a
		for i in range(self.size - 1, 0, -1):
			self.__update(i)

	def set(self, p, x):
		p += self.size
		for i in range(self.log, 0, -1):
			self.__push(p >> i)
		self.d[p] = x
		for i in range(1, self.log + 1):
			self.__update(p >> i)

	def __getitem__(self, p):
		p += self.size
		for i in range(self.log, 0, -1):
			self.__push(p >> i)
		return self.d[p]

	def prod(self, l, r):
		if l == r:
			return self.e()
		l += self.size
		r += self.size
		for i in range(self.log, 0, -1):
			if l >> i << i != l:
				self.__push(l >> i)
			if r >> i << i != r:
				self.__push(r >> i)
		sml = self.e()
		smr = self.e()
		while l < r:
			if l & 1:
				sml = self.op(sml, self.d[l])
				l += 1
			if r & 1:
				r -= 1
				smr = self.op(self.d[r], smr)
			l >>= 1
			r >>= 1
		return self.op(sml, smr)

	def apply(self, l, r, f):
		if l == r:
			return
		l += self.size
		r += self.size
		for i in range(self.log, 0, -1):
			if l >> i << i != l:
				self.__push(l >> i)
			if r >> i << i != r:
				self.__push(r - 1 >> i)
		(l2, r2) = (l, r)
		while l < r:
			if l & 1:
				self.__all_apply(l, f)
				l += 1
			if r & 1:
				r -= 1
				self.__all_apply(r, f)
			l >>= 1
			r >>= 1
		(l, r) = (l2, r2)
		for i in range(1, self.log + 1):
			if l >> i << i != l:
				self.__update(l >> i)
			if r >> i << i != r:
				self.__update(r - 1 >> i)

	def __update(self, k):
		self.d[k] = self.op(self.d[2 * k], self.d[2 * k + 1])

	def __all_apply(self, k, f):
		self.d[k] = self.mapping(f, self.d[k])
		if k < self.size:
			self.lz[k] = self.composition(f, self.lz[k])

	def __push(self, k):
		self.__all_apply(2 * k, self.lz[k])
		self.__all_apply(2 * k + 1, self.lz[k])
		self.lz[k] = self.im()

def op(x, y):
	return x + y

def mapping(x, y):
	return min(x, y)

def composition(x, y):
	return min(x, y)

def im():
	return 100000000000

def a():
	import sys
	input = sys.stdin.buffer.readline
	(N, Q) = map(int, input().split())

	def e():
		return N - 2
	ans = (N - 2) * (N - 2)
	ssss = [N - 2] * (N - 1)
	st = LazySegmentTree(op, e, mapping, composition, im, ssss)
	sa = LazySegmentTree(op, e, mapping, composition, im, ssss)
	for _ in range(Q):
		(t, l) = map(int, input().split())
		if t == 1:
			t = st.__getitem__(l - 1) + 1
			sa.apply(1, t, l - 2)
			ans -= t - 1
		else:
			t = sa.__getitem__(l - 1) + 1
			st.apply(1, t, l - 2)
			ans -= t - 1
	print(ans)
a()


import sys
from operator import ge

def input():
	return sys.stdin.readline().strip()

def list2d(a, b, c):
	return [[c for j in range(b)] for i in range(a)]

def list3d(a, b, c, d):
	return [[[d for k in range(c)] for j in range(b)] for i in range(a)]

def list4d(a, b, c, d, e):
	return [[[[e for l in range(d)] for k in range(c)] for j in range(b)] for i in range(a)]

def ceil(x, y=1):
	return int(-(-x // y))

def INT():
	return int(input())

def MAP():
	return map(int, input().split())

def LIST(N=None):
	return list(MAP()) if N is None else [INT() for i in range(N)]

def Yes():
	print('Yes')

def No():
	print('No')

def YES():
	print('YES')

def NO():
	print('NO')
sys.setrecursionlimit(10 ** 9)
INF = 10 ** 19
MOD = 10 ** 9 + 7
EPS = 10 ** (-10)

class SegTree:

	def __init__(self, n, func, intv, A=[]):
		self.n = n
		self.func = func
		self.intv = intv
		n2 = 1
		while n2 < n:
			n2 <<= 1
		self.n2 = n2
		self.tree = [self.intv] * (n2 << 1)
		if A:
			for i in range(n):
				self.tree[n2 + i] = A[i]
			for i in range(n2 - 1, -1, -1):
				self.tree[i] = self.func(self.tree[i * 2], self.tree[i * 2 + 1])

	def update(self, i, x):
		i += self.n2
		self.tree[i] = x
		while i > 0:
			i >>= 1
			self.tree[i] = self.func(self.tree[i * 2], self.tree[i * 2 + 1])

	def add(self, i, x):
		self.update(i, self.get(i) + x)

	def query(self, a, b):
		l = a + self.n2
		r = b + self.n2
		s = self.intv
		while l < r:
			if r & 1:
				r -= 1
				s = self.func(s, self.tree[r])
			if l & 1:
				s = self.func(s, self.tree[l])
				l += 1
			l >>= 1
			r >>= 1
		return s

	def get(self, i):
		return self.tree[i + self.n2]

	def all(self):
		return self.tree[1]

	def bisearch_fore(self, l, r, x, func):
		ok = r + 1
		ng = l - 1
		while ng + 1 < ok:
			mid = (ok + ng) // 2
			if func(self.query(l, mid + 1), x):
				ok = mid
			else:
				ng = mid
		if ok != r + 1:
			return ok
		else:
			return INF

	def print(self):
		for i in range(self.n):
			print(self.get(i), end=' ')
		print()
(N, Q) = MAP()
ans = (N - 2) * (N - 2)
seg1 = SegTree(N + 1, max, -INF, [0] * (N + 1))
seg2 = SegTree(N + 1, max, -INF, [0] * (N + 1))
seg1.update(N, N)
seg2.update(N, N)
for _ in range(Q):
	(t, x) = MAP()
	if t == 1:
		res = seg1.bisearch_fore(0, N, x, ge)
		ans -= res - 2
		seg2.update(x, res)
	else:
		res = seg2.bisearch_fore(0, N, x, ge)
		ans -= res - 2
		seg1.update(x, res)
print(ans)


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
MOD = 998244353

class BIT2:

	def __init__(self, N):
		self.N = N + 1
		self.data0 = [0] * (N + 1)
		self.data1 = [0] * (N + 1)

	def _add(self, data, k, x):
		while k < self.N:
			data[k] += x
			k += k & -k

	def _sum(self, data, k):
		s = 0
		while k:
			s += data[k]
			k -= k & -k
		return s

	def add(self, l, r, x):
		self._add(self.data0, l, -x * (l - 1))
		self._add(self.data0, r, x * (r - 1))
		self._add(self.data1, l, x)
		self._add(self.data1, r, -x)

	def sum(self, l, r):
		return self._sum(self.data1, r - 1) * (r - 1) + self._sum(self.data0, r - 1) - self._sum(self.data1, l - 1) * (l - 1) - self._sum(self.data0, l - 1)
(N, Q) = map(int, readline().split())
bit1 = BIT2(N)
bit1.add(1, N + 1, N - 2)
bit2 = BIT2(N)
bit2.add(1, N + 1, N - 2)
total = (N - 2) ** 2
right = N
low = N
cnt = 0
for _ in range(Q):
	(cmd, t) = map(int, readline().split())
	if cmd == 1:
		tmp = bit1.sum(t, t + 1)
		cnt += tmp
		bit1.add(t, t + 1, -tmp)
		if t < right:
			bit2.add(1, low, t - right)
			right = t
	else:
		tmp = bit2.sum(t, t + 1)
		cnt += tmp
		bit2.add(t, t + 1, -tmp)
		if t < low:
			bit1.add(1, right, t - low)
			low = t
ans = total - cnt
print(ans)


(n, q) = map(int, input().split())
query = [list(map(int, input().split())) for _ in range(q)]
ans = (n - 2) ** 2
(cnt, wh) = ([n - 2, n - 2], [[None] * (n - 2), [None] * (n - 2)])
for (num, x) in query:
	(num, x) = (num - 1, x - 2)
	if cnt[num] > x:
		wh[num][x:cnt[num]] = [cnt[1 - num]] * (cnt[num] - x)
		cnt[num] = x
	ans -= wh[num][x]
	wh[num][x] = 0
print(ans)


import sys
input = sys.stdin.readline

def main():
	(n, q) = list(map(int, input().split()))
	ans = (n - 2) ** 2
	h = n
	w = n
	a = [n for _ in range(n)]
	b = [n for _ in range(n)]
	for _ in range(q):
		(t, x) = list(map(int, input().split()))
		if t == 1:
			if x < w:
				for i in range(x, w):
					a[i] = h
				w = x
			ans -= a[x] - 2
		else:
			if x < h:
				for i in range(x, h):
					b[i] = w
				h = x
			ans -= b[x] - 2
	print(ans)

def __starting_point():
	main()
__starting_point()


(N, Q) = map(int, input().split())
ANS = (N - 2) ** 2
(R, C) = (N, N)
RLEN = []
CLEN = []
for i in range(Q):
	(RC, num) = map(int, input().split())
	if RC == 1:
		if R > num:
			for j in range(R - num):
				RLEN.append(C)
			ANS -= C - 2
			R = num
		elif len(RLEN) > 0:
			ANS -= RLEN[N - num - 1] - 2
		else:
			ANS -= R - 2
	elif C > num:
		for j in range(C - num):
			CLEN.append(R)
		ANS -= R - 2
		C = num
	elif len(CLEN) > 0:
		ANS -= CLEN[N - num - 1] - 2
	else:
		ANS -= C - 2
print(ANS)


import sys
sys.setrecursionlimit(500000)

def input():
	return sys.stdin.readline()[:-1]

class SegmentTree:

	def __init__(self, L, op, ide):
		self.op = op
		self.ide = ide
		self.sz = len(L)
		self.n = 1
		self.s = 1
		for i in range(1000):
			self.n *= 2
			self.s += 1
			if self.n >= self.sz:
				break
		self.node = [self.ide] * (2 * self.n - 1)
		for i in range(self.sz):
			self.node[i + self.n - 1] = L[i]
		for i in range(self.n - 2, -1, -1):
			self.node[i] = self.op(self.node[i * 2 + 1], self.node[i * 2 + 2])

	def add(self, a, x):
		k = a + self.n - 1
		self.node[k] += x
		for i in range(1000):
			k = (k - 1) // 2
			self.node[k] = self.op(self.node[2 * k + 1], self.node[2 * k + 2])
			if k <= 0:
				break

	def substitute(self, a, x):
		k = a + self.n - 1
		self.node[k] = self.op(x, self.node[k])
		for i in range(1000):
			k = (k - 1) // 2
			self.node[k] = self.op(self.node[2 * k + 1], self.node[2 * k + 2])
			if k <= 0:
				break

	def get_one(self, a):
		k = a + self.n - 1
		return self.node[k]

	def get(self, l, r):
		res = self.ide
		n = self.n
		if self.sz <= r or 0 > l:
			return False
		for i in range(self.s):
			count = 2 ** i - 1
			a = (r + 1) // n
			b = (l - 1) // n
			if a - b == 3:
				res = self.op(self.node[count + b + 1], res)
				res = self.op(self.node[count + b + 2], res)
				right = a * n
				left = (b + 1) * n - 1
				break
			if a - b == 2:
				res = self.op(self.node[count + b + 1], res)
				right = a * n
				left = (b + 1) * n - 1
				break
			n = n // 2
		n1 = n // 2
		for j in range(i + 1, self.s):
			count = 2 ** j - 1
			a = (left + 1) // n1
			b = (l - 1) // n1
			if a - b == 2:
				res = self.op(self.node[count + b + 1], res)
				left = (b + 1) * n1 - 1
			n1 = n1 // 2
		n1 = n // 2
		for j in range(i + 1, self.s):
			count = 2 ** j - 1
			a = (r + 1) // n1
			b = (right - 1) // n1
			if a - b == 2:
				res = self.op(self.node[count + b + 1], res)
				right = a * n1
			n1 = n1 // 2
		return res

def smin(a, b):
	if a > b:
		return b
	else:
		return a

def main():
	(N, Q) = list(map(int, input().split()))
	ST1 = SegmentTree([N - 2] * (N - 2), smin, N - 2)
	ST2 = SegmentTree([N - 2] * (N - 2), smin, N - 2)
	ans = 0
	for i in range(Q):
		(a, b) = list(map(int, input().split()))
		b -= 2
		if a == 1:
			c = ST1.get(b, N - 3)
			ans += c
			ST2.substitute(c - 1, b)
		else:
			c = ST2.get(b, N - 3)
			ans += c
			ST1.substitute(c - 1, b)
	print((N - 2) ** 2 - ans)
main()


class LazyPropSegmentTree:

	def __init__(self, N):
		self.N = N
		self.LV = (N - 1).bit_length()
		self.N0 = 2 ** self.LV
		self.data = [N - 1] * (2 * self.N0)
		self.lazy = [float('inf')] * (2 * self.N0)

	def gindex(self, l, r):
		L = l + self.N0 >> 1
		R = r + self.N0 >> 1
		lc = 0 if l & 1 else (L & -L).bit_length()
		rc = 0 if r & 1 else (R & -R).bit_length()
		for i in range(self.LV):
			if rc <= i:
				yield R
			if L < R and lc <= i:
				yield L
			L >>= 1
			R >>= 1

	def propagates(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i - 1]
			if v == float('inf'):
				continue
			self.lazy[2 * i - 1] = min(self.lazy[2 * i - 1], v)
			self.lazy[2 * i] = min(self.lazy[2 * i], v)
			self.data[2 * i - 1] = min(self.data[2 * i - 1], v)
			self.data[2 * i] = min(self.data[2 * i], v)
			self.lazy[i - 1] = float('inf')

	def update(self, l, r, x):
		(*ids,) = self.gindex(l, r + 1)
		self.propagates(*ids)
		L = self.N0 + l
		R = self.N0 + r + 1
		while L < R:
			if R & 1:
				R -= 1
				self.lazy[R - 1] = min(self.lazy[R - 1], x)
				self.data[R - 1] = min(self.data[R - 1], x)
			if L & 1:
				self.lazy[L - 1] = min(self.lazy[L - 1], x)
				self.data[L - 1] = min(self.data[L - 1], x)
				L += 1
			L >>= 1
			R >>= 1
		for i in ids:
			self.data[i - 1] = min(self.data[2 * i - 1], self.data[2 * i])

	def point_query(self, k):
		(*ids,) = self.gindex(k, k + 1)
		self.propagates(*ids)
		return self.data[k + self.N0 - 1]
(N, Q) = map(int, input().split())
query = [tuple(map(int, input().split())) for i in range(Q)]
row = LazyPropSegmentTree(N + 1)
column = LazyPropSegmentTree(N + 1)
ans = (N - 2) ** 2
for (t, x) in query:
	if t == 1:
		n = row.point_query(x)
		ans -= n - 2
		column.update(2, n, x)
	else:
		n = column.point_query(x)
		ans -= n - 2
		row.update(2, n, x)
print(ans)


def main():
	examF()

def examA():
	S = SI()
	if S[-1] == 's':
		ans = S + 'es'
	else:
		ans = S + 's'
	print(ans)
	return

def examB():
	N = I()
	D = [LI() for _ in range(N)]
	current = 0
	for (d1, d2) in D:
		if d1 == d2:
			current += 1
		else:
			current = 0
		if current == 3:
			print('Yes')
			return
	print('No')
	return

def examC():
	N = I()
	cnt = 0
	for i in range(1, N):
		for j in range(1, 1 + N // i - (N % i == 0)):
			cnt += 1
	ans = cnt
	print(ans)
	return

def examD():
	(N, K) = LI()
	LR = [LI() for _ in range(K)]
	dp = [0] * N
	S = [0] * N
	dp[0] = 1
	S[0] = 1
	for i in range(1, N):
		cur = 0
		for (l, r) in LR:
			if i < l:
				continue
			cur += S[i - l]
			if i < r + 1:
				continue
			cur -= S[i - r - 1]
			cur += mod2
			cur %= mod2
		dp[i] = cur
		S[i] = S[i - 1] + cur
		S[i] %= mod2
	ans = dp[-1]
	print(ans)
	return

def examE():
	(N, X, M) = LI()
	cnt = 0
	L = []
	used = [-1] * (M + 1)
	for i in range(N):
		used[X] = i
		L.append(X)
		cnt += X
		X = pow(X, 2, M)
		if X == 1 or X == 0:
			cnt += (N - i - 1) * X
			break
		if used[X] >= 0:
			loop = i - used[X] + 1
			S = sum(L[used[X]:i + 1])
			rest = N - i - 1
			cnt += rest // loop * S + sum(L[used[X]:used[X] + rest % loop])
			break
	ans = cnt
	print(ans)
	return

def examF():

	class SegmentTree:

		def __init__(self, n, ele, segfun):
			self.ide_ele = ele
			self.segfun = segfun
			self.n = n
			self.N0 = 1 << n.bit_length()
			self.data = [self.ide_ele] * (self.N0 * 2)

		def update_add(self, l, r, val):
			l += self.N0
			r += self.N0
			while l < r:
				if l & 1:
					self.data[l] += val
					l += 1
				if r & 1:
					self.data[r - 1] += val
					r -= 1
				l //= 2
				r //= 2

		def update(self, l, r, val):
			l += self.N0
			r += self.N0
			while l < r:
				if l & 1:
					self.data[l] = self.segfun(self.data[l], val)
					l += 1
				if r & 1:
					self.data[r - 1] = self.segfun(self.data[r - 1], val)
					r -= 1
				l //= 2
				r //= 2

		def query(self, i):
			i += len(self.data) // 2
			ret = self.data[i]
			while i > 0:
				i //= 2
				ret = self.segfun(ret, self.data[i])
			return ret
	(N, Q) = LI()
	SH = SegmentTree(N, N - 2, lambda a, b: min(a, b))
	SW = SegmentTree(N, N - 2, lambda a, b: min(a, b))
	cnt = 0
	for q in range(Q):
		(t, x) = LI()
		if t == 1:
			up_w_0 = SH.query(x - 2)
			cnt += up_w_0
			SW.update(0, up_w_0, x - 2)
		elif t == 2:
			left_h_0 = SW.query(x - 2)
			cnt += left_h_0
			SH.update(0, left_h_0, x - 2)
	ans = (N - 2) ** 2 - cnt
	print(ans)
	return
from decimal import getcontext, Decimal as dec
import sys, bisect, itertools, heapq, math, random
from copy import deepcopy
from heapq import heappop, heappush, heapify
from collections import Counter, defaultdict, deque
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines

def I():
	return int(input())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def DI():
	return dec(input())

def LDI():
	return list(map(dec, sys.stdin.readline().split()))

def LSI():
	return list(map(str, sys.stdin.readline().split()))

def LS():
	return sys.stdin.readline().split()

def SI():
	return sys.stdin.readline().strip()
global mod, mod2, inf, alphabet, alphabet_convert, _ep
mod = 10 ** 9 + 7
mod2 = 998244353
inf = 1 << 31
_ep = dec('0.000000000001')
alphabet = [chr(ord('a') + i) for i in range(26)]
alphabet_convert = {chr(ord('a') + i): i for i in range(26)}
getcontext().prec = 28
sys.setrecursionlimit(10 ** 7)
main()


import sys, queue, math, copy, itertools, bisect, collections, heapq

def main():
	LI = lambda : [int(x) for x in sys.stdin.readline().split()]
	(N, Q) = LI()
	N0 = 2 ** (N - 1).bit_length()
	stx = [N - 1] * (N0 * 2)
	sty = [N - 1] * (N0 * 2)

	def update(l, r, x, st):
		l += N0 - 1
		r += N0 - 1
		while l < r:
			st[l] = min(st[l], x)
			st[r] = min(st[r], x)
			l //= 2
			r = r // 2 - 1
		st[l] = min(st[l], x)

	def get_data(i, st):
		i += N0 - 1
		ret = N - 1
		while i >= 0:
			ret = min(ret, st[i])
			i = (i - 1) // 2
		return ret
	ans = (N - 2) ** 2
	for _ in range(Q):
		(c, p) = LI()
		p -= 1
		if c == 1:
			s = get_data(p, sty)
			ans -= s - 1
			update(0, s - 1, p, stx)
		else:
			s = get_data(p, stx)
			ans -= s - 1
			update(0, s - 1, p, sty)
	print(ans)
main()


from bisect import bisect_right
(n, q) = map(int, input().split())
v_lay = [(-(n - 1), n - 2)]
h_lay = [(-(n - 1), n - 2)]
ans = (n - 2) * (n - 2)
for _ in range(q):
	(case, lay_pos) = map(int, input().split())
	ref_lay = v_lay if case == 1 else h_lay
	index = bisect_right(ref_lay, (-lay_pos, n))
	(_, lay) = ref_lay[index - 1]
	ans -= lay
	if index == len(ref_lay):
		ref_lay = h_lay if case == 1 else v_lay
		(laid_pos, num) = ref_lay[-1]
		if laid_pos == -(lay + 1):
			ref_lay[-1] = (-(lay + 1), min(lay_pos - 2, num))
		else:
			ref_lay.append((-(lay + 1), lay_pos - 2))
print(ans)


import numpy as np

def resolve():
	(n, q) = map(int, input().split())
	xe = np.array([0] * n)
	ye = np.array([0] * n)
	(xemin, yemin) = (n - 1, n - 1)
	bs = (n - 2) ** 2
	for i in range(q):
		(j, x) = map(int, input().split())
		if j == 1:
			if xemin >= x - 1:
				xe[x - 1:xemin] = yemin - 1
				xemin = x - 1
			bs -= xe[x - 1]
		else:
			if yemin >= x - 1:
				ye[x - 1:yemin] = xemin - 1
				yemin = x - 1
			bs -= ye[x - 1]
	print(bs)

def __starting_point():
	resolve()
__starting_point()


from bisect import bisect_left, bisect_right
(n, q) = map(int, input().split())
hori_cnt = [n - 2] * (n + 2)
ql = []
for _ in range(q):
	(c, x) = map(int, input().split())
	ql.append((c, x))
tate_min = n
yoko_min = n
yoko_kyokai = []
ans1 = 0
for (c, x) in ql:
	if c == 1:
		if x < tate_min:
			hori_cnt[yoko_min] = x - 2
			yoko_kyokai.append(yoko_min * -1)
			tate_min = x
	else:
		if x < yoko_min:
			yoko_min = x
		ind = bisect_left(yoko_kyokai, x * -1) - 1
		if ind == -1:
			if x < yoko_min:
				ans1 += tate_min - 2
			else:
				ans1 += n - 2
		else:
			val = yoko_kyokai[ind]
			ans1 += hori_cnt[val * -1]
tate_cnt = [n - 2] * (n + 2)
yoko_min = n
tate_min = n
tate_kyokai = []
ans2 = 0
for (c, x) in ql:
	if c == 2:
		if x < yoko_min:
			tate_cnt[tate_min] = x - 2
			tate_kyokai.append(tate_min * -1)
			yoko_min = x
	else:
		if x < tate_min:
			tate_min = x
		ind = bisect_left(tate_kyokai, x * -1) - 1
		if ind == -1:
			if x < tate_min:
				ans2 += yoko_min - 2
			else:
				ans2 += n - 2
		else:
			val = tate_kyokai[ind]
			ans2 += tate_cnt[val * -1]
print((n - 2) * (n - 2) - ans1 - ans2)


import sys
input = sys.stdin.readline
import math
import bisect
import heapq
from collections import defaultdict
from collections import deque
from collections import Counter
from functools import lru_cache
MOD = 998244353
INF = float('inf')
AZ = 'abcdefghijklmnopqrstuvwxyz'

def I():
	return int(input().strip())

def S():
	return input().strip()

def IL():
	return list(map(int, input().split()))

def SL():
	return list(map(str, input().split()))

def ILs(n):
	return list((int(input()) for _ in range(n)))

def SLs(n):
	return list((input().strip() for _ in range(n)))

def ILL(n):
	return [list(map(int, input().split())) for _ in range(n)]

def SLL(n):
	return [list(map(str, input().split())) for _ in range(n)]

def DD(arg):
	return defaultdict(arg)

def inv(n):
	return pow(n, MOD - 2, MOD)
kaijo_memo = []

def kaijo(n):
	if len(kaijo_memo) > n:
		return kaijo_memo[n]
	if len(kaijo_memo) == 0:
		kaijo_memo.append(1)
	while len(kaijo_memo) <= n:
		kaijo_memo.append(kaijo_memo[-1] * len(kaijo_memo) % MOD)
	return kaijo_memo[n]
gyaku_kaijo_memo = []

def gyaku_kaijo(n):
	if len(gyaku_kaijo_memo) > n:
		return gyaku_kaijo_memo[n]
	if len(gyaku_kaijo_memo) == 0:
		gyaku_kaijo_memo.append(1)
	while len(gyaku_kaijo_memo) <= n:
		gyaku_kaijo_memo.append(gyaku_kaijo_memo[-1] * pow(len(gyaku_kaijo_memo), MOD - 2, MOD) % MOD)
	return gyaku_kaijo_memo[n]

def nCr(n, r):
	if n == r:
		return 1
	if n < r or r < 0:
		return 0
	ret = 1
	ret = ret * kaijo(n) % MOD
	ret = ret * gyaku_kaijo(r) % MOD
	ret = ret * gyaku_kaijo(n - r) % MOD
	return ret

def factorization(n):
	arr = []
	temp = n
	for i in range(2, int(-(-n ** 0.5 // 1)) + 1):
		if temp % i == 0:
			cnt = 0
			while temp % i == 0:
				cnt += 1
				temp //= i
			arr.append([i, cnt])
	if temp != 1:
		arr.append([temp, 1])
	if arr == []:
		arr.append([n, 1])
	return arr

def make_divisors(n):
	divisors = []
	for i in range(1, int(n ** 0.5) + 1):
		if n % i == 0:
			divisors.append(i)
			if i != n // i:
				divisors.append(n // i)
	return divisors

def make_primes(N):
	max = int(math.sqrt(N))
	seachList = [i for i in range(2, N + 1)]
	primeNum = []
	while seachList[0] <= max:
		primeNum.append(seachList[0])
		tmp = seachList[0]
		seachList = [i for i in seachList if i % tmp != 0]
	primeNum.extend(seachList)
	return primeNum

def gcd(a, b):
	while b:
		(a, b) = (b, a % b)
	return a

def lcm(a, b):
	return a * b // gcd(a, b)

def count_bit(n):
	count = 0
	while n:
		n &= n - 1
		count += 1
	return count

def base_10_to_n(X, n):
	if X // n:
		return base_10_to_n(X // n, n) + [X % n]
	return [X % n]

def base_n_to_10(X, n):
	return sum((int(str(X)[-i - 1]) * n ** i for i in range(len(str(X)))))

def base_10_to_n_without_0(X, n):
	X -= 1
	if X // n:
		return base_10_to_n_without_0(X // n, n) + [X % n]
	return [X % n]

def int_log(n, a):
	count = 0
	while n >= a:
		n //= a
		count += 1
	return count
(N, Q) = IL()

class RUQ:

	def __init__(self, N, default=None):
		self.N0 = 2 ** (N - 1).bit_length()
		self.data = [(-1, N - 1)] * (2 * self.N0)
		self.INF = (-1, default)

	def update(self, l, r, v):
		L = l + self.N0
		R = r + self.N0
		while L < R:
			if R & 1:
				R -= 1
				self.data[R - 1] = v
			if L & 1:
				self.data[L - 1] = v
				L += 1
			L >>= 1
			R >>= 1

	def _query(self, k):
		k += self.N0 - 1
		s = self.INF
		while k >= 0:
			if self.data[k]:
				s = max(s, self.data[k])
			k = (k - 1) // 2
		return s

	def query(self, k):
		return self._query(k)[1]
TATE = RUQ(N - 1, N - 2)
YOKO = RUQ(N - 1, N - 2)
hidari = N
ue = N
ans = (N - 2) ** 2
for t in range(Q):
	(c, x) = IL()
	if c == 1:
		ans -= TATE.query(x - 2)
		if x < hidari:
			hidari = x
			YOKO.update(0, TATE.query(x - 2), (t, x - 2))
		TATE.update(x - 2, x - 1, (t, 0))
	else:
		ans -= YOKO.query(x - 2)
		if x < ue:
			ue = x
			TATE.update(0, YOKO.query(x - 2), (t, x - 2))
		YOKO.update(x - 2, x - 1, (t, 0))
print(ans)


from sys import stdin
input = stdin.buffer.readline

def main():
	(n, q) = map(int, input().split())
	(height, width) = (n, n)
	mark1 = [0] * n
	mark2 = [0] * n
	ans = (n - 2) * (n - 2)
	for _ in range(q):
		(typ, x) = map(int, input().split())
		if typ == 1:
			if x < width:
				ans -= height - 2
				for i in range(x, width):
					mark1[i] = height - 2
				width = x
			else:
				ans -= mark1[x]
		elif x < height:
			ans -= width - 2
			for i in range(x, height):
				mark2[i] = width - 2
			height = x
		else:
			ans -= mark2[x]
	print(ans)
main()


import sys
sys.setrecursionlimit(500005)
stdin = sys.stdin
ni = lambda : int(ns())
na = lambda : list(map(int, stdin.readline().split()))
ns = lambda : stdin.readline().strip()

class SegmentTreeOverwriteRMQ:
	M: int
	H: int
	N: int
	st: [int]
	cover: [int]
	I: int = 99999999999999

	def __init__(self, n):
		self.N = n
		self.H = 1
		while self.H < self.N:
			self.H *= 2
		self.M = self.H * 2
		self.cover = [self.I] * self.H
		self.st = [self.I] * self.M
		for i in range(self.H - 1, 0, -1):
			self.propagate(i)

	def propagate(self, i):
		if self.cover[i] == self.I:
			self.st[i] = min(self.st[2 * i], self.st[2 * i + 1])
		else:
			self.st[i] = self.cover[i]

	def update(self, l, r, v):
		self._update(l, r, v, 0, self.H, 1)

	def _update(self, l, r, v, cl, cr, cur):
		if l <= cl and cr <= r:
			if cr == cl + 1:
				self.st[cur] = v
			else:
				self.cover[cur] = v
				self.propagate(cur)
		else:
			mid = (cl + cr) // 2
			bp = False
			if self.cover[cur] != self.I:
				if 2 * cur >= self.H:
					self.st[2 * cur] = self.cover[cur]
					self.st[2 * cur + 1] = self.cover[cur]
				else:
					self.cover[2 * cur] = self.cover[cur]
					self.cover[2 * cur + 1] = self.cover[cur]
					bp = True
				self.cover[cur] = self.I
			if cl < r and l < mid:
				self._update(l, r, v, cl, mid, 2 * cur)
			elif bp:
				self.propagate(2 * cur)
			if mid < r and l < cr:
				self._update(l, r, v, mid, cr, 2 * cur + 1)
			elif bp:
				self.propagate(2 * cur + 1)
			self.propagate(cur)

	def min(self, l, r):
		return self._min(l, r, 0, self.H, 1)

	def _min(self, l, r, cl, cr, cur):
		if l <= cl and cr <= r:
			return self.st[cur]
		else:
			if self.cover[cur] != self.I:
				return self.cover[cur]
			(L, R) = (self.I, self.I)
			mid = cl + cr >> 1
			if cl < r and l < mid:
				L = self._min(l, r, cl, mid, 2 * cur)
			if mid < r and l < cr:
				R = self._min(l, r, mid, cr, 2 * cur + 1)
			return min(L, R)
(n, q) = na()
row = SegmentTreeOverwriteRMQ(n + 2)
row.update(2, n, n)
col = SegmentTreeOverwriteRMQ(n + 2)
col.update(2, n, n)
rmin = n
cmin = n
black = (n - 2) * (n - 2)
for z in range(q):
	(t, x) = na()
	if t == 1:
		black -= row.min(x, x + 1) - 2
		if x < rmin:
			rmin = x
			col.update(0, cmin, rmin)
	else:
		black -= col.min(x, x + 1) - 2
		if x < cmin:
			cmin = x
			row.update(0, rmin, cmin)
print(black)


import sys
sys.setrecursionlimit(10 ** 7)
input = sys.stdin.readline
f_inf = float('inf')
mod = 10 ** 9 + 7

def resolve():
	(n, q) = list(map(int, input().split()))
	query = [list(map(int, input().split())) for _ in range(q)]
	res = (n - 2) * (n - 2)
	R = C = n - 1
	yoko = [n - 1] * (n - 1)
	tate = [n - 1] * (n - 1)
	for (x, y) in query:
		y -= 1
		if x == 1:
			if y > C:
				res -= tate[y] - 1
			else:
				res -= R - 1
				for c in range(C - 1, y, -1):
					tate[c] = R
				C = y
			tate[y] = 0
		else:
			if y > R:
				res -= yoko[y] - 1
			else:
				res -= C - 1
				for r in range(R - 1, y, -1):
					yoko[r] = C
				R = y
			yoko[y] = 0
	print(res)

def __starting_point():
	resolve()
__starting_point()


import sys

def MI():
	return map(int, sys.stdin.readline().rstrip().split())

class BIT:

	def __init__(self, init_value):
		self.n = len(init_value)
		self.tree = [0] * (self.n + 1)
		for i in range(1, self.n + 1):
			x = init_value[i - 1]
			while i <= self.n:
				self.tree[i] += x
				i += i & -i

	def update(self, i, x):
		while i <= self.n:
			self.tree[i] += x
			i += i & -i
		return

	def query(self, i):
		res = 0
		while i > 0:
			res += self.tree[i]
			i -= i & -i
		return res
(N, Q) = MI()
(A, B) = ([0] * N, [0] * N)
(A[0], B[0]) = (N - 2, N - 2)
(A[N - 1], B[N - 1]) = (-(N - 2), -(N - 2))
(I, J) = (BIT(A), BIT(B))
(i_min, j_min) = (N, N)
ans = (N - 2) ** 2
for _ in range(Q):
	(a, x) = MI()
	if a == 1:
		ans -= I.query(x)
		if x < i_min:
			i_min = x
			y = J.tree[1]
			J.update(1, x - 2 - y)
			J.update(j_min, -(x - 2 - y))
	else:
		ans -= J.query(x)
		if x < j_min:
			j_min = x
			y = I.tree[1]
			I.update(1, x - 2 - y)
			I.update(i_min, -(x - 2 - y))
print(ans)


(N, Q) = map(int, input().split())
left = N
up = N
ans = (N - 2) ** 2
lefts = [N] * (N + 1)
ups = [N] * (N + 1)
for _ in range(Q):
	(num, x) = map(int, input().split())
	if num == 1:
		if x < left:
			for i in range(x, left):
				ups[i] = up
			left = x
		ans -= ups[x] - 2
	else:
		if x < up:
			for i in range(x, up):
				lefts[i] = left
			up = x
		ans -= lefts[x] - 2
print(ans)


(N, Q, *Query) = [int(_) for _ in open(0).read().split()]
D = Query[::2]
X = Query[1::2]

class LazySegmentTree:

	def __init__(self, array, f, g, h, ti, ei):
		self.f = f
		self.g = g
		self.h = h
		self.ti = ti
		self.ei = ei
		self.height = height = len(array).bit_length()
		self.n = n = 2 ** height
		self.dat = dat = [ti] * n + array + [ti] * (n - len(array))
		self.laz = [ei] * (2 * n)
		for i in range(n - 1, 0, -1):
			dat[i] = f(dat[i << 1], dat[i << 1 | 1])

	def reflect(self, k):
		dat = self.dat
		ei = self.ei
		laz = self.laz
		g = self.g
		return self.dat[k] if laz[k] is ei else g(dat[k], laz[k])

	def evaluate(self, k):
		laz = self.laz
		ei = self.ei
		reflect = self.reflect
		dat = self.dat
		h = self.h
		if laz[k] is ei:
			return
		laz[k << 1 | 0] = h(laz[k << 1 | 0], laz[k])
		laz[k << 1 | 1] = h(laz[k << 1 | 1], laz[k])
		dat[k] = reflect(k)
		laz[k] = ei

	def thrust(self, k):
		height = self.height
		evaluate = self.evaluate
		for i in range(height, 0, -1):
			evaluate(k >> i)

	def recalc(self, k):
		dat = self.dat
		reflect = self.reflect
		f = self.f
		while k:
			k >>= 1
			dat[k] = f(reflect(k << 1 | 0), reflect(k << 1 | 1))

	def update(self, a, b, x):
		thrust = self.thrust
		n = self.n
		h = self.h
		laz = self.laz
		recalc = self.recalc
		a += n
		b += n - 1
		l = a
		r = b + 1
		thrust(a)
		thrust(b)
		while l < r:
			if l & 1:
				laz[l] = h(laz[l], x)
				l += 1
			if r & 1:
				r -= 1
				laz[r] = h(laz[r], x)
			l >>= 1
			r >>= 1
		recalc(a)
		recalc(b)

	def set_val(self, a, x):
		n = self.n
		thrust = self.thrust
		dat = self.dat
		laz = self.laz
		recalc = self.recalc
		ei = self.ei
		a += n
		thrust(a)
		dat[a] = x
		laz[a] = ei
		recalc(a)

	def query(self, a, b):
		f = self.f
		ti = self.ti
		n = self.n
		thrust = self.thrust
		reflect = self.reflect
		a += n
		b += n - 1
		thrust(a)
		thrust(b)
		l = a
		r = b + 1
		vl = vr = ti
		while l < r:
			if l & 1:
				vl = f(vl, reflect(l))
				l += 1
			if r & 1:
				r -= 1
				vr = f(reflect(r), vr)
			l >>= 1
			r >>= 1
		return f(vl, vr)
array = [N] * (N + 1)
f = lambda a, b: a if b == 0 else b
g = lambda a, b: min(a, b)
h = lambda a, b: min(a, b)
ti = 0
ei = float('inf')
lst1 = LazySegmentTree(array=array, ti=ti, ei=ei, f=f, g=g, h=h)
lst2 = LazySegmentTree(array=array, ti=ti, ei=ei, f=f, g=g, h=h)
ans = 0
for (d, x) in zip(D, X):
	if d == 1:
		y = lst1.query(x, x + 1)
		ans += y - 2
		lst2.update(1, y, x)
	else:
		y = lst2.query(x, x + 1)
		ans += y - 2
		lst1.update(1, y, x)
ans = (N - 2) ** 2 - ans
print(ans)


import sys
input = sys.stdin.buffer.readline
sys.setrecursionlimit(10 ** 7)
from collections import defaultdict
mod = 10 ** 9 + 7
INF = float('inf')

def getlist():
	return list(map(int, input().split()))

class lazySegTree(object):

	def __init__(self, N):
		self.N = N
		self.LV = (N - 1).bit_length()
		self.N0 = 2 ** self.LV
		self.data = [N - 1] * (2 * self.N0)
		self.lazy = [INF] * (2 * self.N0)

	def gindex(self, l, r):
		L = l + self.N0 >> 1
		R = r + self.N0 >> 1
		lc = 0 if l & 1 else (L & -L).bit_length()
		rc = 0 if r & 1 else (R & -R).bit_length()
		for i in range(self.LV):
			if rc <= i:
				yield R
			if L < R and lc <= i:
				yield L
			L >>= 1
			R >>= 1

	def propagates(self, *ids):
		for i in reversed(ids):
			v = self.lazy[i - 1]
			if v == INF:
				continue
			self.lazy[2 * i - 1] = min(self.lazy[2 * i - 1], v)
			self.lazy[2 * i] = min(self.lazy[2 * i], v)
			self.data[2 * i - 1] = min(self.data[2 * i - 1], v)
			self.data[2 * i] = min(self.data[2 * i], v)
			self.lazy[i - 1] = INF

	def update(self, l, r, x):
		(*ids,) = self.gindex(l, r + 1)
		self.propagates(*ids)
		L = self.N0 + l
		R = self.N0 + r + 1
		while L < R:
			if R & 1:
				R -= 1
				self.lazy[R - 1] = min(self.lazy[R - 1], x)
				self.data[R - 1] = min(self.data[R - 1], x)
			if L & 1:
				self.lazy[L - 1] = min(self.lazy[L - 1], x)
				self.data[L - 1] = min(self.data[L - 1], x)
				L += 1
			L >>= 1
			R >>= 1
		for i in ids:
			self.data[i - 1] = min(self.data[2 * i - 1], self.data[2 * i])

	def pointQuery(self, k):
		(*ids,) = self.gindex(k, k + 1)
		self.propagates(*ids)
		return self.data[k + self.N0 - 1]

	def debug(self):
		ids = [i for i in range(self.N0, 0, -1)]
		self.propagates(*ids)
		print(self.data[self.N0 - 1:])

def main():
	(N, Q) = getlist()
	lSeg_low = lazySegTree(N + 1)
	lSeg_col = lazySegTree(N + 1)
	ans = (N - 2) ** 2
	for i in range(Q):
		(n, x) = getlist()
		if n == 1:
			itr = lSeg_col.pointQuery(x)
			ans -= itr - 2
			lSeg_low.update(2, itr - 1, x)
		else:
			itr = lSeg_low.pointQuery(x)
			ans -= itr - 2
			lSeg_col.update(2, itr - 1, x)
	print(ans)
main()


def debug(N, st):
	print(*[st.query(i, i + 1) for i in range(N)], sep=' ')

def solve(N, Q, Queries):
	from itertools import accumulate
	row = SegmentTreeLazy([float('inf')] * N, float('inf'), float('inf'), min, min, min)
	col = SegmentTreeLazy([float('inf')] * N, float('inf'), float('inf'), min, min, min)
	rmin = list(accumulate([N if c == 2 else x for (c, x) in Queries], min))
	cmin = list(accumulate([N if c == 1 else x for (c, x) in Queries], min))
	ans = 0

	def f(st, emin, i, step):
		st.update(i, N, step)
		idx = st.query(i, i + 1)
		return emin[idx] - 2
	for (step, (c, x)) in enumerate(Queries):
		if c == 1:
			ans += f(row, cmin, x - 1, step)
		else:
			ans += f(col, rmin, x - 1, step)
	return (N - 2) ** 2 - ans

class SegmentTreeLazy:

	def __init__(self, arr, ti, ei, func, op, merge):
		self.h = (len(arr) - 1).bit_length()
		self.n = 2 ** self.h
		self.func = func
		self.op = op
		self.merge = merge
		self.ti = ti
		self.ei = ei
		self.val = [ti for _ in range(2 * self.n)]
		for i in range(len(arr)):
			self.val[self.n + i] = arr[i]
		for i in range(1, self.n)[::-1]:
			self.val[i] = self.func(self.val[2 * i], self.val[2 * i + 1])
		self.laz = [ei for _ in range(2 * self.n)]

	def reflect(self, k):
		if self.laz[k] == self.ei:
			return self.val[k]
		return self.op(self.val[k], self.laz[k])

	def propagate(self, k):
		if self.laz[k] == self.ei:
			return
		self.laz[2 * k] = self.merge(self.laz[2 * k], self.laz[k])
		self.laz[2 * k + 1] = self.merge(self.laz[2 * k + 1], self.laz[k])
		self.val[k] = self.reflect(k)
		self.laz[k] = self.ei

	def thrust(self, k):
		for i in range(1, self.h + 1)[::-1]:
			self.propagate(k >> i)

	def recalc(self, k):
		while k:
			k >>= 1
			self.val[k] = self.func(self.reflect(2 * k), self.reflect(2 * k + 1))

	def update(self, lt, rt, x):
		lt += self.n
		rt += self.n
		vl = lt
		vr = rt
		self.thrust(lt)
		self.thrust(rt - 1)
		while rt - lt > 0:
			if lt & 1:
				self.laz[lt] = self.merge(self.laz[lt], x)
				lt += 1
			if rt & 1:
				rt -= 1
				self.laz[rt] = self.merge(self.laz[rt], x)
			lt >>= 1
			rt >>= 1
		self.recalc(vl)
		self.recalc(vr - 1)

	def query(self, lt, rt):
		lt += self.n
		rt += self.n
		self.thrust(lt)
		self.thrust(rt - 1)
		vl = vr = self.ti
		while rt - lt > 0:
			if lt & 1:
				vl = self.func(vl, self.reflect(lt))
				lt += 1
			if rt & 1:
				rt -= 1
				vr = self.func(self.reflect(rt), vr)
			lt >>= 1
			rt >>= 1
		return self.func(vl, vr)

def main():
	(N, Q) = map(int, input().split())
	Queries = [list(map(int, input().split())) for _ in range(Q)]
	print(solve(N, Q, Queries))

def test():
	import doctest
	doctest.testmod()
main()


from __future__ import print_function
import sys
import traceback
from bisect import bisect_left, bisect_right, insort
from itertools import chain, repeat, starmap
from math import log
from operator import add, eq, ne, gt, ge, lt, le, iadd
from textwrap import dedent
from collections.abc import Sequence, MutableSequence, ItemsView, KeysView, ValuesView, MutableSet, Set
from functools import wraps, reduce
from _thread import get_ident

def recursive_repr(fillvalue='...'):

	def decorating_function(user_function):
		repr_running = set()

		@wraps(user_function)
		def wrapper(self):
			key = (id(self), get_ident())
			if key in repr_running:
				return fillvalue
			repr_running.add(key)
			try:
				result = user_function(self)
			finally:
				repr_running.discard(key)
			return result
		return wrapper
	return decorating_function

class SortedList(MutableSequence):
	DEFAULT_LOAD_FACTOR = 1000

	def __init__(self, iterable=None, key=None):
		assert key is None
		self._len = 0
		self._load = self.DEFAULT_LOAD_FACTOR
		self._lists = []
		self._maxes = []
		self._index = []
		self._offset = 0
		if iterable is not None:
			self._update(iterable)

	def __new__(cls, iterable=None, key=None):
		if key is None:
			return object.__new__(cls)
		elif cls is SortedList:
			return object.__new__(SortedKeyList)
		else:
			raise TypeError('inherit SortedKeyList for key argument')

	@property
	def key(self):
		return None

	def _reset(self, load):
		values = reduce(iadd, self._lists, [])
		self._clear()
		self._load = load
		self._update(values)

	def clear(self):
		self._len = 0
		del self._lists[:]
		del self._maxes[:]
		del self._index[:]
		self._offset = 0
	_clear = clear

	def add(self, value):
		_lists = self._lists
		_maxes = self._maxes
		if _maxes:
			pos = bisect_right(_maxes, value)
			if pos == len(_maxes):
				pos -= 1
				_lists[pos].append(value)
				_maxes[pos] = value
			else:
				insort(_lists[pos], value)
			self._expand(pos)
		else:
			_lists.append([value])
			_maxes.append(value)
		self._len += 1

	def _expand(self, pos):
		_load = self._load
		_lists = self._lists
		_index = self._index
		if len(_lists[pos]) > _load << 1:
			_maxes = self._maxes
			_lists_pos = _lists[pos]
			half = _lists_pos[_load:]
			del _lists_pos[_load:]
			_maxes[pos] = _lists_pos[-1]
			_lists.insert(pos + 1, half)
			_maxes.insert(pos + 1, half[-1])
			del _index[:]
		elif _index:
			child = self._offset + pos
			while child:
				_index[child] += 1
				child = child - 1 >> 1
			_index[0] += 1

	def update(self, iterable):
		_lists = self._lists
		_maxes = self._maxes
		values = sorted(iterable)
		if _maxes:
			if len(values) * 4 >= self._len:
				values.extend(chain.from_iterable(_lists))
				values.sort()
				self._clear()
			else:
				_add = self.add
				for val in values:
					_add(val)
				return
		_load = self._load
		_lists.extend((values[pos:pos + _load] for pos in range(0, len(values), _load)))
		_maxes.extend((sublist[-1] for sublist in _lists))
		self._len = len(values)
		del self._index[:]
	_update = update

	def __contains__(self, value):
		_maxes = self._maxes
		if not _maxes:
			return False
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			return False
		_lists = self._lists
		idx = bisect_left(_lists[pos], value)
		return _lists[pos][idx] == value

	def discard(self, value):
		_maxes = self._maxes
		if not _maxes:
			return
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			return
		_lists = self._lists
		idx = bisect_left(_lists[pos], value)
		if _lists[pos][idx] == value:
			self._delete(pos, idx)

	def remove(self, value):
		_maxes = self._maxes
		if not _maxes:
			raise ValueError('{0!r} not in list'.format(value))
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			raise ValueError('{0!r} not in list'.format(value))
		_lists = self._lists
		idx = bisect_left(_lists[pos], value)
		if _lists[pos][idx] == value:
			self._delete(pos, idx)
		else:
			raise ValueError('{0!r} not in list'.format(value))

	def _delete(self, pos, idx):
		_lists = self._lists
		_maxes = self._maxes
		_index = self._index
		_lists_pos = _lists[pos]
		del _lists_pos[idx]
		self._len -= 1
		len_lists_pos = len(_lists_pos)
		if len_lists_pos > self._load >> 1:
			_maxes[pos] = _lists_pos[-1]
			if _index:
				child = self._offset + pos
				while child > 0:
					_index[child] -= 1
					child = child - 1 >> 1
				_index[0] -= 1
		elif len(_lists) > 1:
			if not pos:
				pos += 1
			prev = pos - 1
			_lists[prev].extend(_lists[pos])
			_maxes[prev] = _lists[prev][-1]
			del _lists[pos]
			del _maxes[pos]
			del _index[:]
			self._expand(prev)
		elif len_lists_pos:
			_maxes[pos] = _lists_pos[-1]
		else:
			del _lists[pos]
			del _maxes[pos]
			del _index[:]

	def _loc(self, pos, idx):
		if not pos:
			return idx
		_index = self._index
		if not _index:
			self._build_index()
		total = 0
		pos += self._offset
		while pos:
			if not pos & 1:
				total += _index[pos - 1]
			pos = pos - 1 >> 1
		return total + idx

	def _pos(self, idx):
		if idx < 0:
			last_len = len(self._lists[-1])
			if -idx <= last_len:
				return (len(self._lists) - 1, last_len + idx)
			idx += self._len
			if idx < 0:
				raise IndexError('list index out of range')
		elif idx >= self._len:
			raise IndexError('list index out of range')
		if idx < len(self._lists[0]):
			return (0, idx)
		_index = self._index
		if not _index:
			self._build_index()
		pos = 0
		child = 1
		len_index = len(_index)
		while child < len_index:
			index_child = _index[child]
			if idx < index_child:
				pos = child
			else:
				idx -= index_child
				pos = child + 1
			child = (pos << 1) + 1
		return (pos - self._offset, idx)

	def _build_index(self):
		row0 = list(map(len, self._lists))
		if len(row0) == 1:
			self._index[:] = row0
			self._offset = 0
			return
		head = iter(row0)
		tail = iter(head)
		row1 = list(starmap(add, zip(head, tail)))
		if len(row0) & 1:
			row1.append(row0[-1])
		if len(row1) == 1:
			self._index[:] = row1 + row0
			self._offset = 1
			return
		size = 2 ** (int(log(len(row1) - 1, 2)) + 1)
		row1.extend(repeat(0, size - len(row1)))
		tree = [row0, row1]
		while len(tree[-1]) > 1:
			head = iter(tree[-1])
			tail = iter(head)
			row = list(starmap(add, zip(head, tail)))
			tree.append(row)
		reduce(iadd, reversed(tree), self._index)
		self._offset = size * 2 - 1

	def __delitem__(self, index):
		if isinstance(index, slice):
			(start, stop, step) = index.indices(self._len)
			if step == 1 and start < stop:
				if start == 0 and stop == self._len:
					return self._clear()
				elif self._len <= 8 * (stop - start):
					values = self._getitem(slice(None, start))
					if stop < self._len:
						values += self._getitem(slice(stop, None))
					self._clear()
					return self._update(values)
			indices = range(start, stop, step)
			if step > 0:
				indices = reversed(indices)
			(_pos, _delete) = (self._pos, self._delete)
			for index in indices:
				(pos, idx) = _pos(index)
				_delete(pos, idx)
		else:
			(pos, idx) = self._pos(index)
			self._delete(pos, idx)

	def __getitem__(self, index):
		_lists = self._lists
		if isinstance(index, slice):
			(start, stop, step) = index.indices(self._len)
			if step == 1 and start < stop:
				if start == 0 and stop == self._len:
					return reduce(iadd, self._lists, [])
				(start_pos, start_idx) = self._pos(start)
				start_list = _lists[start_pos]
				stop_idx = start_idx + stop - start
				if len(start_list) >= stop_idx:
					return start_list[start_idx:stop_idx]
				if stop == self._len:
					stop_pos = len(_lists) - 1
					stop_idx = len(_lists[stop_pos])
				else:
					(stop_pos, stop_idx) = self._pos(stop)
				prefix = _lists[start_pos][start_idx:]
				middle = _lists[start_pos + 1:stop_pos]
				result = reduce(iadd, middle, prefix)
				result += _lists[stop_pos][:stop_idx]
				return result
			if step == -1 and start > stop:
				result = self._getitem(slice(stop + 1, start + 1))
				result.reverse()
				return result
			indices = range(start, stop, step)
			return list((self._getitem(index) for index in indices))
		else:
			if self._len:
				if index == 0:
					return _lists[0][0]
				elif index == -1:
					return _lists[-1][-1]
			else:
				raise IndexError('list index out of range')
			if 0 <= index < len(_lists[0]):
				return _lists[0][index]
			len_last = len(_lists[-1])
			if -len_last < index < 0:
				return _lists[-1][len_last + index]
			(pos, idx) = self._pos(index)
			return _lists[pos][idx]
	_getitem = __getitem__

	def __setitem__(self, index, value):
		message = 'use ``del sl[index]`` and ``sl.add(value)`` instead'
		raise NotImplementedError(message)

	def __iter__(self):
		return chain.from_iterable(self._lists)

	def __reversed__(self):
		return chain.from_iterable(map(reversed, reversed(self._lists)))

	def reverse(self):
		raise NotImplementedError('use ``reversed(sl)`` instead')

	def islice(self, start=None, stop=None, reverse=False):
		_len = self._len
		if not _len:
			return iter(())
		(start, stop, _) = slice(start, stop).indices(self._len)
		if start >= stop:
			return iter(())
		_pos = self._pos
		(min_pos, min_idx) = _pos(start)
		if stop == _len:
			max_pos = len(self._lists) - 1
			max_idx = len(self._lists[-1])
		else:
			(max_pos, max_idx) = _pos(stop)
		return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)

	def _islice(self, min_pos, min_idx, max_pos, max_idx, reverse):
		_lists = self._lists
		if min_pos > max_pos:
			return iter(())
		if min_pos == max_pos:
			if reverse:
				indices = reversed(range(min_idx, max_idx))
				return map(_lists[min_pos].__getitem__, indices)
			indices = range(min_idx, max_idx)
			return map(_lists[min_pos].__getitem__, indices)
		next_pos = min_pos + 1
		if next_pos == max_pos:
			if reverse:
				min_indices = range(min_idx, len(_lists[min_pos]))
				max_indices = range(max_idx)
				return chain(map(_lists[max_pos].__getitem__, reversed(max_indices)), map(_lists[min_pos].__getitem__, reversed(min_indices)))
			min_indices = range(min_idx, len(_lists[min_pos]))
			max_indices = range(max_idx)
			return chain(map(_lists[min_pos].__getitem__, min_indices), map(_lists[max_pos].__getitem__, max_indices))
		if reverse:
			min_indices = range(min_idx, len(_lists[min_pos]))
			sublist_indices = range(next_pos, max_pos)
			sublists = map(_lists.__getitem__, reversed(sublist_indices))
			max_indices = range(max_idx)
			return chain(map(_lists[max_pos].__getitem__, reversed(max_indices)), chain.from_iterable(map(reversed, sublists)), map(_lists[min_pos].__getitem__, reversed(min_indices)))
		min_indices = range(min_idx, len(_lists[min_pos]))
		sublist_indices = range(next_pos, max_pos)
		sublists = map(_lists.__getitem__, sublist_indices)
		max_indices = range(max_idx)
		return chain(map(_lists[min_pos].__getitem__, min_indices), chain.from_iterable(sublists), map(_lists[max_pos].__getitem__, max_indices))

	def irange(self, minimum=None, maximum=None, inclusive=(True, True), reverse=False):
		_maxes = self._maxes
		if not _maxes:
			return iter(())
		_lists = self._lists
		if minimum is None:
			min_pos = 0
			min_idx = 0
		elif inclusive[0]:
			min_pos = bisect_left(_maxes, minimum)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_left(_lists[min_pos], minimum)
		else:
			min_pos = bisect_right(_maxes, minimum)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_right(_lists[min_pos], minimum)
		if maximum is None:
			max_pos = len(_maxes) - 1
			max_idx = len(_lists[max_pos])
		elif inclusive[1]:
			max_pos = bisect_right(_maxes, maximum)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_lists[max_pos])
			else:
				max_idx = bisect_right(_lists[max_pos], maximum)
		else:
			max_pos = bisect_left(_maxes, maximum)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_lists[max_pos])
			else:
				max_idx = bisect_left(_lists[max_pos], maximum)
		return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)

	def __len__(self):
		return self._len

	def bisect_left(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_left(_maxes, value)
		if pos == len(_maxes):
			return self._len
		idx = bisect_left(self._lists[pos], value)
		return self._loc(pos, idx)

	def bisect_right(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_right(_maxes, value)
		if pos == len(_maxes):
			return self._len
		idx = bisect_right(self._lists[pos], value)
		return self._loc(pos, idx)
	bisect = bisect_right
	_bisect_right = bisect_right

	def count(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos_left = bisect_left(_maxes, value)
		if pos_left == len(_maxes):
			return 0
		_lists = self._lists
		idx_left = bisect_left(_lists[pos_left], value)
		pos_right = bisect_right(_maxes, value)
		if pos_right == len(_maxes):
			return self._len - self._loc(pos_left, idx_left)
		idx_right = bisect_right(_lists[pos_right], value)
		if pos_left == pos_right:
			return idx_right - idx_left
		right = self._loc(pos_right, idx_right)
		left = self._loc(pos_left, idx_left)
		return right - left

	def copy(self):
		return self.__class__(self)
	__copy__ = copy

	def append(self, value):
		raise NotImplementedError('use ``sl.add(value)`` instead')

	def extend(self, values):
		raise NotImplementedError('use ``sl.update(values)`` instead')

	def insert(self, index, value):
		raise NotImplementedError('use ``sl.add(value)`` instead')

	def pop(self, index=-1):
		if not self._len:
			raise IndexError('pop index out of range')
		_lists = self._lists
		if index == 0:
			val = _lists[0][0]
			self._delete(0, 0)
			return val
		if index == -1:
			pos = len(_lists) - 1
			loc = len(_lists[pos]) - 1
			val = _lists[pos][loc]
			self._delete(pos, loc)
			return val
		if 0 <= index < len(_lists[0]):
			val = _lists[0][index]
			self._delete(0, index)
			return val
		len_last = len(_lists[-1])
		if -len_last < index < 0:
			pos = len(_lists) - 1
			loc = len_last + index
			val = _lists[pos][loc]
			self._delete(pos, loc)
			return val
		(pos, idx) = self._pos(index)
		val = _lists[pos][idx]
		self._delete(pos, idx)
		return val

	def index(self, value, start=None, stop=None):
		_len = self._len
		if not _len:
			raise ValueError('{0!r} is not in list'.format(value))
		if start is None:
			start = 0
		if start < 0:
			start += _len
		if start < 0:
			start = 0
		if stop is None:
			stop = _len
		if stop < 0:
			stop += _len
		if stop > _len:
			stop = _len
		if stop <= start:
			raise ValueError('{0!r} is not in list'.format(value))
		_maxes = self._maxes
		pos_left = bisect_left(_maxes, value)
		if pos_left == len(_maxes):
			raise ValueError('{0!r} is not in list'.format(value))
		_lists = self._lists
		idx_left = bisect_left(_lists[pos_left], value)
		if _lists[pos_left][idx_left] != value:
			raise ValueError('{0!r} is not in list'.format(value))
		stop -= 1
		left = self._loc(pos_left, idx_left)
		if start <= left:
			if left <= stop:
				return left
		else:
			right = self._bisect_right(value) - 1
			if start <= right:
				return start
		raise ValueError('{0!r} is not in list'.format(value))

	def __add__(self, other):
		values = reduce(iadd, self._lists, [])
		values.extend(other)
		return self.__class__(values)
	__radd__ = __add__

	def __iadd__(self, other):
		self._update(other)
		return self

	def __mul__(self, num):
		values = reduce(iadd, self._lists, []) * num
		return self.__class__(values)
	__rmul__ = __mul__

	def __imul__(self, num):
		values = reduce(iadd, self._lists, []) * num
		self._clear()
		self._update(values)
		return self

	def __make_cmp(seq_op, symbol, doc):

		def comparer(self, other):
			if not isinstance(other, Sequence):
				return NotImplemented
			self_len = self._len
			len_other = len(other)
			if self_len != len_other:
				if seq_op is eq:
					return False
				if seq_op is ne:
					return True
			for (alpha, beta) in zip(self, other):
				if alpha != beta:
					return seq_op(alpha, beta)
			return seq_op(self_len, len_other)
		seq_op_name = seq_op.__name__
		comparer.__name__ = '__{0}__'.format(seq_op_name)
		doc_str = 'Return true if and only if sorted list is {0} `other`.\n        ``sl.__{1}__(other)`` <==> ``sl {2} other``\n        Comparisons use lexicographical order as with sequences.\n        Runtime complexity: `O(n)`\n        :param other: `other` sequence\n        :return: true if sorted list is {0} `other`\n        '
		comparer.__doc__ = dedent(doc_str.format(doc, seq_op_name, symbol))
		return comparer
	__eq__ = __make_cmp(eq, '==', 'equal to')
	__ne__ = __make_cmp(ne, '!=', 'not equal to')
	__lt__ = __make_cmp(lt, '<', 'less than')
	__gt__ = __make_cmp(gt, '>', 'greater than')
	__le__ = __make_cmp(le, '<=', 'less than or equal to')
	__ge__ = __make_cmp(ge, '>=', 'greater than or equal to')
	__make_cmp = staticmethod(__make_cmp)

	def __reduce__(self):
		values = reduce(iadd, self._lists, [])
		return (type(self), (values,))

	@recursive_repr()
	def __repr__(self):
		return '{0}({1!r})'.format(type(self).__name__, list(self))

	def _check(self):
		try:
			assert self._load >= 4
			assert len(self._maxes) == len(self._lists)
			assert self._len == sum((len(sublist) for sublist in self._lists))
			for sublist in self._lists:
				for pos in range(1, len(sublist)):
					assert sublist[pos - 1] <= sublist[pos]
			for pos in range(1, len(self._lists)):
				assert self._lists[pos - 1][-1] <= self._lists[pos][0]
			for pos in range(len(self._maxes)):
				assert self._maxes[pos] == self._lists[pos][-1]
			double = self._load << 1
			assert all((len(sublist) <= double for sublist in self._lists))
			half = self._load >> 1
			for pos in range(0, len(self._lists) - 1):
				assert len(self._lists[pos]) >= half
			if self._index:
				assert self._len == self._index[0]
				assert len(self._index) == self._offset + len(self._lists)
				for pos in range(len(self._lists)):
					leaf = self._index[self._offset + pos]
					assert leaf == len(self._lists[pos])
				for pos in range(self._offset):
					child = (pos << 1) + 1
					if child >= len(self._index):
						assert self._index[pos] == 0
					elif child + 1 == len(self._index):
						assert self._index[pos] == self._index[child]
					else:
						child_sum = self._index[child] + self._index[child + 1]
						assert child_sum == self._index[pos]
		except BaseException:
			traceback.print_exc(file=sys.stdout)
			print('len', self._len)
			print('load', self._load)
			print('offset', self._offset)
			print('len_index', len(self._index))
			print('index', self._index)
			print('len_maxes', len(self._maxes))
			print('maxes', self._maxes)
			print('len_lists', len(self._lists))
			print('lists', self._lists)
			raise

def identity(value):
	return value

class SortedKeyList(SortedList):

	def __init__(self, iterable=None, key=identity):
		self._key = key
		self._len = 0
		self._load = self.DEFAULT_LOAD_FACTOR
		self._lists = []
		self._keys = []
		self._maxes = []
		self._index = []
		self._offset = 0
		if iterable is not None:
			self._update(iterable)

	def __new__(cls, iterable=None, key=identity):
		return object.__new__(cls)

	@property
	def key(self):
		return self._key

	def clear(self):
		self._len = 0
		del self._lists[:]
		del self._keys[:]
		del self._maxes[:]
		del self._index[:]
	_clear = clear

	def add(self, value):
		_lists = self._lists
		_keys = self._keys
		_maxes = self._maxes
		key = self._key(value)
		if _maxes:
			pos = bisect_right(_maxes, key)
			if pos == len(_maxes):
				pos -= 1
				_lists[pos].append(value)
				_keys[pos].append(key)
				_maxes[pos] = key
			else:
				idx = bisect_right(_keys[pos], key)
				_lists[pos].insert(idx, value)
				_keys[pos].insert(idx, key)
			self._expand(pos)
		else:
			_lists.append([value])
			_keys.append([key])
			_maxes.append(key)
		self._len += 1

	def _expand(self, pos):
		_lists = self._lists
		_keys = self._keys
		_index = self._index
		if len(_keys[pos]) > self._load << 1:
			_maxes = self._maxes
			_load = self._load
			_lists_pos = _lists[pos]
			_keys_pos = _keys[pos]
			half = _lists_pos[_load:]
			half_keys = _keys_pos[_load:]
			del _lists_pos[_load:]
			del _keys_pos[_load:]
			_maxes[pos] = _keys_pos[-1]
			_lists.insert(pos + 1, half)
			_keys.insert(pos + 1, half_keys)
			_maxes.insert(pos + 1, half_keys[-1])
			del _index[:]
		elif _index:
			child = self._offset + pos
			while child:
				_index[child] += 1
				child = child - 1 >> 1
			_index[0] += 1

	def update(self, iterable):
		_lists = self._lists
		_keys = self._keys
		_maxes = self._maxes
		values = sorted(iterable, key=self._key)
		if _maxes:
			if len(values) * 4 >= self._len:
				values.extend(chain.from_iterable(_lists))
				values.sort(key=self._key)
				self._clear()
			else:
				_add = self.add
				for val in values:
					_add(val)
				return
		_load = self._load
		_lists.extend((values[pos:pos + _load] for pos in range(0, len(values), _load)))
		_keys.extend((list(map(self._key, _list)) for _list in _lists))
		_maxes.extend((sublist[-1] for sublist in _keys))
		self._len = len(values)
		del self._index[:]
	_update = update

	def __contains__(self, value):
		_maxes = self._maxes
		if not _maxes:
			return False
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return False
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				return False
			if _lists[pos][idx] == value:
				return True
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					return False
				len_sublist = len(_keys[pos])
				idx = 0

	def discard(self, value):
		_maxes = self._maxes
		if not _maxes:
			return
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				return
			if _lists[pos][idx] == value:
				self._delete(pos, idx)
				return
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					return
				len_sublist = len(_keys[pos])
				idx = 0

	def remove(self, value):
		_maxes = self._maxes
		if not _maxes:
			raise ValueError('{0!r} not in list'.format(value))
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			raise ValueError('{0!r} not in list'.format(value))
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				raise ValueError('{0!r} not in list'.format(value))
			if _lists[pos][idx] == value:
				self._delete(pos, idx)
				return
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					raise ValueError('{0!r} not in list'.format(value))
				len_sublist = len(_keys[pos])
				idx = 0

	def _delete(self, pos, idx):
		_lists = self._lists
		_keys = self._keys
		_maxes = self._maxes
		_index = self._index
		keys_pos = _keys[pos]
		lists_pos = _lists[pos]
		del keys_pos[idx]
		del lists_pos[idx]
		self._len -= 1
		len_keys_pos = len(keys_pos)
		if len_keys_pos > self._load >> 1:
			_maxes[pos] = keys_pos[-1]
			if _index:
				child = self._offset + pos
				while child > 0:
					_index[child] -= 1
					child = child - 1 >> 1
				_index[0] -= 1
		elif len(_keys) > 1:
			if not pos:
				pos += 1
			prev = pos - 1
			_keys[prev].extend(_keys[pos])
			_lists[prev].extend(_lists[pos])
			_maxes[prev] = _keys[prev][-1]
			del _lists[pos]
			del _keys[pos]
			del _maxes[pos]
			del _index[:]
			self._expand(prev)
		elif len_keys_pos:
			_maxes[pos] = keys_pos[-1]
		else:
			del _lists[pos]
			del _keys[pos]
			del _maxes[pos]
			del _index[:]

	def irange(self, minimum=None, maximum=None, inclusive=(True, True), reverse=False):
		min_key = self._key(minimum) if minimum is not None else None
		max_key = self._key(maximum) if maximum is not None else None
		return self._irange_key(min_key=min_key, max_key=max_key, inclusive=inclusive, reverse=reverse)

	def irange_key(self, min_key=None, max_key=None, inclusive=(True, True), reverse=False):
		_maxes = self._maxes
		if not _maxes:
			return iter(())
		_keys = self._keys
		if min_key is None:
			min_pos = 0
			min_idx = 0
		elif inclusive[0]:
			min_pos = bisect_left(_maxes, min_key)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_left(_keys[min_pos], min_key)
		else:
			min_pos = bisect_right(_maxes, min_key)
			if min_pos == len(_maxes):
				return iter(())
			min_idx = bisect_right(_keys[min_pos], min_key)
		if max_key is None:
			max_pos = len(_maxes) - 1
			max_idx = len(_keys[max_pos])
		elif inclusive[1]:
			max_pos = bisect_right(_maxes, max_key)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_keys[max_pos])
			else:
				max_idx = bisect_right(_keys[max_pos], max_key)
		else:
			max_pos = bisect_left(_maxes, max_key)
			if max_pos == len(_maxes):
				max_pos -= 1
				max_idx = len(_keys[max_pos])
			else:
				max_idx = bisect_left(_keys[max_pos], max_key)
		return self._islice(min_pos, min_idx, max_pos, max_idx, reverse)
	_irange_key = irange_key

	def bisect_left(self, value):
		return self._bisect_key_left(self._key(value))

	def bisect_right(self, value):
		return self._bisect_key_right(self._key(value))
	bisect = bisect_right

	def bisect_key_left(self, key):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return self._len
		idx = bisect_left(self._keys[pos], key)
		return self._loc(pos, idx)
	_bisect_key_left = bisect_key_left

	def bisect_key_right(self, key):
		_maxes = self._maxes
		if not _maxes:
			return 0
		pos = bisect_right(_maxes, key)
		if pos == len(_maxes):
			return self._len
		idx = bisect_right(self._keys[pos], key)
		return self._loc(pos, idx)
	bisect_key = bisect_key_right
	_bisect_key_right = bisect_key_right

	def count(self, value):
		_maxes = self._maxes
		if not _maxes:
			return 0
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			return 0
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		total = 0
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				return total
			if _lists[pos][idx] == value:
				total += 1
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					return total
				len_sublist = len(_keys[pos])
				idx = 0

	def copy(self):
		return self.__class__(self, key=self._key)
	__copy__ = copy

	def index(self, value, start=None, stop=None):
		_len = self._len
		if not _len:
			raise ValueError('{0!r} is not in list'.format(value))
		if start is None:
			start = 0
		if start < 0:
			start += _len
		if start < 0:
			start = 0
		if stop is None:
			stop = _len
		if stop < 0:
			stop += _len
		if stop > _len:
			stop = _len
		if stop <= start:
			raise ValueError('{0!r} is not in list'.format(value))
		_maxes = self._maxes
		key = self._key(value)
		pos = bisect_left(_maxes, key)
		if pos == len(_maxes):
			raise ValueError('{0!r} is not in list'.format(value))
		stop -= 1
		_lists = self._lists
		_keys = self._keys
		idx = bisect_left(_keys[pos], key)
		len_keys = len(_keys)
		len_sublist = len(_keys[pos])
		while True:
			if _keys[pos][idx] != key:
				raise ValueError('{0!r} is not in list'.format(value))
			if _lists[pos][idx] == value:
				loc = self._loc(pos, idx)
				if start <= loc <= stop:
					return loc
				elif loc > stop:
					break
			idx += 1
			if idx == len_sublist:
				pos += 1
				if pos == len_keys:
					raise ValueError('{0!r} is not in list'.format(value))
				len_sublist = len(_keys[pos])
				idx = 0
		raise ValueError('{0!r} is not in list'.format(value))

	def __add__(self, other):
		values = reduce(iadd, self._lists, [])
		values.extend(other)
		return self.__class__(values, key=self._key)
	__radd__ = __add__

	def __mul__(self, num):
		values = reduce(iadd, self._lists, []) * num
		return self.__class__(values, key=self._key)

	def __reduce__(self):
		values = reduce(iadd, self._lists, [])
		return (type(self), (values, self.key))

	@recursive_repr()
	def __repr__(self):
		type_name = type(self).__name__
		return '{0}({1!r}, key={2!r})'.format(type_name, list(self), self._key)

	def _check(self):
		try:
			assert self._load >= 4
			assert len(self._maxes) == len(self._lists) == len(self._keys)
			assert self._len == sum((len(sublist) for sublist in self._lists))
			for sublist in self._keys:
				for pos in range(1, len(sublist)):
					assert sublist[pos - 1] <= sublist[pos]
			for pos in range(1, len(self._keys)):
				assert self._keys[pos - 1][-1] <= self._keys[pos][0]
			for (val_sublist, key_sublist) in zip(self._lists, self._keys):
				assert len(val_sublist) == len(key_sublist)
				for (val, key) in zip(val_sublist, key_sublist):
					assert self._key(val) == key
			for pos in range(len(self._maxes)):
				assert self._maxes[pos] == self._keys[pos][-1]
			double = self._load << 1
			assert all((len(sublist) <= double for sublist in self._lists))
			half = self._load >> 1
			for pos in range(0, len(self._lists) - 1):
				assert len(self._lists[pos]) >= half
			if self._index:
				assert self._len == self._index[0]
				assert len(self._index) == self._offset + len(self._lists)
				for pos in range(len(self._lists)):
					leaf = self._index[self._offset + pos]
					assert leaf == len(self._lists[pos])
				for pos in range(self._offset):
					child = (pos << 1) + 1
					if child >= len(self._index):
						assert self._index[pos] == 0
					elif child + 1 == len(self._index):
						assert self._index[pos] == self._index[child]
					else:
						child_sum = self._index[child] + self._index[child + 1]
						assert child_sum == self._index[pos]
		except BaseException:
			traceback.print_exc(file=sys.stdout)
			print('len', self._len)
			print('load', self._load)
			print('offset', self._offset)
			print('len_index', len(self._index))
			print('index', self._index)
			print('len_maxes', len(self._maxes))
			print('maxes', self._maxes)
			print('len_keys', len(self._keys))
			print('keys', self._keys)
			print('len_lists', len(self._lists))
			print('lists', self._lists)
			raise

class SortedSet(MutableSet, Sequence):

	def __init__(self, iterable=None, key=None):
		self._key = key
		if not hasattr(self, '_set'):
			self._set = set()
		self._list = SortedList(self._set, key=key)
		_set = self._set
		self.isdisjoint = _set.isdisjoint
		self.issubset = _set.issubset
		self.issuperset = _set.issuperset
		_list = self._list
		self.bisect_left = _list.bisect_left
		self.bisect = _list.bisect
		self.bisect_right = _list.bisect_right
		self.index = _list.index
		self.irange = _list.irange
		self.islice = _list.islice
		self._reset = _list._reset
		if key is not None:
			self.bisect_key_left = _list.bisect_key_left
			self.bisect_key_right = _list.bisect_key_right
			self.bisect_key = _list.bisect_key
			self.irange_key = _list.irange_key
		if iterable is not None:
			self._update(iterable)

	@classmethod
	def _fromset(cls, values, key=None):
		sorted_set = object.__new__(cls)
		sorted_set._set = values
		sorted_set.__init__(key=key)
		return sorted_set

	@property
	def key(self):
		return self._key

	def __contains__(self, value):
		return value in self._set

	def __getitem__(self, index):
		return self._list[index]

	def __delitem__(self, index):
		_set = self._set
		_list = self._list
		if isinstance(index, slice):
			values = _list[index]
			_set.difference_update(values)
		else:
			value = _list[index]
			_set.remove(value)
		del _list[index]

	def __make_cmp(set_op, symbol, doc):

		def comparer(self, other):
			if isinstance(other, SortedSet):
				return set_op(self._set, other._set)
			elif isinstance(other, Set):
				return set_op(self._set, other)
			return NotImplemented
		set_op_name = set_op.__name__
		comparer.__name__ = '__{0}__'.format(set_op_name)
		doc_str = 'Return true if and only if sorted set is {0} `other`.\n        ``ss.__{1}__(other)`` <==> ``ss {2} other``\n        Comparisons use subset and superset semantics as with sets.\n        Runtime complexity: `O(n)`\n        :param other: `other` set\n        :return: true if sorted set is {0} `other`\n        '
		comparer.__doc__ = dedent(doc_str.format(doc, set_op_name, symbol))
		return comparer
	__eq__ = __make_cmp(eq, '==', 'equal to')
	__ne__ = __make_cmp(ne, '!=', 'not equal to')
	__lt__ = __make_cmp(lt, '<', 'a proper subset of')
	__gt__ = __make_cmp(gt, '>', 'a proper superset of')
	__le__ = __make_cmp(le, '<=', 'a subset of')
	__ge__ = __make_cmp(ge, '>=', 'a superset of')
	__make_cmp = staticmethod(__make_cmp)

	def __len__(self):
		return len(self._set)

	def __iter__(self):
		return iter(self._list)

	def __reversed__(self):
		return reversed(self._list)

	def add(self, value):
		_set = self._set
		if value not in _set:
			_set.add(value)
			self._list.add(value)
	_add = add

	def clear(self):
		self._set.clear()
		self._list.clear()

	def copy(self):
		return self._fromset(set(self._set), key=self._key)
	__copy__ = copy

	def count(self, value):
		return 1 if value in self._set else 0

	def discard(self, value):
		_set = self._set
		if value in _set:
			_set.remove(value)
			self._list.remove(value)
	_discard = discard

	def pop(self, index=-1):
		value = self._list.pop(index)
		self._set.remove(value)
		return value

	def remove(self, value):
		self._set.remove(value)
		self._list.remove(value)

	def difference(self, *iterables):
		diff = self._set.difference(*iterables)
		return self._fromset(diff, key=self._key)
	__sub__ = difference

	def difference_update(self, *iterables):
		_set = self._set
		_list = self._list
		values = set(chain(*iterables))
		if 4 * len(values) > len(_set):
			_set.difference_update(values)
			_list.clear()
			_list.update(_set)
		else:
			_discard = self._discard
			for value in values:
				_discard(value)
		return self
	__isub__ = difference_update

	def intersection(self, *iterables):
		intersect = self._set.intersection(*iterables)
		return self._fromset(intersect, key=self._key)
	__and__ = intersection
	__rand__ = __and__

	def intersection_update(self, *iterables):
		_set = self._set
		_list = self._list
		_set.intersection_update(*iterables)
		_list.clear()
		_list.update(_set)
		return self
	__iand__ = intersection_update

	def symmetric_difference(self, other):
		diff = self._set.symmetric_difference(other)
		return self._fromset(diff, key=self._key)
	__xor__ = symmetric_difference
	__rxor__ = __xor__

	def symmetric_difference_update(self, other):
		_set = self._set
		_list = self._list
		_set.symmetric_difference_update(other)
		_list.clear()
		_list.update(_set)
		return self
	__ixor__ = symmetric_difference_update

	def union(self, *iterables):
		return self.__class__(chain(iter(self), *iterables), key=self._key)
	__or__ = union
	__ror__ = __or__

	def update(self, *iterables):
		_set = self._set
		_list = self._list
		values = set(chain(*iterables))
		if 4 * len(values) > len(_set):
			_list = self._list
			_set.update(values)
			_list.clear()
			_list.update(_set)
		else:
			_add = self._add
			for value in values:
				_add(value)
		return self
	__ior__ = update
	_update = update

	def __reduce__(self):
		return (type(self), (self._set, self._key))

	@recursive_repr()
	def __repr__(self):
		_key = self._key
		key = '' if _key is None else ', key={0!r}'.format(_key)
		type_name = type(self).__name__
		return '{0}({1!r}{2})'.format(type_name, list(self), key)

	def _check(self):
		_set = self._set
		_list = self._list
		_list._check()
		assert len(_set) == len(_list)
		assert all((value in _set for value in _list))

class SortedDict(dict):

	def __init__(self, *args, **kwargs):
		if args and (args[0] is None or callable(args[0])):
			_key = self._key = args[0]
			args = args[1:]
		else:
			_key = self._key = None
		self._list = SortedList(key=_key)
		_list = self._list
		self._list_add = _list.add
		self._list_clear = _list.clear
		self._list_iter = _list.__iter__
		self._list_reversed = _list.__reversed__
		self._list_pop = _list.pop
		self._list_remove = _list.remove
		self._list_update = _list.update
		self.bisect_left = _list.bisect_left
		self.bisect = _list.bisect_right
		self.bisect_right = _list.bisect_right
		self.index = _list.index
		self.irange = _list.irange
		self.islice = _list.islice
		self._reset = _list._reset
		if _key is not None:
			self.bisect_key_left = _list.bisect_key_left
			self.bisect_key_right = _list.bisect_key_right
			self.bisect_key = _list.bisect_key
			self.irange_key = _list.irange_key
		self._update(*args, **kwargs)

	@property
	def key(self):
		return self._key

	@property
	def iloc(self):
		try:
			return self._iloc
		except AttributeError:
			warnings.warn('sorted_dict.iloc is deprecated. Use SortedDict.keys() instead.', DeprecationWarning, stacklevel=2)
			_iloc = self._iloc = SortedKeysView(self)
			return _iloc

	def clear(self):
		dict.clear(self)
		self._list_clear()

	def __delitem__(self, key):
		dict.__delitem__(self, key)
		self._list_remove(key)

	def __iter__(self):
		return self._list_iter()

	def __reversed__(self):
		return self._list_reversed()

	def __setitem__(self, key, value):
		if key not in self:
			self._list_add(key)
		dict.__setitem__(self, key, value)
	_setitem = __setitem__

	def copy(self):
		return self.__class__(self._key, self.items())
	__copy__ = copy

	@classmethod
	def fromkeys(cls, iterable, value=None):
		return cls(((key, value) for key in iterable))

	def keys(self):
		return SortedKeysView(self)

	def items(self):
		return SortedItemsView(self)

	def values(self):
		return SortedValuesView(self)

	class _NotGiven(object):

		def __repr__(self):
			return '<not-given>'
	__not_given = _NotGiven()

	def pop(self, key, default=__not_given):
		if key in self:
			self._list_remove(key)
			return dict.pop(self, key)
		else:
			if default is self.__not_given:
				raise KeyError(key)
			return default

	def popitem(self, index=-1):
		if not self:
			raise KeyError('popitem(): dictionary is empty')
		key = self._list_pop(index)
		value = dict.pop(self, key)
		return (key, value)

	def peekitem(self, index=-1):
		key = self._list[index]
		return (key, self[key])

	def setdefault(self, key, default=None):
		if key in self:
			return self[key]
		dict.__setitem__(self, key, default)
		self._list_add(key)
		return default

	def update(self, *args, **kwargs):
		if not self:
			dict.update(self, *args, **kwargs)
			self._list_update(dict.__iter__(self))
			return
		if not kwargs and len(args) == 1 and isinstance(args[0], dict):
			pairs = args[0]
		else:
			pairs = dict(*args, **kwargs)
		if 10 * len(pairs) > len(self):
			dict.update(self, pairs)
			self._list_clear()
			self._list_update(dict.__iter__(self))
		else:
			for key in pairs:
				self._setitem(key, pairs[key])
	_update = update

	def __reduce__(self):
		items = dict.copy(self)
		return (type(self), (self._key, items))

	@recursive_repr()
	def __repr__(self):
		_key = self._key
		type_name = type(self).__name__
		key_arg = '' if _key is None else '{0!r}, '.format(_key)
		item_format = '{0!r}: {1!r}'.format
		items = ', '.join((item_format(key, self[key]) for key in self._list))
		return '{0}({1}{{{2}}})'.format(type_name, key_arg, items)

	def _check(self):
		_list = self._list
		_list._check()
		assert len(self) == len(_list)
		assert all((key in self for key in _list))

def _view_delitem(self, index):
	_mapping = self._mapping
	_list = _mapping._list
	dict_delitem = dict.__delitem__
	if isinstance(index, slice):
		keys = _list[index]
		del _list[index]
		for key in keys:
			dict_delitem(_mapping, key)
	else:
		key = _list.pop(index)
		dict_delitem(_mapping, key)

class SortedKeysView(KeysView, Sequence):
	__slots__ = ()

	@classmethod
	def _from_iterable(cls, it):
		return SortedSet(it)

	def __getitem__(self, index):
		return self._mapping._list[index]
	__delitem__ = _view_delitem

class SortedItemsView(ItemsView, Sequence):
	__slots__ = ()

	@classmethod
	def _from_iterable(cls, it):
		return SortedSet(it)

	def __getitem__(self, index):
		_mapping = self._mapping
		_mapping_list = _mapping._list
		if isinstance(index, slice):
			keys = _mapping_list[index]
			return [(key, _mapping[key]) for key in keys]
		key = _mapping_list[index]
		return (key, _mapping[key])
	__delitem__ = _view_delitem

class SortedValuesView(ValuesView, Sequence):
	__slots__ = ()

	def __getitem__(self, index):
		_mapping = self._mapping
		_mapping_list = _mapping._list
		if isinstance(index, slice):
			keys = _mapping_list[index]
			return [_mapping[key] for key in keys]
		key = _mapping_list[index]
		return _mapping[key]
	__delitem__ = _view_delitem

def hash(a, b):
	return a * 10 ** 6 + b

def decode(hash):
	return divmod(hash, 10 ** 6)
(N, Q) = map(int, input().split())
rsl = SortedList()
csl = SortedList()
rsl.add(hash(0, 0))
rsl.add(hash(N, N))
csl.add(hash(0, 0))
csl.add(hash(N, N))
ans = (N - 2) * (N - 2)
for i in range(Q):
	(a, x) = map(int, input().split())
	if a == 1:
		idx = rsl.bisect_left(x * 10 ** 6)
		h = rsl[idx]
		(d1, d2) = decode(h)
		ans -= d2 - 2
		csl.add(hash(d2 - 1, x))
	if a == 2:
		idx = csl.bisect_left(x * 10 ** 6)
		h = csl[idx]
		(d1, d2) = decode(h)
		ans -= d2 - 2
		rsl.add(hash(d2 - 1, x))
print(ans)


(n, q) = map(int, input().split())
queries = [list(map(int, input().split())) for _ in range(q)]
v = n - 1
h = n - 1
tate = [n - 1] * n
yoko = [n - 1] * n
ans = (n - 2) ** 2
for (q1, q2) in queries:
	q2 -= 1
	if q1 == 1:
		if q2 < h:
			ans -= v - 1
			for i in range(h, q2, -1):
				tate[i] = v
			h = q2
		else:
			ans -= tate[q2] - 1
	elif q2 < v:
		ans -= max(0, h - 1)
		for i in range(v, q2, -1):
			yoko[i] = h
		v = q2
	else:
		ans -= yoko[q2] - 1
print(ans)


import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
readlines = sys.stdin.buffer.readlines
inf = 10 ** 10

class Seg_min:

	def __init__(self, x):
		self.ide_ele_min = inf
		self.func = min
		self.n = len(x)
		self.num_max = 2 ** (self.n - 1).bit_length()
		self.x = [self.ide_ele_min] * 2 * self.num_max
		for (i, num) in enumerate(x, self.num_max):
			self.x[i] = num
		for i in range(self.num_max - 1, 0, -1):
			self.x[i] = self.func(self.x[i << 1], self.x[(i << 1) + 1])

	def update(self, i, x):
		i += self.num_max
		self.x[i] = x
		while i > 0:
			i = i // 2
			self.x[i] = self.func(self.x[i << 1], self.x[(i << 1) + 1])

	def query(self, i, j):
		res = self.ide_ele_min
		if i >= j:
			return res
		i += self.num_max
		j += self.num_max - 1
		while i <= j:
			if i == j:
				res = self.func(res, self.x[i])
				break
			if i & 1:
				res = self.func(res, self.x[i])
				i += 1
			if not j & 1:
				res = self.func(res, self.x[j])
				j -= 1
			i = i >> 1
			j = j >> 1
		return res
(n, q, *query) = list(map(int, read().split()))
wall_ns = Seg_min([inf] * (n - 2))
wall_ew = Seg_min([inf] * (n - 2))
min_ns = [n - 2] * (q + 1)
min_ew = [n - 2] * (q + 1)
ans = (n - 2) * (n - 2)
for i in range(1, q + 1):
	x = query[i * 2 - 1] - 2
	if query[i * 2 - 2] == 1:
		last = wall_ns.query(0, x)
		if last == inf:
			last = i - 1
		ans -= min_ew[last]
		wall_ns.update(x, i)
		min_ns[i] = min(min_ns[i - 1], x)
		min_ew[i] = min_ew[i - 1]
	else:
		last = wall_ew.query(0, x)
		if last == inf:
			last = i - 1
		ans -= min_ns[last]
		wall_ew.update(x, i)
		min_ew[i] = min(min_ew[i - 1], x)
		min_ns[i] = min_ns[i - 1]
print(ans)


import sys
sys.setrecursionlimit(10 ** 6)
int1 = lambda x: int(x) - 1
p2D = lambda x: print(*x, sep='\n')

def II():
	return int(sys.stdin.readline())

def MI():
	return map(int, sys.stdin.readline().split())

def LI():
	return list(map(int, sys.stdin.readline().split()))

def LLI(rows_number):
	return [LI() for _ in range(rows_number)]

def SI():
	return sys.stdin.readline()[:-1]

class BIT:

	def __init__(self, n):
		self.inf = 10 ** 9
		self.n = n + 3
		self.table = [self.inf] * (self.n + 1)

	def update(self, i, x):
		i += 1
		while i <= self.n:
			if x < self.table[i]:
				self.table[i] = x
			i += i & -i

	def min(self, i):
		i += 1
		res = self.inf
		while i > 0:
			if self.table[i] < res:
				res = self.table[i]
			i -= i & -i
		return res
inf = 10 ** 9
(n, q) = MI()
ans = (n - 2) ** 2
t = l = n
yo = []
ta = []
for i in range(q):
	(op, x) = MI()
	if op == 1:
		ta.append((i, x))
	else:
		yo.append((i, x))
if not ta or not yo:
	ans -= (len(ta) + len(yo)) * (n - 2)
	print(ans)
	return

def cnt(ia, jb):
	res = 0
	bit = BIT(q + 5)
	for (i, a) in ia:
		bit.update(i, a)
	jb.sort(key=lambda x: x[1])
	now = 2
	for (j, b) in jb:
		cur = bit.min(j)
		if cur == inf:
			cur = n
		now = max(now, cur)
		res += now - 2
	return res
ans -= cnt(ta, yo)
ans -= cnt(yo, ta)
print(ans)


(n, q) = map(int, input().split())
query = [list(input().split()) for _ in range(q)]
from bisect import bisect_right as bl
ax = [-n]
vx = [n - 2]
ay = [-n]
vy = [n - 2]
ans = (n - 2) ** 2
for (t, i) in query:
	i = int(i)
	if t == '1':
		idx = bl(ax, -i)
		if idx == len(ax):
			ax.append(-i)
			vx.append(vx[-1])
			vy[-1] = i - 2
		ans -= vx[idx - 1]
	else:
		idx = bl(ay, -i)
		if idx == len(ay):
			ay.append(-i)
			vy.append(vy[-1])
			vx[-1] = i - 2
		ans -= vy[idx - 1]
print(ans)


def main():
	(n, q) = map(int, input().split())
	(H, V) = ([0] * (n + 1), [0] * (n + 1))
	(h, v) = (n, n)
	cnt = 0
	for _ in range(q):
		(s, x) = map(int, input().split())
		if s == 1:
			if x < v:
				cnt += h - 2
				for i in range(x, v):
					H[i] = h
				v = x
			else:
				cnt += H[x] - 2
		if s == 2:
			if x < h:
				cnt += v - 2
				for i in range(x, h):
					V[i] = v
				h = x
			else:
				cnt += V[x] - 2
	print((n - 2) ** 2 - cnt)
main()


(n, q) = list(map(int, input().split()))
ans = (n - 2) ** 2
d = [n] * (n + 1)
r = [n] * (n + 1)
rmin = n
dmin = n
for _ in range(q):
	(query, x) = list(map(int, input().split()))
	if query == 1:
		if x < rmin:
			for i in range(rmin, x - 1, -1):
				r[i] = dmin
			rmin = x
		ans -= r[x] - 2
	else:
		if x < dmin:
			for i in range(dmin, x - 1, -1):
				d[i] = rmin
			dmin = x
		ans -= d[x] - 2
print(ans)


(n, q) = map(int, input().split())
l = [0] * n
u = [0] * n
lmin = n - 2
umin = n - 2
lgoal = n
ugoal = n
for _ in range(q):
	(s, t) = map(int, input().split())
	if s == 1:
		if t > ugoal:
			u[t - 1] = 0
		else:
			for i in range(t, ugoal - 1):
				u[i] = umin
			lmin = t - 2
			ugoal = t
	elif t > lgoal:
		l[t - 1] = 0
	else:
		for i in range(t, lgoal - 1):
			l[i] = lmin
		umin = t - 2
		lgoal = t
print(sum(l) + sum(u) + lmin * umin)


class SegmentTreeDual:

	def __init__(self, arr, op=lambda x, y: y if y != -1 else x, ie=-1):
		self.h = (len(arr) - 1).bit_length()
		self.n = 2 ** self.h
		self.ie = ie
		self.op = op
		self.val = [ie for _ in range(self.n)]
		self.laz = [ie for _ in range(2 * self.n)]
		for i in range(len(arr)):
			self.val[i] = arr[i]

	def propagate(self, k):
		if self.laz[k] == self.ie:
			return
		if self.n <= k:
			self.val[k - self.n] = self.op(self.val[k - self.n], self.laz[k])
		else:
			self.laz[2 * k] = self.op(self.laz[2 * k], self.laz[k])
			self.laz[2 * k + 1] = self.op(self.laz[2 * k + 1], self.laz[k])
		self.laz[k] = self.ie

	def update(self, lt, rt, x):
		lt += self.n
		rt += self.n
		while rt - lt > 0:
			if lt & 1:
				self.laz[lt] = self.op(self.laz[lt], x)
				lt += 1
			if rt & 1:
				rt -= 1
				self.laz[rt] = self.op(self.laz[rt], x)
			lt >>= 1
			rt >>= 1

	def get(self, idx):
		res = self.val[idx]
		idx += self.n
		while idx:
			res = self.op(res, self.laz[idx])
			idx >>= 1
		return res
import sys
input = sys.stdin.buffer.readline
(N, Q) = map(int, input().split())
x = [N - 1] * (N - 1) + [0]
y = [N - 1] * (N - 1) + [0]
stx = SegmentTreeDual(x, min, 10 ** 18)
sty = SegmentTreeDual(y, min, 10 ** 18)
res = (N - 2) * (N - 2)
for _ in range(Q):
	(q, k) = map(int, input().split())
	if q == 1:
		g = stx.get(k - 1)
		res -= g - 1
		sty.update(1, g, k - 1)
	if q == 2:
		g = sty.get(k - 1)
		res -= g - 1
		stx.update(1, g, k - 1)
print(res)


from itertools import accumulate
import sys
read = sys.stdin.buffer.read
readline = sys.stdin.buffer.readline
max2 = lambda x, y: x if x > y else y
min2 = lambda x, y: x if x < y else y

def solve(N, queries):
	N -= 2
	X = [0] * (N + 1)
	Y = [0] * (N + 1)
	for (a, b) in queries:
		if b == 0:
			continue
		if a == 0:
			X[b] += 1
		else:
			Y[b] += 1
	X = tuple(accumulate(X))
	Y = tuple(accumulate(Y))
	w = N
	h = N
	res = 0
	for (a, b) in queries:
		b -= 1
		if a == 0:
			if w > b:
				res += (X[w] - X[b]) * h
				w = b
		elif h > b:
			res += (Y[h] - Y[b]) * w
			h = b
	return N * N - res
(N, Q) = map(int, readline().split())
m = map(lambda x: int(x) - 1, read().split())
queries = tuple(zip(m, m))
print(solve(N, queries))


import sys
input = sys.stdin.readline
(N, Q) = map(int, input().split())
Qs = [list(map(int, input().split())) for _ in range(Q)]

class SegmentTree:

	def __init__(self, n, segfunc=min, ele=10 ** 10):
		self.ide_ele = ele
		self.num = pow(2, (n - 1).bit_length())
		self.seg = [self.ide_ele] * 2 * self.num
		self.segfunc = segfunc

	def init(self, init_val):
		for i in range(len(init_val)):
			self.seg[i + self.num - 1] = init_val[i]
		for i in range(self.num - 2, -1, -1):
			self.seg[i] = self.segfunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

	def update(self, k, x):
		k += self.num - 1
		self.seg[k] = x
		while k:
			k = (k - 1) // 2
			self.seg[k] = self.segfunc(self.seg[k * 2 + 1], self.seg[k * 2 + 2])

	def query(self, p, q):
		if q <= p:
			return self.ide_ele
		p += self.num - 1
		q += self.num - 2
		res = self.ide_ele
		while q - p > 1:
			if p & 1 == 0:
				res = self.segfunc(res, self.seg[p])
			if q & 1 == 1:
				res = self.segfunc(res, self.seg[q])
				q -= 1
			p = p // 2
			q = (q - 1) // 2
		if p == q:
			res = self.segfunc(res, self.seg[p])
		else:
			res = self.segfunc(self.segfunc(res, self.seg[p]), self.seg[q])
		return res
cols = SegmentTree(N, ele=N - 1)
raws = SegmentTree(N, ele=N - 1)
ans = (N - 2) * (N - 2)
for (q, x) in Qs:
	x -= 1
	if q == 1:
		i = cols.query(x, N)
		raws.update(i, min(x, raws.seg[raws.num - 1 + i]))
		ans -= i - 1
	if q == 2:
		i = raws.query(x, N)
		cols.update(i, min(x, cols.seg[cols.num - 1 + i]))
		ans -= i - 1
print(ans)


import sys
input = lambda : sys.stdin.readline().rstrip()

class SegmentTreeDual:

	def __init__(self, init, initX, unitA, g, h):
		self.g = g
		self.h = h
		self.unitA = unitA
		if type(init) == int:
			self.n = init
			self.n = 1 << (self.n - 1).bit_length()
			self.X = [initX] * (self.n * 2)
			self.size = [1] * (self.n * 2)
		else:
			self.n = len(init)
			self.n = 1 << (self.n - 1).bit_length()
			self.X = [initX] * self.n + init + [initX] * (self.n - len(init))
			self.size = [0] * self.n + [1] * len(init) + [0] * (self.n - len(init))
		for i in range(self.n - 1, 0, -1):
			self.size[i] = self.size[i * 2] + self.size[i * 2 | 1]
		self.A = [unitA] * (self.n * 2)

	def calc(self, i):
		return self.g(self.X[i], self.A[i], self.size[i])

	def propagate(self, i):
		self.X[i] = self.g(self.X[i], self.A[i], self.size[i])
		self.A[i * 2] = self.h(self.A[i * 2], self.A[i])
		self.A[i * 2 | 1] = self.h(self.A[i * 2 | 1], self.A[i])
		self.A[i] = self.unitA

	def propagate_above(self, i):
		H = i.bit_length()
		for h in range(H, 0, -1):
			self.propagate(i >> h)

	def propagate_all(self):
		for i in range(1, self.n):
			self.propagate(i)

	def getvalue(self, i):
		i += self.n
		self.propagate_above(i)
		return self.calc(i)

	def operate_range(self, l, r, a):
		l += self.n
		r += self.n
		(l0, r0) = (l // (l & -l), r // (r & -r) - 1)
		self.propagate_above(l0)
		self.propagate_above(r0)
		while l < r:
			if l & 1:
				self.A[l] = self.h(self.A[l], a)
				l += 1
			if r & 1:
				r -= 1
				self.A[r] = self.h(self.A[r], a)
			l >>= 1
			r >>= 1

	def check(self, randX, randA, maxs, rep):
		from random import randrange
		for _ in range(rep):
			x = randX()
			a = randA()
			b = randA()
			c = randA()
			s = randrange(1, maxs + 1)
			err = 0
			if not h(a, unitA) == h(unitA, a) == a:
				err = 1
				print('!!!!! unitA Error !!!!!')
				print('unitA =', unitA)
				print('a =', a)
				print('f(a, unitA) =', f(a, unitA))
				print('f(unitA, a) =', f(unitA, a))
			if not h(h(a, b), c) == h(a, h(b, c)):
				err = 1
				print('!!!!! Associativity Error A !!!!!')
				print('a, b, c, h(a, b), h(b, c) =', a, b, c, h(a, b), h(b, c))
				print('h(h(a, b), c) =', h(h(a, b), c))
				print('h(a, h(b, c)) =', h(a, h(b, c)))
			if not g(x, unitA, s) == x:
				err = 1
				print('!!!!! Identity Error !!!!!')
				print('unitA, x, s =', unitA, x, s)
				print('g(x, unitA, s) =', g(x, unitA, s))
			if not g(g(x, a, s), b, s) == g(x, h(a, b), s):
				err = 1
				print('!!!!! Act Error !!!!!')
				print('x, a, b, s, g(x, a, s), h(a, b) =', x, a, b, s, g(x, a, s), h(a, b))
				print('g(g(x, a, s), b, s) =', g(g(x, a, s), b, s))
				print('g(x, h(a, b), s)    =', g(x, h(a, b), s))
			if err:
				break
				assert h(a, unitA) == h(unitA, a) == a
				assert h(h(a, b), c) == h(a, h(b, c))
				assert g(x, unitA, s) == x
				assert g(g(x, a, s), b, s) == g(x, h(a, b), s)
		else:
			pass
			print('Monoid Check OK!')

	def debug(self):
		print('self.n =', self.n)
		deX = []
		deA = []
		deS = []
		(a, b) = (self.n, self.n * 2)
		while b:
			deX.append(self.X[a:b])
			deA.append(self.A[a:b])
			deS.append(self.size[a:b])
			(a, b) = (a // 2, a)
		print('--- debug ---')
		for d in deX[::-1]:
			print(d)
		print('--- ---')
		for d in deA[::-1]:
			print(d)
		print('--- ---')
		for d in deS[::-1]:
			print(d)
		print('--- ---')
(N, Q) = map(int, input().split())
g = lambda x, a, s: min(x, a)
h = lambda a, b: min(a, b)
unitA = 1 << 30
initX = N
st1 = SegmentTreeDual(N, initX, unitA, g, h)
st2 = SegmentTreeDual(N, initX, unitA, g, h)
if False:
	from random import randrange
	randX = lambda : randrange(-10, 11)
	randA = lambda : [-1, randrange(21)][randrange(2)]
	maxs = 10
	rep = 1000
	st1.check(randX, randA, maxs, rep)
	st2.check(randX, randA, maxs, rep)
	print('END')
ans = (N - 2) ** 2
for _ in range(Q):
	(t, x) = map(int, input().split())
	if t == 1:
		a = st2.getvalue(x)
		ans -= a - 2
		st1.operate_range(1, a, x)
	else:
		a = st1.getvalue(x)
		ans -= a - 2
		st2.operate_range(1, a, x)
print(ans)


class SegTreeBool:

	def segFunc(self, x, y):
		return x + y

	def searchIndexFunc(self, val):
		return val > 0

	def __init__(self, ide, init_val):
		n = len(init_val)
		self.ide_ele = ide
		self.num = 2 ** (n - 1).bit_length()
		self.seg = [self.ide_ele] * 2 * self.num
		for i in range(n):
			self.seg[i + self.num - 1] = init_val[i]
		for i in range(self.num - 2, -1, -1):
			self.seg[i] = self.segFunc(self.seg[2 * i + 1], self.seg[2 * i + 2])

	def update(self, idx, val):
		idx += self.num - 1
		self.seg[idx] = val
		while idx:
			idx = (idx - 1) // 2
			self.seg[idx] = self.segFunc(self.seg[idx * 2 + 1], self.seg[idx * 2 + 2])

	def query(self, begin, end):
		if end <= begin:
			return self.ide_ele
		begin += self.num - 1
		end += self.num - 2
		res = self.ide_ele
		while begin + 1 < end:
			if begin & 1 == 0:
				res = self.segFunc(res, self.seg[begin])
			if end & 1 == 1:
				res = self.segFunc(res, self.seg[end])
				end -= 1
			begin = begin // 2
			end = (end - 1) // 2
		if begin == end:
			res = self.segFunc(res, self.seg[begin])
		else:
			res = self.segFunc(self.segFunc(res, self.seg[begin]), self.seg[end])
		return res

	def getLargestIndex(self, begin, end):
		(L, R) = (begin, end)
		if not self.searchIndexFunc(self.query(begin, end)):
			return None
		while L + 1 < R:
			P = (L + R) // 2
			if self.searchIndexFunc(self.query(P, R)):
				L = P
			else:
				R = P
		return L

	def getSmallestIndex(self, begin, end):
		(L, R) = (begin, end)
		if not self.searchIndexFunc(self.query(begin, end)):
			return None
		while L + 1 < R:
			P = (L + R + 1) // 2
			if self.searchIndexFunc(self.query(L, P)):
				R = P
			else:
				L = P
		return L

def main():
	(n, q) = map(int, input().split())
	qry = [list(map(int, input().split())) for _ in range(q)]
	ans = (n - 2) ** 2
	(m1, m2) = (n, n)
	segbool1 = SegTreeBool(0, [0] * n)
	segbool2 = SegTreeBool(0, [0] * n)
	ms1 = [n] * n
	ms2 = [n] * n
	for (ptn, idx) in qry:
		if ptn == 1:
			tmp = None
			if segbool1.query(0, idx) == 0:
				tmp = m2 - 2
			else:
				pt = segbool1.getLargestIndex(0, idx)
				tmp = ms1[pt]
			ans -= tmp
			ms1[idx] = tmp
			segbool1.update(idx, 1)
			if idx < m1:
				m1 = idx
		else:
			tmp = None
			if segbool2.query(0, idx) == 0:
				tmp = m1 - 2
			else:
				pt = segbool2.getLargestIndex(0, idx)
				tmp = ms2[pt]
			ans -= tmp
			ms2[idx] = tmp
			segbool2.update(idx, 1)
			if idx < m2:
				m2 = idx
	print(ans)
main()