Vika has an infinite sheet of squared paper. Initially all squares are white. She introduced a two-dimensional coordinate system on this sheet and drew n black horizontal and vertical segments parallel to the coordinate axes. All segments have width equal to 1 square, that means every segment occupy some set of neighbouring squares situated in one row or one column.Your task is to calculate the number of painted cells. If a cell was painted more than once, it should be calculated exactly once.

The first line of the input contains a single integer n (1 ≤ n ≤ 100 000) — the number of segments drawn by Vika. Each of the next n lines contains four integers x1, y1, x2 and y2 ( - 109 ≤ x1, y1, x2, y2 ≤ 109) — the coordinates of the endpoints of the segments drawn by Vika. It is guaranteed that all the segments are parallel to coordinate axes. Segments may touch, overlap and even completely coincide.

Print the number of cells painted by Vika. If a cell was painted more than once, it should be calculated exactly once in the answer.

NoteIn the first sample Vika will paint squares (0, 1), (1, 1), (2, 1), (1, 2), (1, 3), (1, 4), (0, 3) and (2, 3).

import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  var yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom += (h.y -> maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.from(y1)
        val to = yCom.to(y2)
        if (from.nonEmpty && to.nonEmpty) {
          val cy1 = from.head._2
          val cy2 = to.last._2
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Integer, Integer]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs)
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          val dy1 = yCom.get(_y1)
          val dy2 = yCom.get(_y2)
          if (cy1 != dy1) println("1", cy1, dy1)
          if (cy2 != dy2) println("2", cy2, dy2)
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          if (from.firstEntry.getKey != yCom.ceilingKey(y1)) println(from.firstEntry.getKey, yCom.ceilingKey(y1))
          if (to.lastEntry.getKey != yCom.floorKey(y2)) println(to.lastEntry.getKey, yCom.floorKey(y2))
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import scala.collection.mutable.ArrayBuffer
import scala.collection.immutable.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  class SegTree(n: Int) {

    val NEUTRAL = 0 // neutral element in respect of operation used (+)

    val t = Array.fill(4 * Integer.highestOneBit(n)) { 0 }

    def query(l: Int, r: Int, v: Int = 1, tl: Int = 0, tr: Int = n - 1): Int = {
      if (l > r) NEUTRAL
      else if (l == tl && r == tr) t(v)
      else {
        val tm = (tl + tr) >> 1
        val v2 = v << 1
        query(l, Math.min(r, tm), v2, tl, tm) +
          query(Math.max(l, tm + 1), r, v2 + 1, tm + 1, tr)
      }
    }

    def update(pos: Int, delta: Int, v: Int = 1, tl: Int = 0, tr: Int = n - 1) {
      if (tl == tr) t(v) += delta
      else {
        val tm = (tl + tr) >> 1
        val v2 = v << 1
        if (pos <= tm) update(pos, delta, v2, tl, tm)
        else update(pos, delta, v2 + 1, tm + 1, tr)
        t(v) = t(v2) + t(v2 + 1)
      }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  var yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom += (h.y -> maxY)
      maxY += 2
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val st = new SegTree(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom(y)
        st.update(cy, 1)
      case HEnd(x, y) =>
        val cy = yCom(y)
        st.update(cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.from(y1)
        val to = yCom.to(y2)
        if (from.nonEmpty && to.nonEmpty) {
          val cy1 = from.head._2
          val cy2 = to.last._2
          if (cy1 <= cy2) {
            val d = st.query(cy1, cy2)
            if (d < 0) println(d)
            area -= d
          }
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          if (from.firstEntry.getKey != yCom.ceilingKey(y1)) println(from.firstEntry.getKey, yCom.ceilingKey(y1))
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
      } else {
        if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
  }
  val hs = hBuilder.result.sortBy(_.y)

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
      } else {
        if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 10
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          val d = BIT.rangeQuery(bit, cy1, cy2)
          if (d < 0) println(d)
          area -= d
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        //val from = yCom.tailMap(y1, true)
        val _y1 = yCom.ceilingKey(y1)
        val to = yCom.headMap(y2, true)
        if (_y1 != null && !to.isEmpty) {
          val cy1 = yCom.get(_y1) //from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val _y2 = yCom.floorKey(y2)
        //val to = yCom.headMap(y2, true)
        if (!from.isEmpty && _y2 != null) {
          val cy1 = from.firstEntry.getValue
          val cy2 = yCom.get(_y2) //to.lastEntry.getValue
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
      } else {
        if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
  }
  val hs = hBuilder.result.sortBy(_.y)

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
      } else {
        if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          val d = BIT.rangeQuery(bit, cy1, cy2)
          assert(d >= 0)
          area -= d
        }
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
      } else {
        if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
  }
  val hs = hBuilder.result.sortBy(_.y)

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
      } else {
        if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        }
      } else {
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
  }
  val hs = hBuilder.result

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()
  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        }
      } else {
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val cy1 = yCom.get(_y1)
        val _y2 = yCom.floorKey(y2)
        val cy2 = yCom.get(_y2)
        area -= BIT.rangeQuery(bit, cy1, cy2)
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
      } else {
        if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
  }
  val hs = hBuilder.result

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
      } else {
        if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val cy1 = yCom.get(_y1)
        val _y2 = yCom.floorKey(y2)
        val cy2 = yCom.get(_y2)
        area -= BIT.rangeQuery(bit, cy1, cy2)
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
      } else {
        if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
  }
  val hs = hBuilder.result.sortBy(_.y)

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
      } else {
        if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val cy1 = yCom.get(_y1)
        val _y2 = yCom.floorKey(y2)
        val cy2 = yCom.get(_y2)
        area -= BIT.rangeQuery(bit, cy1, cy2)
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs)
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
          if (from.isEmpty != (_y1 == null)) println("1", from.isEmpty, y1, _y1)
          if (to.isEmpty != (_y2 == null)) println("2", to.isEmpty, y2, _y2)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          val dy1 = yCom.get(_y1)
          val dy2 = yCom.get(_y2)
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs)
  val bit = BIT(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import scala.collection._
import scala.collection.mutable.ArrayBuilder
import java.util.TreeMap

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val horBuilder0 = new ArrayBuilder.ofRef[Hor]
  val vertBuilder = new ArrayBuilder.ofRef[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vertBuilder += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      horBuilder0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs0 = horBuilder0.result.sortBy(h => (h.y, h.x1))
  val hBuilder = new ArrayBuilder.ofRef[Hor]()

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hBuilder += Hor(x1, x2, y)
  }
  val hs = hBuilder.result.sortBy(_.y)

  val vs0 = vertBuilder.result.sortBy(v => (v.x, v.y1))
  val vBuilder = new ArrayBuilder.ofRef[Vert]()

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vBuilder += Vert(x, y1, y2)
  }
  val vs = vBuilder.result

  val events = (hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs).sortBy(e => (e.x, e.priority))

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val bit = BIT(maxY + 1)

  for (event <- events) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  class SegTree(n: Int) {

    val NEUTRAL = 0 // neutral element in respect of operation used (+)

    val t = Array.fill(4 * Integer.highestOneBit(n)){ 0 }

    def query(l: Int, r: Int, v: Int = 1, tl: Int = 0, tr: Int = n - 1): Int = {
      if (l > r) NEUTRAL
      else if (l == tl && r == tr) t(v)
      else {
        val tm = (tl + tr) >> 1
        val v2 = v << 1
        query(l, Math.min(r, tm), v2, tl, tm) +
          query(Math.max(l, tm + 1), r, v2 + 1, tm + 1, tr)
      }
    }

    def update(pos: Int, delta: Int, v: Int = 1, tl: Int = 0, tr: Int = n - 1) {
      if (tl == tr) t(v) += delta
      else {
        val tm = (tl + tr) >> 1
        val v2 = v << 1
        if (pos <= tm) update(pos, delta, v2, tl, tm)
        else update(pos, delta, v2 + 1, tm + 1, tr)
        t(v) = t(v2) + t(v2 + 1)
      }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          if (y > Int.MinValue) hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          if (x > Int.MinValue) vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 1
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 2
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val st = new SegTree(maxY + 1)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        st.update(cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        st.update(cy, -1)
      case Vert(x, y1, y2) =>
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
        if (_y1 != null && _y2 != null && _y1 <= _y2) {
          val cy1 = yCom.get(_y1)
          val cy2 = yCom.get(_y2)
          val d = st.query(cy1, cy2)
          if (d < 0) println(d)
          area -= d
        }
    }
  }

  println(area)
}

import java.util.TreeMap
import scala.collection.mutable.ArrayBuffer

object D extends App {

  object BIT {

    def query(t: Array[Int], r: Int, acc: Int = 0): Int =
      if (r < 0) acc else query(t, (r & (r + 1)) - 1, acc + t(r))

    def rangeQuery(t: Array[Int], l: Int, r: Int) = query(t, r) - query(t, l - 1)

    def update(t: Array[Int], i: Int, delta: Int): Unit =
      if (i < t.length) {
        t(i) += delta
        update(t, i | (i + 1), delta)
      }

    def apply(size: Int): Array[Int] = {
      Array.fill(size) { 0 }
    }

  }

  @inline def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt) }

  trait Event {
    def x: Int
    def priority: Int
  }

  val Array(n) = readInts(1)
  final case class Hor(x1: Int, x2: Int, y: Int)
  final case class Vert(x: Int, y1: Int, y2: Int) extends Event {
    def priority = 2
  }

  final case class HStart(x: Int, y: Int) extends Event {
    def priority = 1
  }

  final case class HEnd(x: Int, y: Int) extends Event {
    def priority = 3
  }

  val hs0 = ArrayBuffer.empty[Hor]
  val vs0 = ArrayBuffer.empty[Vert]

  var area = 0L

  for (i <- 0 until n) {
    val Array(_x1, _y1, _x2, _y2) = readInts(4)
    val x1 = _x1 min _x2
    val x2 = _x1 max _x2
    val y1 = _y1 min _y2
    val y2 = _y1 max _y2
    if (x1 == x2) {
      vs0 += Vert(x1, y1, y2)
      area += (y2 - y1 + 1)
    } else {
      hs0 += Hor(x1, x2, y1)
      area += (x2 - x1 + 1)
    }
  }

  val hs = ArrayBuffer.empty[Hor]

  {
    var y = Int.MinValue
    var x1 = Int.MinValue
    var x2 = Int.MinValue
    for (h <- hs0.sortBy(h => (h.y, h.x1))) {
      if (h.y == y) {
        if (h.x1 <= x2) {
          if (h.x2 < x2) {
            area -= (h.x2 - h.x1 + 1)
          } else {
            area -= (x2 - h.x1 + 1)
            x2 = h.x2
          }
        } else {
          hs += Hor(x1, x2, y)
          x1 = h.x1
          x2 = h.x2
        }
      } else {
        if (y > Int.MinValue) hs += Hor(x1, x2, y)
        y = h.y
        x1 = h.x1
        x2 = h.x2
      }
    }
    if (y > Int.MinValue) hs += Hor(x1, x2, y)
  }

  val vs = ArrayBuffer.empty[Vert]

  {
    var x = Int.MinValue
    var y1 = Int.MinValue
    var y2 = Int.MinValue
    for (v <- vs0.sortBy(v => (v.x, v.y1))) {
      if (v.x == x) {
        if (v.y1 <= y2) {
          if (v.y2 < y2) {
            area -= (v.y2 - v.y1 + 1)
          } else {
            area -= (y2 - v.y1 + 1)
            y2 = v.y2
          }
        } else {
          vs += Vert(x, y1, y2)
          y1 = v.y1
          y2 = v.y2
        }
      } else {
        if (x > Int.MinValue) vs += Vert(x, y1, y2)
        x = v.x
        y1 = v.y1
        y2 = v.y2
      }
    }
    if (x > Int.MinValue) vs += Vert(x, y1, y2)
  }

  val yCom = new TreeMap[Int, Int]

  var prev = Int.MinValue
  var maxY = 0
  for (h <- hs.sortBy(_.y)) {
    if (h.y > prev) {
      yCom.put(h.y, maxY)
      maxY += 1
      prev = h.y
    }
  }

  val events = hs.map(h => HStart(h.x1, h.y)) ++ hs.map(h => HEnd(h.x2, h.y)) ++ vs
  val bit = BIT(maxY)

  for (event <- events.sortBy(e => (e.x, e.priority))) {
    event match {
      case HStart(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, 1)
      case HEnd(x, y) =>
        val cy = yCom.get(y)
        BIT.update(bit, cy, -1)
      case Vert(x, y1, y2) =>
        val from = yCom.tailMap(y1, true)
        val to = yCom.headMap(y2, true)
        val _y1 = yCom.ceilingKey(y1)
        val _y2 = yCom.floorKey(y2)
          if (from.isEmpty != (_y1 == null)) println("1", _y1)
          if (to.isEmpty != (_y2 == null)) println("2", _y2)
        if (!from.isEmpty && !to.isEmpty) {
          val cy1 = from.firstEntry.getValue
          val cy2 = to.lastEntry.getValue
          val dy1 = yCom.get(_y1)
          val dy2 = yCom.get(_y2)
          if (cy1 <= cy2) area -= BIT.rangeQuery(bit, cy1, cy2)
        }
    }
  }

  println(area)
}