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 = list(map(int, input().split()))

        vertical_lines.append((a, b, c))

        x_set |= {a, b}

        y_set |= {c}



    horizontal_lines = []

    for _ in range(M):

        d, e, f = list(map(int, 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)]



    grid = [[0] * (len(x_set) * 2 - 1) for _ in range(len(y_set) * 2 - 1)]

    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[c][x] = 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[y][d] = 1



    que = deque()

    used = [[0] * len(x_set) * 2 for _ in range(len(y_set) * 2)]

    dy = [1, 1, -1, -1]

    dx = [1, -1, 1, -1]

    for k in range(4):

        nny, nnx = y_encoded[0] + dy[k], x_encoded[0] + dx[k]

        if 1 <= nny < len(y_set) * 2 - 1 and 1 <= nnx < len(x_set) * 2 - 1:

            que.append((nny, nnx))

            used[nny][nnx] = 1

    ans = 0

    dy = [1, 0, -1, 0]

    dx = [0, 1, 0, -1]

    while que:

        y, x = que.popleft()

        if y % 2 and x % 2:

            ans += y_length[y] * x_length[x]

        for k in range(4):

            ny, nx = y + dy[k], x + dx[k]

            nny, nnx = ny + dy[k], nx + dx[k]

            if grid[ny][nx] == 0:

                if nny < 0 or nny >= len(y_set) * 2 - 1 or nnx < 0 or nnx >= len(x_set) * 2 - 1:

                    return 'INF'

                if not used[nny][nnx]:

                    que.append((nny, nnx))

                    used[nny][nnx] = 1

    return ans



print((f_single_dot()))
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 = list(map(int, input().split()))

        vertical_lines.append((a, b, c))

        x_set |= {a, b}

        y_set |= {c}



    horizontal_lines = []

    for _ in range(M):

        d, e, f = list(map(int, 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)]



    grid = [[0] * (len(y_set) * 2 - 1) for _ in range(len(x_set) * 2 - 1)]

    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



    que = deque()

    used = [[0] * len(y_set) * 2 for _ in range(len(x_set) * 2)]

    dy = [1, 1, -1, -1]

    dx = [1, -1, 1, -1]

    for k in range(4):

        nnx, nny = x_encoded[0] + dx[k], y_encoded[0] + dy[k]

        if 1 <= nnx < len(x_set) * 2 - 1 and 1 <= nny < len(y_set) * 2 - 1:

            que.append((nnx, nny))

            used[nnx][nny] = 1

    ans = 0

    dy = [1, 0, -1, 0]

    dx = [0, 1, 0, -1]

    while que:

        x, y = que.popleft()

        if x % 2 and y % 2:

            ans += x_length[x] * y_length[y]

        for k in range(4):

            nx, ny = x + dx[k], y + dy[k]

            nnx, nny = nx + dx[k], ny + dy[k]

            if grid[nx][ny] == 0:

                if nnx < 0 or nnx >= len(x_set) * 2 - 1 or nny < 0 or nny >= len(y_set) * 2 - 1:

                    return 'INF'

                if not used[nnx][nny]:

                    que.append((nnx, nny))

                    used[nnx][nny] = 1

    return ans



print((f_single_dot()))
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 = list(map(int, input().split()))
        vertical_lines.append((a, b, c))
        x_set |= {a, b}
        y_set |= {c}
    horizontal_lines = []
    for _ in range(M):
        d, e, f = list(map(int, 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)
    ]
    grid = [[0] * (len(x_set) * 2 - 1) for _ in range(len(y_set) * 2 - 1)]
    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[c][x] = 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[y][d] = 1
    que = deque()
    used = [[0] * len(x_set) * 2 for _ in range(len(y_set) * 2)]
    dy = [1, 1, -1, -1]
    dx = [1, -1, 1, -1]
    for k in range(4):
        nny, nnx = y_encoded[0] + dy[k], x_encoded[0] + dx[k]
        if 1 <= nny < len(y_set) * 2 - 1 and 1 <= nnx < len(x_set) * 2 - 1:
            que.append((nny, nnx))
            used[nny][nnx] = 1
    ans = 0
    dy = [1, 0, -1, 0]
    dx = [0, 1, 0, -1]
    while que:
        y, x = que.popleft()
        if y % 2 and x % 2:
            ans += y_length[y] * x_length[x]
        for k in range(4):
            ny, nx = y + dy[k], x + dx[k]
            nny, nnx = ny + dy[k], nx + dx[k]
            if grid[ny][nx] == 0:
                if (
                    nny < 0
                    or nny >= len(y_set) * 2 - 1
                    or nnx < 0
                    or nnx >= len(x_set) * 2 - 1
                ):
                    return "INF"
                if not used[nny][nnx]:
                    que.append((nny, nnx))
                    used[nny][nnx] = 1
    return ans


print((f_single_dot()))

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 = list(map(int, input().split()))
        vertical_lines.append((a, b, c))
        x_set |= {a, b}
        y_set |= {c}
    horizontal_lines = []
    for _ in range(M):
        d, e, f = list(map(int, 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)
    ]
    grid = [[0] * (len(y_set) * 2 - 1) for _ in range(len(x_set) * 2 - 1)]
    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
    que = deque()
    used = [[0] * len(y_set) * 2 for _ in range(len(x_set) * 2)]
    dy = [1, 1, -1, -1]
    dx = [1, -1, 1, -1]
    for k in range(4):
        nnx, nny = x_encoded[0] + dx[k], y_encoded[0] + dy[k]
        if 1 <= nnx < len(x_set) * 2 - 1 and 1 <= nny < len(y_set) * 2 - 1:
            que.append((nnx, nny))
            used[nnx][nny] = 1
    ans = 0
    dy = [1, 0, -1, 0]
    dx = [0, 1, 0, -1]
    while que:
        x, y = que.popleft()
        if x % 2 and y % 2:
            ans += x_length[x] * y_length[y]
        for k in range(4):
            nx, ny = x + dx[k], y + dy[k]
            nnx, nny = nx + dx[k], ny + dy[k]
            if grid[nx][ny] == 0:
                if (
                    nnx < 0
                    or nnx >= len(x_set) * 2 - 1
                    or nny < 0
                    or nny >= len(y_set) * 2 - 1
                ):
                    return "INF"
                if not used[nnx][nny]:
                    que.append((nnx, nny))
                    used[nnx][nny] = 1
    return ans


print((f_single_dot()))

-    grid = [[0] * (len(x_set) * 2 - 1) for _ in range(len(y_set) * 2 - 1)] +    grid = [[0] * (len(y_set) * 2 - 1) for _ in range(len(x_set) * 2 - 1)] -            grid[c][x] = 1 +            grid[x][c] = 1 -            grid[y][d] = 1 +            grid[d][y] = 1 -    used = [[0] * len(x_set) * 2 for _ in range(len(y_set) * 2)] +    used = [[0] * len(y_set) * 2 for _ in range(len(x_set) * 2)] -        nny, nnx = y_encoded[0] + dy[k], x_encoded[0] + dx[k] -        if 1 <= nny < len(y_set) * 2 - 1 and 1 <= nnx < len(x_set) * 2 - 1: -            que.append((nny, nnx)) -            used[nny][nnx] = 1 +        nnx, nny = x_encoded[0] + dx[k], y_encoded[0] + dy[k] +        if 1 <= nnx < len(x_set) * 2 - 1 and 1 <= nny < len(y_set) * 2 - 1: +            que.append((nnx, nny)) +            used[nnx][nny] = 1 -        y, x = que.popleft() -        if y % 2 and x % 2: -            ans += y_length[y] * x_length[x] +        x, y = que.popleft() +        if x % 2 and y % 2: +            ans += x_length[x] * y_length[y] -            ny, nx = y + dy[k], x + dx[k] -            nny, nnx = ny + dy[k], nx + dx[k] -            if grid[ny][nx] == 0: +            nx, ny = x + dx[k], y + dy[k] +            nnx, nny = nx + dx[k], ny + dy[k] +            if grid[nx][ny] == 0: -                    nny < 0 +                    nnx < 0 +                    or nnx >= len(x_set) * 2 - 1 +                    or nny < 0 -                    or nnx < 0 -                    or nnx >= len(x_set) * 2 - 1 -                if not used[nny][nnx]: -                    que.append((nny, nnx)) -                    used[nny][nnx] = 1 +                if not used[nnx][nny]: +                    que.append((nnx, nny)) +                    used[nnx][nny] = 1