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

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)


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)


(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)


(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)


(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)


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
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)


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 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)


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()


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()


(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)


(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)


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()


(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)


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)


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)


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
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()


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) = 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)


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)


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 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())
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)


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)


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
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)


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)


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)


(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)


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)


(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)


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)


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()