There is a grass field that stretches infinitely.
In this field, there is a negligibly small cow. Let (x, y) denote the point that is x\ \mathrm{cm} south and y\ \mathrm{cm} east of the point where the cow stands now. The cow itself is standing at (0, 0).
There are also N north-south lines and M east-west lines drawn on the field. The i-th north-south line is the segment connecting the points (A_i, C_i) and (B_i, C_i), and the j-th east-west line is the segment connecting the points (D_j, E_j) and (D_j, F_j).
What is the area of the region the cow can reach when it can move around as long as it does not cross the segments (including the endpoints)? If this area is infinite, print INF instead.

-----Constraints-----
 - All values in input are integers between -10^9 and 10^9  (inclusive).
 - 1 \leq N, M \leq 1000
 - A_i < B_i\ (1 \leq i \leq N)
 - E_j < F_j\ (1 \leq j \leq M)
 - The point (0, 0) does not lie on any of the given segments.

-----Input-----
Input is given from Standard Input in the following format:
N M
A_1 B_1 C_1
:
A_N B_N C_N
D_1 E_1 F_1
:
D_M E_M F_M

-----Output-----
If the area of the region the cow can reach is infinite, print INF; otherwise, print an integer representing the area in \mathrm{cm^2}.
(Under the constraints, it can be proved that the area of the region is always an integer if it is not infinite.)

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

-----Sample Output-----
13

The area of the region the cow can reach is 13\ \mathrm{cm^2}.

Difficulty: MEDIUM_HARD

Solutions:
(N, M) = map(int, input().split())
h_lines = {}
v_lines = {}
for _ in range(N):
	(a, b, c) = map(int, input().split())
	if c in v_lines:
		v_lines[c].append((a, b))
	else:
		v_lines[c] = [(a, b)]
for _ in range(M):
	(d, e, f) = map(int, input().split())
	if d in h_lines:
		h_lines[d].append((e, f))
	else:
		h_lines[d] = [(e, f)]
h_lines = list(h_lines.items())
v_lines = list(v_lines.items())
h_lines.sort()
v_lines.sort()
rows = len(v_lines) - 1
cols = len(h_lines) - 1
h_walls = [[False] * rows for _ in range(cols + 1)]
v_walls = [[False] * (rows + 1) for _ in range(cols)]
for (i, (y, l)) in enumerate(h_lines):
	for (x1, x2) in l:
		j = 0
		while j < rows:
			if x1 <= v_lines[j][0]:
				break
			j += 1
		while j < rows:
			if x2 < v_lines[j + 1][0]:
				break
			h_walls[i][j] = True
			j += 1
for (j, (x, l)) in enumerate(v_lines):
	for (y1, y2) in l:
		i = 0
		while i < cols:
			if y1 <= h_lines[i][0]:
				break
			i += 1
		while i < cols:
			if y2 < h_lines[i + 1][0]:
				break
			v_walls[i][j] = True
			i += 1

def find_initial_pos():
	for i in range(cols):
		if h_lines[i][0] <= 0 and 0 <= h_lines[i + 1][0]:
			for j in range(rows):
				if v_lines[j][0] <= 0 and 0 <= v_lines[j + 1][0]:
					return (i, j)
	return None

def calc_area():
	cur = find_initial_pos()
	if cur == None:
		return 'INF'
	stack = [cur]
	area = 0
	visited = [[False] * rows for _ in range(cols)]
	visited[cur[0]][cur[1]] = True
	search = ((1, 0, lambda y, x: not h_walls[y + 1][x]), (-1, 0, lambda y, x: not h_walls[y][x]), (0, 1, lambda y, x: not v_walls[y][x + 1]), (0, -1, lambda y, x: not v_walls[y][x]))
	while stack:
		(y, x) = stack.pop()
		area += (h_lines[y + 1][0] - h_lines[y][0]) * (v_lines[x + 1][0] - v_lines[x][0])
		for (dy, dx, check) in search:
			if check(y, x):
				ny = y + dy
				nx = x + dx
				if nx < 0 or nx >= rows or ny < 0 or (ny >= cols):
					return 'INF'
				if not visited[ny][nx]:
					stack.append((ny, nx))
					visited[ny][nx] = True
	return str(area)
print(calc_area())


import sys
sys.setrecursionlimit(10 ** 9)
input = sys.stdin.readline
from bisect import bisect_left, bisect_right
INF = 10 ** 18

def resolve():
	(n, m) = map(int, input().split())
	a = [list(map(int, input().split())) for i in range(n)]
	b = [list(map(int, input().split())) for i in range(m)]
	X = {-INF, INF}
	Y = {-INF, INF}
	for i in a:
		Y.add(i[2])
	for i in b:
		X.add(i[0])
	X = list(sorted(X))
	Y = list(sorted(Y))
	n = len(X) - 1
	m = len(Y) - 1
	wallx = [[False] * m for i in range(n)]
	wally = [[False] * m for i in range(n)]
	for (x1, x2, y1) in a:
		x1 = bisect_left(X, x1)
		y1 = bisect_left(Y, y1)
		x2 = bisect_right(X, x2) - 1
		for i in range(x1, x2):
			wally[i][y1] = True
	for (x1, y1, y2) in b:
		x1 = bisect_left(X, x1)
		y1 = bisect_left(Y, y1)
		y2 = bisect_right(Y, y2) - 1
		for i in range(y1, y2):
			wallx[x1][i] = True
	cow = [[False] * m for i in range(n)]
	cx = bisect_right(X, 0) - 1
	cy = bisect_right(Y, 0) - 1
	cow[cx][cy] = True
	q = [(cx, cy)]
	ans = 0
	while q:
		(x, y) = q.pop()
		if not x or not y:
			print('INF')
			return
		ans += (X[x + 1] - X[x]) * (Y[y + 1] - Y[y])
		if x and (not wallx[x][y]) and (not cow[x - 1][y]):
			cow[x - 1][y] = True
			q.append((x - 1, y))
		if y and (not wally[x][y]) and (not cow[x][y - 1]):
			cow[x][y - 1] = True
			q.append((x, y - 1))
		if x + 1 < n and (not wallx[x + 1][y]) and (not cow[x + 1][y]):
			cow[x + 1][y] = True
			q.append((x + 1, y))
		if y + 1 < m and (not wally[x][y + 1]) and (not cow[x][y + 1]):
			cow[x][y + 1] = True
			q.append((x, y + 1))
	print(ans)
resolve()


import bisect
import sys
lower_bound = bisect.bisect_left
upper_bound = bisect.bisect_right
INF = 1073741823
(n, m) = map(int, input().split())
a = [list(map(int, input().split())) for i in range(n)]
b = [list(map(int, input().split())) for i in range(m)]
X = {-INF, INF}
Y = {-INF, INF}
for i in a:
	Y.add(i[2])
for i in b:
	X.add(i[0])
X = list(sorted(X))
Y = list(sorted(Y))
n = len(X) - 1
m = len(Y) - 1
wallx = [[False] * m for i in range(n)]
wally = [[False] * m for i in range(n)]
for (x1, x2, y1) in a:
	x1 = lower_bound(X, x1)
	y1 = lower_bound(Y, y1)
	x2 = upper_bound(X, x2) - 1
	for i in range(x1, x2):
		wally[i][y1] = True
for (x1, y1, y2) in b:
	x1 = lower_bound(X, x1)
	y1 = lower_bound(Y, y1)
	y2 = upper_bound(Y, y2) - 1
	for i in range(y1, y2):
		wallx[x1][i] = True
cow = [[False] * m for i in range(n)]
cx = upper_bound(X, 0) - 1
cy = upper_bound(Y, 0) - 1
cow[cx][cy] = True
q = [(cx, cy)]
ans = 0
while q:
	(x, y) = q.pop()
	if not x or not y:
		print('INF')
		sys.exit()
	ans += (X[x + 1] - X[x]) * (Y[y + 1] - Y[y])
	if x and (not wallx[x][y]) and (not cow[x - 1][y]):
		cow[x - 1][y] = True
		q.append((x - 1, y))
	if y and (not wally[x][y]) and (not cow[x][y - 1]):
		cow[x][y - 1] = True
		q.append((x, y - 1))
	if x + 1 < n and (not wallx[x + 1][y]) and (not cow[x + 1][y]):
		cow[x + 1][y] = True
		q.append((x + 1, y))
	if y + 1 < m and (not wally[x][y + 1]) and (not cow[x][y + 1]):
		cow[x][y + 1] = True
		q.append((x, y + 1))
print(ans)