//package abc168.F

import java.io.*
import java.math.*
import java.util.*
import kotlin.math.*

var reader: BufferedReader = System.`in`.bufferedReader()
var writer: PrintWriter = PrintWriter(System.`out`)

fun next() = reader.readLine()!!
fun nextInt() = next().toInt()
fun nextLong() = next().toLong()
fun nextDouble() = next().toDouble()
fun nextStrings() = next().split(" ")
fun nextInts() = nextStrings().map { it.toInt() }
fun nextLongs() = nextStrings().map { it.toLong() }
fun nextDoubles() = nextStrings().map { it.toDouble() }

fun put(v: Any?) = writer.print(v)
fun puts() = writer.println()
fun puts(v: Any?) = writer.println(v)

var debug = false
fun dp(v: Any?) {
    if (debug) println(v)
}
fun dp() {
    if (debug) println()
}

fun <T> unique(list: List<T>): MutableList<T> {
    return TreeSet<T>(list).toMutableList()
}

class UFT(
    val N: Int
) {
    val parent = Array<Int>(N) { it }
    val rank = Array<Int>(N) { 0 }

    fun root(x: Int): Int {
        if (parent[x] != x) {
            parent[x] = root(parent[x])
        }
        return parent[x]
    }
    fun same(x: Int, y: Int): Boolean {
        return root(x) == root(y)
    }
    fun unite(x: Int, y: Int) {
        val rootX = root(x)
        val rootY = root(y)
        if (rootX == rootY) {
            return
        }

        if (rank[rootX] < rank[rootY]) {
            parent[rootX] = rootY
        } else {
            parent[rootY] = rootX
            if (rank[rootX] == rank[rootY]) {
                ++rank[rootX]
            }
        }
    }
}

fun test(case: Int, input: String, expected: String) {
    reader = input.trimIndent().reader().buffered()

    val stringWriter = StringWriter()
    writer = PrintWriter(stringWriter)

    solve()
    writer.flush()

    val actual = stringWriter.toString()

    println("[test $case]")
    if ("${expected}" == actual) {
        println("OK")
    } else {
        println("NG")
        println()
        println("expected: \"${expected}\"")
        println("actual:   \"${actual}\"")
    }
    println()
}

fun main(args: Array<String>) {
    if ((args.size == 1) && (args[0] == "test")) {
        testAll()
    } else {
        solve()
        writer.flush()
    }
}

///////////////////////////////////////////////////////////

fun testAll() {
    debug = true

    test(1,
    """
    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
    """,
    "13")
    test(2,
    """
    6 1
    -3 -1 -2
    -3 -1 1
    -2 -1 2
    1 4 -2
    1 4 -1
    1 4 1
    3 1 4
    """,
    "INF")
}

fun <T> readToList(n: Int, transformer: (List<Long>) -> T): MutableList<T> {
    return mutableListOf<T>().also { list ->
        repeat(n) {
            val lines = nextLongs()
            list.add(transformer(lines))
        }
    }
}

class Indexer(
    val X: Int,
    val Y: Int
) {
    operator fun invoke(x: Int, y: Int): Int {
        return y * X + x
    }

    fun <T> contentToString(arr: Array<T>): String {
        val builder = StringBuilder()

        builder.appendln("----------")
        for (y in 0 until Y) {
            for (x in 0 until X) {
                builder.append(arr[this(x, y)])
                builder.append(", ")
            }
            builder.appendln()
        }
        builder.append("----------")

        return builder.toString()
    }
}

val TOP = 1
val BOTTOM = 2
val LEFT = 4
val RIGHT = 8

typealias Line = Pair<Long, Long>
typealias Point = Pair<Int, Int>

fun doSolve(): Long {

    val (N, M) = nextInts()

    var Xseries = mutableListOf<Long>()
    Xseries.add(0L)

    var Yseries = mutableListOf<Long>()
    Yseries.add(0L)

    var HLines = mutableListOf<Pair<Long, Line>>()
    var VLines = mutableListOf<Pair<Long, Line>>()

    repeat(N) {
        val (a, b, c) = nextLongs()
        Xseries.add(a)
        Xseries.add(b)
        Yseries.add(c)

        HLines.add(Pair(c, Line(a, b)))
    }

    repeat(M) {
        val (d, e, f) = nextLongs()
        Xseries.add(d)
        Yseries.add(e)
        Yseries.add(f)

        VLines.add(Pair(d, Line(e, f)))
    }

    Xseries = unique(Xseries)
    Yseries = unique(Yseries)

    //dp(Xseries)
    //dp(Yseries)

    val X = Xseries.size + 2
    val Y = Yseries.size + 2
    val index = Indexer(X, Y)

    val uft = UFT(X*Y)

    val Hwalls = Array<Int>(X*Y) { 0 }
    val Vwalls = Array<Int>(X*Y) { 0 }
    HLines.forEach { (c, line) ->
        val (a, b) = line

        val xIdx1 = Xseries.binarySearch(a) + 1
        val xIdx2 = Xseries.binarySearch(b) + 1
        val yIdx = Yseries.binarySearch(c) + 1

        ++Hwalls[index(xIdx1, yIdx)]
        --Hwalls[index(xIdx2, yIdx)]
    }

    VLines.forEach { (d, line) ->
        val (e, f) = line

        val xIdx = Xseries.binarySearch(d) + 1
        val yIdx1 = Yseries.binarySearch(e) + 1
        val yIdx2 = Yseries.binarySearch(f) + 1

        ++Vwalls[index(xIdx, yIdx1)]
        --Vwalls[index(xIdx, yIdx2)]
    }

    for (y in 0 until Y) {
        for (x in 0 until X) {
            if (x > 0) Hwalls[index(x, y)] += Hwalls[index(x-1, y)]
            if (y > 0) Vwalls[index(x, y)] += Vwalls[index(x, y-1)]

            //dp("[$x, $y]: ${Hwalls[index(x, y)]}, ${Vwalls[index(x, y)]}")
            if ((y > 0) && (Hwalls[index(x, y)] == 0)) {
                uft.unite(index(x, y), index(x, y-1))
            }
            if ((x > 0) && (Vwalls[index(x, y)] == 0)) {
                uft.unite(index(x, y), index(x-1, y))
            }
        }
    }

    //dp(index.contentToString(uft.parent))

    var startX = Xseries.binarySearch(0L) + 1
    var startY = Yseries.binarySearch(0L) + 1

    val origin = uft.root(index(startX, startY))
    if (origin == uft.root(index(1, 0))) {
        return -1
    }
    dp("[$startX, $startY]: origin")

    var area = 0L

    for (y in 1 until Y-2) {
        for (x in 1 until X-2) {
            if (uft.root(index(x, y)) == origin) {
                area += (Xseries[x]-Xseries[x-1]) * (Yseries[y]-Yseries[y-1])
            }
        }
    }

    return area
}

fun solve() {
    val ret = doSolve()
    if (ret >= 0) {
        put(ret)
    } else {
        put("INF")
    }
}


Measured memory_bytes: 676624