package main

import (
	"fmt"
	"sort"
)

type Zs struct {
	vals   []int
	inds   []int
	lens   []int
	labels []string
	ranks  map[string][]int
}

func (zs Zs) Len() int {
	return len(zs.inds)
}

func (zs Zs) Less(i, j int) bool {
	return zs.vals[zs.inds[i]] < zs.vals[zs.inds[j]]
}

func (zs Zs) Swap(i, j int) {
	zs.inds[i], zs.inds[j] = zs.inds[j], zs.inds[i]
}

func (zs Zs) GetIndex(i int) (int, string) {
	ind := zs.inds[i]
	for j := 0; j < len(zs.lens); j++ {
		if ind < zs.lens[j] {
			return ind, zs.labels[j]
		}
		ind -= zs.lens[j]
	}
	return -1, ""
}

func (zs Zs) GetVal(i int) int {
	return zs.vals[zs.inds[i]]
}

func NewZs(val_arrs [][]int, lens []int, labels []string) Zs {
	s := 0
	vals := make([]int, 0)
	for j := 0; j < len(lens); j++ {
		s += lens[j]
		vals = append(vals, val_arrs[j]...)
	}
	inds := make([]int, s)
	for i := 0; i < s; i++ {
		inds[i] = i
	}
	zs := Zs{vals, inds, lens, labels, nil}
	sort.Sort(zs)

	zs.ranks = make(map[string][]int)
	for j := 0; j < len(lens); j++ {
		zs.ranks[labels[j]] = make([]int, lens[j])
	}

	for i := 0; i < s; i++ {
		ind, label := zs.GetIndex(i)
		zs.ranks[label][ind] = i
	}

	return zs
}

func can_pass(b1, b2, p1, p2 int) bool {
	return (p1 < b1) || (b2 < p2)
}

func main() {
	var N, M int
	fmt.Scanf("%d %d\n", &N, &M)
	A := make([]int, N)
	B := make([]int, N)
	C := make([]int, N)
	D := make([]int, M)
	E := make([]int, M)
	F := make([]int, M)
	for i := 0; i < N; i++ {
		fmt.Scanf("%d %d %d\n", &A[i], &B[i], &C[i])
	}
	for i := 0; i < M; i++ {
		fmt.Scanf("%d %d %d\n", &D[i], &E[i], &F[i])
	}

	xs := NewZs([][]int{A, B, D}, []int{N, N, M}, []string{"A", "B", "D"})
	ys := NewZs([][]int{E, F, C}, []int{M, M, N}, []string{"E", "F", "C"})

	T := map[string][]int{"A": A, "B": B, "C": C, "D": D, "E": E, "F": F}

	W := 2*N + M - 1
	H := N + 2*M - 1

	if xs.GetVal(W) <= 0 || 0 <= xs.GetVal(0) {
		fmt.Println("INF")
		return
	}
	sx := 0
	for xs.GetVal(sx) < 0 {
		sx++
	}
	sx--

	if ys.GetVal(H) <= 0 || 0 <= ys.GetVal(0) {
		fmt.Println("INF")
		return
	}
	sy := 0
	for ys.GetVal(sy) < 0 {
		sy++
	}
	sy--

	AreaFlag := make([][]bool, 2*N+M-1)
	for i := 0; i < 2*N+M-1; i++ {
		AreaFlag[i] = make([]bool, N+2*M-1)
	}

	stack_xy := make([][2]int, 0)
	stack_xy = append(stack_xy, [2]int{sx, sy})
	stack_n := 1
	var x, y int
	var area int = 0
	var out bool = false

	// fmt.Printf("(sx,sy)=(%d, %d)\n", sx, sy)
	// fmt.Println()
	// for i := 0; i <= W; i++ {
	// 	ind, label := xs.GetIndex(i)
	// 	fmt.Printf("(x=%d) %s[%d]: %d\n", i, label, ind, xs.GetVal(i))
	// }
	// fmt.Println()
	// for i := 0; i <= H; i++ {
	// 	ind, label := ys.GetIndex(i)
	// 	fmt.Printf("(y=%d) %s[%d]: %d\n", i, label, ind, ys.GetVal(i))
	// }
	// fmt.Println()

	for {
		if stack_n == 0 {
			break
		}

		x, y = stack_xy[stack_n-1][0], stack_xy[stack_n-1][1]
		stack_xy = stack_xy[:stack_n-1]
		stack_n--

		if AreaFlag[x][y] {
			continue
		}

		AreaFlag[x][y] = true
		w, h := xs.GetVal(x+1)-xs.GetVal(x), ys.GetVal(y+1)-ys.GetVal(y)
		area += w * h

		// fmt.Printf("(x,y)=(%d,%d)\n", x, y)

		if w > 0 {
			// up
			if y == 0 || !AreaFlag[x][y-1] {
				ind, label := ys.GetIndex(y)
				// 間隔0で固まっているのを考慮してもこの条件式で良いのか?
				if label != "C" || can_pass(T["A"][ind], T["B"][ind], xs.GetVal(x), xs.GetVal(x+1)) {
					if y == 0 {
						out = true
						break
					} else {
						stack_xy = append(stack_xy, [2]int{x, y - 1})
						stack_n++
					}
				}
			}
			// down
			if y == H-1 || !AreaFlag[x][y+1] {
				ind, label := ys.GetIndex(y + 1)
				if label != "C" || can_pass(T["A"][ind], T["B"][ind], xs.GetVal(x), xs.GetVal(x+1)) {
					if y == H-1 {
						out = true
						break
					} else {
						stack_xy = append(stack_xy, [2]int{x, y + 1})
						stack_n++
					}
				}
			}
		}

		if h > 0 {
			// left
			if x == 0 || !AreaFlag[x-1][y] {
				ind, label := xs.GetIndex(x)
				if label != "D" || can_pass(T["E"][ind], T["F"][ind], ys.GetVal(y), ys.GetVal(y+1)) {
					if x == 0 {
						out = true
						break
					} else {
						stack_xy = append(stack_xy, [2]int{x - 1, y})
						stack_n++
					}
				}
			}
			// right
			if x == W-1 || !AreaFlag[x+1][y] {
				ind, label := xs.GetIndex(x + 1)
				if label != "D" || can_pass(T["E"][ind], T["F"][ind], ys.GetVal(y), ys.GetVal(y+1)) {
					if x == W-1 {
						fmt.Println("out")
						out = true
						break
					} else {
						stack_xy = append(stack_xy, [2]int{x + 1, y})
						stack_n++
					}
				}
			}
		}
	}

	// fmt.Println()
	// for y := 0; y < H; y++ {
	// 	for x := 0; x < W; x++ {
	// 		if AreaFlag[x][y] {
	// 			a := (xs.GetVal(x+1) - xs.GetVal(x)) * (ys.GetVal(y+1) - ys.GetVal(y))
	// 			fmt.Print(a)
	// 		} else {
	// 			fmt.Print(".")
	// 		}
	// 	}
	// 	fmt.Printf(" %d\n", y%10)
	// }
	// fmt.Println()
	// for x := 0; x < W; x++ {
	// 	fmt.Print(x % 10)
	// }
	// fmt.Println()
	// fmt.Println()

	if out {
		fmt.Println("INF")
	} else {
		fmt.Println(area)
	}
}
