import collection.mutable.{ArrayBuffer, Queue}

object Main extends App {
  val sc = new FastScanner(System.in)
  val n, m = sc.nextInt()
  var xs, ys = List[Int](0)
  var lx, ly = List[(Int, Int, Int)]()
  for (i <- 1 to n) {
    val a, b, c = sc.nextInt()
    lx ::= (a,b,c)
    xs ::= a
    xs ::= b
    ys ::= c
  }
  for (i <- 1 to m) {
    val d, e, f = sc.nextInt()
    ly ::= (d,e,f)
    xs ::= d
    ys ::= e
    ys ::= f
  }

  val xsSorted = xs.distinct.sorted
  val ysSorted = ys.distinct.sorted
  val h = xsSorted.length
  val w = ysSorted.length
  val xCmp = xsSorted.zipWithIndex.toMap
  val yCmp = ysSorted.zipWithIndex.toMap
  val xWidth = xsSorted.sliding(2).map{case List(x1, x2) => x2 - x1}.toVector
  val yWidth = ysSorted.sliding(2).map{case List(y1, y2) => y2 - y1}.toVector
  val lxCmp = lx.map{case (x1,x2,y) => (xCmp(x1),xCmp(x2),yCmp(y))}
  val lyCmp = ly.map{case (x,y1,y2) => (xCmp(x),yCmp(y1),yCmp(y2))}

  val visited = ArrayBuffer.fill(2 * h - 1, 2 * w - 1)(false)
  for {
    (x1,x2,y) <- lxCmp
    x <- 2 * x1 to 2 * x2
  } {
    visited(x)(y*2) = true
  }
  for {
    (x,y1,y2) <- lyCmp
    y <- 2 * y1 to 2 * y2
  } {
    visited(x*2)(y) = true
  }
  visited(xCmp(0) * 2)(yCmp(0) * 2) = true

  var ans = 0L
  val queue = Queue((xCmp(0) * 2, yCmp(0) * 2))
  val d = List((1,0),(-1,0),(0,1),(0,-1))
  while (queue.nonEmpty) {
    val (x,y) = queue.dequeue()
    for ((dx, dy) <- d) {
      val x1 = x + dx
      val y1 = y + dy
      if (!visited(x1)(y1)) {
        if (x1 == 0 || x1 == 2 * h - 2 || y1 == 0 || y1 == 2 * w - 2) {
          ans = -1
          queue.clear()
        } else {
          queue.enqueue((x1, y1))
          visited(x1)(y1) = true
          if (x1 % 2 == 1 && y1 % 2 == 1) {
            ans += xWidth(x1 / 2) * yWidth(y1 / 2)
          }
        }
      }
    }
  }

  println(if (ans == -1) "INF" else ans)
}

class FastScanner(source: java.io.InputStream) {
  val buf = new Array[Byte](1024)
  var now, end = 0

  def isPrintable(b: Byte): Boolean = 33 <= b && b <= 126
  def isNum(b: Byte): Boolean = 48 <= b && b <= 57

  def hasNextByte(): Boolean = {
    if (now < end) {
      true
    } else {
      now = 0
      end = source.read(buf)
      end > 0
    }
  }

  def nextByte(): Byte = {
    if (hasNextByte()) {
      val b = buf(now)
      now += 1
      b
    } else {
      throw new NoSuchElementException()
    }
  }

  def hasNext(): Boolean = {
    while (hasNextByte() && !isPrintable(buf(now))) {
      now += 1
    }
    hasNextByte()
  }

  def next(): String = {
    if (hasNext()) {
      val sb = new StringBuilder()
      var b = nextByte()
      while (isPrintable(b)) {
        sb += b.toChar
        b = nextByte()
      }
      sb.toString
    } else {
      throw new NoSuchElementException()
    }
  }

  def nextInt(): Int = {
    nextLong().toInt
  }

  def nextLong(): Long = {
    if (hasNext()) {
      var b = nextByte()
      var sign = 1
      var n = 0L
      if (b == '-') {
        sign = -1
        b = nextByte()
      }
      while (isNum(b)) {
        n = n * 10 + (b - 48)
        b = nextByte()
      }
      sign * n
    } else {
      throw new NoSuchElementException()
    }
  }

  def nextDouble(): Double = next().toDouble
}
