# Original solution
def f_single_dot():
    # 参考: https://atcoder.jp/contests/abc168/submissions/13368489
    import sys
    from collections import deque
    input = sys.stdin.readline
    N, M = [int(i) for i in input().split()]

    x_set, y_set = set([0]), set([0])  # 重複を除いた xy 座標の一覧 (座標圧縮に必要)

    vertical_lines = []
    for _ in range(N):
        a, b, c = [int(i) for i in input().split()]
        vertical_lines.append((a, b, c))
        x_set |= {a, b}
        y_set |= {c}

    horizontal_lines = []
    for _ in range(M):
        d, e, f = [int(i) for i in input().split()]
        horizontal_lines.append((d, e, f))
        x_set |= {d}
        y_set |= {e, f}

    x_set = sorted(x_set)
    y_set = sorted(y_set)

    # 座標圧縮 (壁も配列に格納するので、2 倍している)
    x_encoded = {n: i * 2 for i, n in enumerate(x_set)}
    y_encoded = {n: i * 2 for i, n in enumerate(y_set)}
    # 座標圧縮されたグリッドで縦横に 1 マス分進むことは実際にはどれくらい進んだことなのか
    x_length = [x_set[i // 2 + 1] - x_set[i // 2] if i %
                2 else 0 for i in range(len(x_set) * 2 - 1)]
    y_length = [y_set[i // 2 + 1] - y_set[i // 2] if i %
                2 else 0 for i in range(len(y_set) * 2 - 1)]

    # 壁を埋めていく (累積和を用いていない)
    x_size, y_size = 2 * len(x_set) - 1, 2 * len(y_set) - 1
    grid = [[0] * y_size for _ in range(x_size)]
    for a, b, c in vertical_lines:
        a, b, c = x_encoded[a], x_encoded[b], y_encoded[c]
        for x in range(a, b + 1):
            grid[x][c] = 1
    for d, e, f in horizontal_lines:
        d, e, f = x_encoded[d], y_encoded[e], y_encoded[f]
        for y in range(e, f + 1):
            grid[d][y] = 1

    queue = deque()
    is_visited = [[0] * (y_size + 1) for _ in range(x_size + 1)]

    # 一度原点から斜めに動く (壁もグリッドに入れたため、ずれが生じたことによる)
    for dx, dy in ((-1, -1), (-1, 1), (1, 1), (1, -1)):
        nx, ny = x_encoded[0] + dx, y_encoded[0] + dy
        if 0 <= nx < x_size and 0 <= ny < y_size:
            queue.append((nx, ny))
            is_visited[nx][ny] = 1

    ans = 0
    while queue:
        x, y = queue.pop()
        if (x % 2) & (y % 2):
            ans += x_length[x] * y_length[y]
        # grid を 2 マスずつ動いているのは、壁をグリッドに入れたことによる
        for dx, dy in ((-1, 0), (1, 0), (0, -1), (0, 1)):
            nx, ny = x + dx, y + dy
            nnx, nny = nx + dx, ny + dy
            if grid[nx][ny] == 0:
                if not ((0 <= nnx < x_size) and (0 <= nny < y_size)):
                    return 'INF'
                if not is_visited[nnx][nny]:
                    queue.appendleft((nnx, nny))
                    is_visited[nnx][nny] = 1
    return ans

print((f_single_dot()))

# Optimized solution
def f_single_dot():
    # 参考: https://atcoder.jp/contests/abc168/submissions/13368489
    import sys
    from collections import deque
    input = sys.stdin.readline
    N, M = [int(i) for i in input().split()]

    x_set, y_set = set([0]), set([0])  # 重複を除いた xy 座標の一覧 (座標圧縮に必要)

    vertical_lines = []
    for _ in range(N):
        a, b, c = [int(i) for i in input().split()]
        vertical_lines.append((a, b, c))
        x_set |= {a, b}
        y_set |= {c}

    horizontal_lines = []
    for _ in range(M):
        d, e, f = [int(i) for i in input().split()]
        horizontal_lines.append((d, e, f))
        x_set |= {d}
        y_set |= {e, f}

    x_set = sorted(x_set)
    y_set = sorted(y_set)

    # 座標圧縮 (壁も配列に格納するので、2 倍している)
    x_encoded = {n: i * 2 for i, n in enumerate(x_set)}
    y_encoded = {n: i * 2 for i, n in enumerate(y_set)}
    # 座標圧縮されたグリッドで縦横に 1 マス分進むことは実際にはどれくらい進んだことなのか
    x_length = [x_set[i // 2 + 1] - x_set[i // 2] if i %
                2 else 0 for i in range(len(x_set) * 2 - 1)]
    y_length = [y_set[i // 2 + 1] - y_set[i // 2] if i %
                2 else 0 for i in range(len(y_set) * 2 - 1)]

    # 壁を埋めていく (累積和を用いていない)
    x_size, y_size = 2 * len(x_set) - 1, 2 * len(y_set) - 1
    grid = [[0] * y_size for _ in range(x_size)]
    for a, b, c in vertical_lines:
        a, b, c = x_encoded[a], x_encoded[b], y_encoded[c]
        for x in range(a, b + 1):
            grid[x][c] = 1
    for d, e, f in horizontal_lines:
        d, e, f = x_encoded[d], y_encoded[e], y_encoded[f]
        for y in range(e, f + 1):
            grid[d][y] = 1

    queue = deque()
    is_visited = [[0] * (y_size + 1) for _ in range(x_size + 1)]

    # 一度原点から斜めに動く (壁もグリッドに入れたため、ずれが生じたことによる)
    for dx, dy in ((-1, -1), (-1, 1), (1, 1), (1, -1)):
        nx, ny = x_encoded[0] + dx, y_encoded[0] + dy
        if 0 <= nx < x_size and 0 <= ny < y_size:
            queue.append((nx, ny))
            is_visited[nx][ny] = 1

    diff = ((-1, 0), (1, 0), (0, -1), (0, 1))
    ans = 0
    while queue:
        x, y = queue.pop()
        if (x % 2) & (y % 2):
            ans += x_length[x] * y_length[y]
        # grid を 2 マスずつ動いているのは、壁をグリッドに入れたことによる
        for dx, dy in diff:
            nx, ny = x + dx, y + dy
            nnx, nny = nx + dx, ny + dy
            if grid[nx][ny] == 0:
                if not ((0 <= nnx < x_size) and (0 <= nny < y_size)):
                    return 'INF'
                if not is_visited[nnx][nny]:
                    queue.appendleft((nnx, nny))
                    is_visited[nnx][nny] = 1
    return ans

print((f_single_dot()))