import java.util.Scanner

import scala.collection.immutable.HashSet
import scala.io.StdIn

object CodeForces extends App {

  val arr = StdIn.readLine().split(' ').map(_.toInt)
  val n = arr(0)
  val m = arr(1)

  val graph = Array.ofDim[List[Int]](n)

  for (_ <- 1 to m){
     val arr = StdIn.readLine().split(' ').map(_.toInt)
    val x = arr(0) - 1
    val y = arr(1) - 1
    if (graph(x) == null) graph(x) = List.empty
    if (graph(y) == null) graph(y) = List.empty

    graph(x) =  y :: graph(x)
    graph(y) =  x :: graph(y)
  }

  val used = Array.ofDim[Boolean](n)
  val set1 = collection.mutable.HashSet.empty[Int]
  val set2 = collection.mutable.HashSet.empty[Int]

  def dfs(x: Int,current: Int): Unit = {
    used(x) = true
    current match {
      case 0 => set1.add(x)
      case 1 => set2.add(x)
      case _ => throw new Exception("wtf")
    }
    graph(x)
      .filter(!used(_))
      .foreach(dfs(_, (current + 1) % 2))
  }

  for(i <- 0 until n) {
    if(!used(i) && graph(i) != null) dfs(i, 0)
  }

  if(set1.intersect(set2).isEmpty) {
    println(set1.size)
    set1.foreach({el =>
      print(el + 1)
      print(" ")
    })
    println()
    println(set2.size)
    set2.foreach({el =>
      print(el + 1)
      print(" ")
    })
  } else println(-1)
}

import java.io._
import java.util.StringTokenizer

import scala.collection.mutable.ListBuffer
import scala.reflect.ClassTag

object Main {
  def main(args: Array[String]): Unit = {
    try {
      val (in, out) =
        if (isOnlineJudge) {
          (
            new FastScanner(new InputStreamReader(System.in)),
            new PrintWriter(System.out)
          )
        } else {
          (
            new FastScanner(new FileReader(new File("src/resource/problem.in"))),
            new PrintWriter(new File("src/resource/problem.out"))
          )
        }
      new C360A(in, out).solve()
      out.flush()
      out.close()
    } catch {
      case e: IOException => e.printStackTrace()
    }
  }

  private[this] val isOnlineJudge = true

  class FastScanner(val streamReader: InputStreamReader) {
    private[this] val reader = new BufferedReader(streamReader, 32768)
    private[this] var tokenizer: StringTokenizer = _

    @inline private[this] final def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())

    def nextLong(): Long = java.lang.Long.parseLong(next())

    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()

    def nl(): Long = nextLong()

    def nc(): Char = nextChar()

    def ns(): String = next()

    def ns(n: Int): Array[Char] = ns().toCharArray

    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)

    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }

    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }

    def nal(n: Int): Array[Long] = map(n)(_ => nl())

    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n)(_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while (i < N) {
      f(i);
      i += 1
    }
  }

  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while (i >= offset) {
      f(i);
      i -= 1
    }
  }

  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from)(f)
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

class C360A(fScanner: Main.FastScanner, out: java.io.PrintWriter) {

  import Main._
  import fScanner._

  def solve(): Unit = {
    val n = ni()
    val m = ni()

    g = Array.fill[ListBuffer[Int]](n)(new ListBuffer[Int])

    REP(m) { _ =>
      val u = ni()
      val v = ni()

      g(u-1) += v-1
      g(v-1) += u-1
    }

    marked = Array.fill(n)(-1)
    REP(n) { i =>
      if(marked(i) == -1) {
        marked(i) = 0
        fill(i)
      }
    }

    var yes = true
    REP(n) { i =>
      val c = marked(i)
      yes = yes & g(i).forall(p => marked(p) == (c^1))
    }
    if(!yes) {
      out.println(-1)
    } else {
      val x = marked.zipWithIndex.filter(_._1 == 0).map(_._2 + 1)
      out.println(x.length)
      out.println(x.mkString(" "))
      val y = marked.zipWithIndex.filter(_._1 == 1).map(_._2 + 1)
      out.println(y.length)
      out.println(y.mkString(" "))
    }
  }

  var g: Array[ListBuffer[Int]] = _
  var marked: Array[Int] = _

  def fill(u: Int) {
    val x = marked(u)
    g(u).foreach { f =>
      if(marked(f) == -1) {
        marked(f) = x^1
        fill(f)
      }
    }
  }
}

object A687 {
  def mark(
    edges: Array[Seq[Int]],
    color: Array[Int],
    now: Int,
    colorToAssign: Int
  ): Boolean = {
    //println(s"Coloring $now the color $colorToAssign")
    color(now) = colorToAssign

    val nextColor = 3 - colorToAssign

    edges(now).map {
      case next if (color(next) == 0) =>
        if (!mark(edges, color, next, nextColor)) return false
      case next if (color(next) != nextColor) =>
        return false
      case _ => // no op
    }

    return true
  }

  def main(args: Array[String]) = {
    val n :: m :: rest = readLine.split(' ').map { _.toInt }.toList
    val edges = Array.ofDim[Seq[Int]](n)

    (0 until n).map { case node => edges(node) = Seq[Int]()}

    (1 to m).map { case l =>
      val u :: v :: rest = readLine.split(' ').map { _.toInt}.toList
      edges(u - 1) = edges(u - 1) :+ (v - 1)
      edges(v - 1) = edges(v - 1) :+ (u - 1)
    }

    val color = Array.ofDim[Int](n)

    val result = (0 until n).map { case node =>
      if (color(node) == 0) mark(edges, color, node, 1)
    }
    .exists(_ == false)

    if (result) {
      println(-1)
    } else {
      println(color.count(_ == 1))
      println(color
        .zipWithIndex
        .filter{ case(c, n) => c == 1 }
        .map{ case(_, n) => n + 1 }
        .mkString(" "))
      println(color.count(_ == 2))
      println(color
        .zipWithIndex
        .filter{ case(c, n) => c == 2 }
        .map{ case(_, n) => n + 1}
        .mkString(" "))
    }
  }
}

object A687 {
  def mark(
    edges: Array[Seq[Int]],
    color: Array[Int],
    now: Int,
    colorToAssign: Int
  ): Boolean = {
    //println(s"Coloring $now the color $colorToAssign")
    color(now) = colorToAssign

    val nextColor = 3 - colorToAssign

    edges(now).map {
      case next if (color(next) == 0) =>
        if (!mark(edges, color, next, nextColor)) return false
      case next if (color(next) != nextColor) =>
        return false
      case _ => // no op
    }

    return true
  }

  def main(args: Array[String]) = {
    val n :: m :: rest = readLine.split(' ').map { _.toInt }.toList
    val edges = Array.ofDim[Seq[Int]](n)

    (0 until n).map { case node => edges(node) = Seq[Int]()}

    (1 to m).map { case l =>
      val u :: v :: rest = readLine.split(' ').map { _.toInt}.toList
      edges(u - 1) = edges(u - 1) :+ (v - 1)
      edges(v - 1) = edges(v - 1) :+ (u - 1)
    }

    val color = Array.ofDim[Int](n)

    val result = (0 until n).map { case node =>
      if (color(node) == 0) mark(edges, color, node, 1)
    }
    .exists(_ == false)

    if (result) {
      println(-1)
    } else {
      val (left, right) = color.zipWithIndex.partition { case (c, i) => c == 1 }
      println(left.length)
      println(left.map { case (_, i) => i + 1}.mkString(" "))
      println(right.length)
      println(right.map { case (_, i) => i + 1}.mkString(" "))
    }
  }
}

import Utils._, annotation.tailrec, collection.mutable, util._, control._, math.Ordering.Implicits._

object _688C extends CodeForcesApp {
  override def apply(io: IO) = {import io.{read, write}
    val v, e = read[Int]
    val graph = map[Int] to mutable.Set.empty[Int]
    repeat(e) {
      val u, v = read[Int]
      graph(u) += v
      graph(v) += u
    }
    val pari, arya = mutable.Set.empty[Int]

    def dfs(i: Int, fromPari: Boolean): Unit = {
      val side = if (fromPari) pari else arya
      side += i
      //debug(i, fromPari, pari, arya)
      graph(i) foreach {
        case j if pari(j) => require(!fromPari)
        case j if arya(j) => require(fromPari)
        case j => dfs(j, !fromPari)
      }
    }

    try {
      (1 to v).foreach(i => if(!pari(i) && !arya(i)) dfs(i, fromPari = true))
      write(pari.size)
        .writeLine()
        .writeAll(pari)
        .writeLine()
        .write(arya.size)
        .writeLine()
        .writeAll(arya)
    } catch {
      case _: Throwable => write(-1)
    }
  }
}
/****************************[Ignore Template Below]****************************************/
trait CodeForcesApp {
  lazy val isOnlineJudge: Boolean = sys.props.get("ONLINE_JUDGE").exists(_.toBoolean)
  def debug(x: Any): Unit = if (!isOnlineJudge) println(x)
  def apply(io: IO): io.type
  def main(args: Array[String]): Unit = this(new IO(System.in, System.out)).close()
}
object Utils {
  import scala.collection.mutable, mutable.{Map => Dict}
  implicit class GenericExtensions[A](val a: A) extends AnyVal {
    def partialMatch[B](f: PartialFunction[A, B]): Option[B] = f lift a
  }
  implicit class TraversableExtensions[A, C[X] <: Traversable[X]](val t: C[A]) extends AnyVal {
    def onlyElement: A = t.head.ensuring(t.size == 1)
    def groupByIdentifier[K](f: A => K): Map[K, A] = t.groupBy(f).mapValues(_.onlyElement)
    def duplicates(implicit b: C of A): C[A] = {
      val elems = mutable.Set.empty[A]
      (t collect {case i if !elems.add(i) => i}).to[C]
    }
    def sumWith[B](f: A => B)(implicit n: Numeric[B]): B = t.foldLeft(n.zero) {case (p, i) => n.plus(p, f(i))}
    def zipWith[B](f: A => B)(implicit b: C of (A, B)): C[(A, B)] = (t map {i => i -> f(i)}).to[C]
    def mapTo[B](f: A => B)(implicit b: C of (A, B)): Map[A, B] = zipWith(f).toUniqueMap
    def whenNonEmpty[B](f: t.type => B): Option[B] = when(t.nonEmpty)(f(t))  // e.g. grades.whenNonEmpty(_.max)
    def collectFirst[B](f: PartialFunction[A, Option[B]]): Option[B] = t.view collect f collectFirst {case Some(x) => x}
    def toMutableMultiSet: Dict[A, Int] = {
      val c = map[A] to 0
      t.foreach(i => c(i) += 1)
      c
    }
    def toMultiSet: Map[A, Int] = toMutableMultiSet.toMap withDefaultValue 0
  }
  implicit class ArrayExtensions[A <: AnyRef](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = java.util.Arrays.sort(a, from, until, cmp) //sort [from, until)
  }
  implicit class ArrayExtensions2[A](val a: Array[A]) extends AnyVal {
    def sort(from: Int, until: Int)(implicit cmp: Ordering[A]): Unit = a.view(from, until).sorted.copyToArray(a, from)
  }
  implicit class SeqExtensions[A, C[X] <: Seq[X]](val s: C[A]) extends AnyVal {
    def isRotationOf(t: Seq[A]): Boolean = s ++ s containsSlice t
  }
  implicit class PairExtensions[A, B](val p: (A, B)) extends AnyVal {
    def key = p._1
    def value = p._2
  }
  implicit class PairsExtensions[A, B, C[X] <: Traversable[X]](t: C[(A, B)]) {
    def toUniqueMap: Map[A, B] = t.groupByIdentifier(_.key).mapValues(_.value)
    def toMultiMap(implicit b: C of B): Map[A, C[B]] = t.groupBy(_.key).mapValues(_.map(_.value).to[C])
    def swap(implicit b: C of (B, A)): C[(B, A)] = t.map(_.swap).to[C]
  }
  implicit class MapExtensions[K, V, C[X, Y] <: Map[X, Y]](val m: C[K, V]) extends AnyVal {
    def lastKeyOption: Option[K] = m.lastOption.map(_.key)
    def firstKeyOption: Option[K] = m.headOption.map(_.key)
    def invert: Map[V, Set[K]] = m.toSet[(K, V)].swap.toMultiMap
    def mapKeys[K2](f: K => K2): Map[K2, V] = m map {case (k, v) => f(k) -> v}
    def toMutable: Dict[K, V] = Dict.empty[K, V] ++ m
  }
  implicit class MutableMapExtensions[K, V](val m: mutable.Map[K, V]) extends AnyVal {
    def removeLast(): Option[(K, V)] = m.lastOption.map(removeNode)
    def removeFirst(): Option[(K, V)] = m.headOption.map(removeNode)
    private def removeNode(kv: (K, V)): (K, V) = {
      m -= kv.key
      kv
    }
  }
  implicit class SetExtensions[A, C[A] <: Set[A]](val s: C[A]) extends AnyVal {
    def notContains(x: A): Boolean = !(s contains x)
    def toMutable = mutable.Set.empty[A] ++ s
  }
  implicit class IterableExtensions[A, C[A] <: Seq[A]](val s: C[A]) extends AnyVal {
    def deleteAtIndex(i: Int, howMany: Int = 1) = s.patch(i, Nil, howMany)
    def insertAtIndex(i: Int, items: Seq[A]) = s.patch(i, items, 0)
    def findWithIndex(f: A => Boolean): Option[(A, Int)] = s.zipWithIndex find {case (a, _) => f(a)}
    def foldUntil[B](z: B)(f: (B, A) => B)(c: B => Boolean): Option[(B, Int)] = s.view.scanLeft(z)(f) findWithIndex c
  }
  implicit class BooleanExtensions(val x: Boolean) extends AnyVal {
    def to[A](implicit n: Numeric[A]) = if(x) n.one else n.zero
    def toYesNo = if(x) "yes" else "no"
  }
  implicit class IntExtensions(val x: Int) extends AnyVal {
    def bitCount: Int = java.lang.Integer.bitCount(x)
  }
  implicit class LongExtensions(val x: Long) extends AnyVal {
    def bitCount: Int = java.lang.Long.bitCount(x)
  }
  implicit class NumericExtensions[A](val x: A)(implicit n: Numeric[A]) {
    import Numeric.Implicits._
    def **(i: Int): A = if (i == 0) n.one else {
      val h = x ** (i/2)
      if (i%2 == 0) h * h else h * h * x
    }
    def distance(y: A) = (x - y).abs()
    def nonNegative: Option[A] = when(n.gteq(x, n.zero))(x)
    def whenNegative(f: => A): A = nonNegative getOrElse f   //e.g. students indexOf "Greg" whenNegative Int.MaxValue
  }
  implicit class IntegralExtensions[A](val x: A)(implicit n: Integral[A]) {
    import scala.collection.immutable.NumericRange, Integral.Implicits._
    def mod(y: A): A = x - ((x / y) * y) //(x/y)*y + (x mod y) == x
    def -->(y: A): NumericRange.Inclusive[A] = NumericRange.inclusive(n.min(x, y), n.max(x, y), n.one)
    def ceilDiv(y: A): A = if (mod(y) == n.zero) x/y else n.one + (x/y)
  }
  implicit def toPoint[A](p: (A, A))(implicit n: Numeric[A]) = new java.awt.geom.Point2D.Double(n.toDouble(p._1), n.toDouble(p._2))
  def desc[A: Ordering]: Ordering[A] = asc[A].reverse  //e.g. students.sortBy(_.height)(desc)
  def asc[A](implicit order: Ordering[A]): Ordering[A] = order
  def map[K] = new {
    def to[V](default: => V): Dict[K, V] = using(_ => default)
    def using[V](f: K => V): Dict[K, V] = new mutable.HashMap[K, V]() {
      override def apply(key: K) = getOrElseUpdate(key, f(key))
    }
  }
  def newMultiMap[K, V]: mutable.MultiMap[K, V] = new mutable.HashMap[K, mutable.Set[V]] with mutable.MultiMap[K, V]
  def memoize[A, B](f: A => B): A ==> B = map[A] using f
  implicit class FuzzyDouble(val x: Double) extends AnyVal {
    def  >~(y: Double) = x > y + eps
    def >=~(y: Double) = x >= y + eps
    def  ~<(y: Double) = y >=~ x
    def ~=<(y: Double) = y >~ x
    def  ~=(y: Double) = (x distance y) <= eps
  }
  @inline def when[A](check: Boolean)(f: => A): Option[A] = if (check) Some(f) else None
  def repeat[U](n: Int)(f: => U): Unit = (1 to n).foreach(_ => f)
  type of[C[_], A] = scala.collection.generic.CanBuild[A, C[A]]
  type ==>[A, B] = collection.Map[A, B]
  val mod: Int = (1e9 + 7).toInt
  val eps: Double = 1e-9
}
/***********************************[Scala I/O]*********************************************/
import Utils._, java.io._, java.util.StringTokenizer

class IO(in: BufferedReader, out: BufferedWriter) extends Iterator[String] with AutoCloseable with Flushable {
  def this(reader: Reader, writer: Writer) = this(new BufferedReader(reader), new BufferedWriter(writer))
  def this(in: InputStream, out: OutputStream) = this(new InputStreamReader(in), new OutputStreamWriter(out))

  private[this] val tokenizers = Iterator.continually(in.readLine()).takeWhile(_ != null).map(new StringTokenizer(_)).buffered
  val printer = new PrintWriter(out, true)

  @inline private[this] def tokenizer() = {
    while(tokenizers.nonEmpty && !tokenizers.head.hasMoreTokens) tokenizers.next()
    when(tokenizers.nonEmpty)(tokenizers.head)
  }

  def read[A](implicit read: IO.Read[A]): A = read.apply(this)
  def read[C[_], A: IO.Read](n: Int)(implicit b: C of A): C[A] = Iterator.fill(n)(read).to[C]

  def readTill(delim: String): String = tokenizer().get.nextToken(delim)
  def readTillEndOfLine(): String = readTill("\n\r")

  override def next() = tokenizer().get.nextToken()
  override def hasNext = tokenizer().nonEmpty

  def write(obj: Any, more: Any*): this.type = {
    printer.print(obj)
    more foreach {i =>
      printer.print(' ')
      printer.print(i)
    }
    this
  }
  def writeLine(obj: Any*): this.type = {
    if (obj.isEmpty) printer.println() else obj foreach printer.println
    this
  }
  def writeAll(obj: Traversable[Any], separator: String = " "): this.type = write(obj mkString separator)

  override def flush() = printer.flush()
  def close() = {
    flush()
    in.close()
    printer.close()
  }
}
object IO {
  class Read[A](val apply: IO => A) {
    def map[B](f: A => B): Read[B] = new Read(apply andThen f)
  }
  object Read {
    implicit def collection[C[_], A: Read](implicit b: C of A): Read[C[A]]         = new Read(r => r.read[C, A](r.read[Int]))
    implicit val string                                       : Read[String]       = new Read(_.next())
    implicit val char                                         : Read[Char]         = string.map(_.toTraversable.onlyElement)
    implicit val int                                          : Read[Int]          = string.map(_.toInt)
    implicit val long                                         : Read[Long]         = string.map(_.toLong)
    implicit val bigInt                                       : Read[BigInt]       = string.map(BigInt(_))
    implicit val double                                       : Read[Double]       = string.map(_.toDouble)
    implicit val bigDecimal                                   : Read[BigDecimal]   = string.map(BigDecimal(_))
    implicit def tuple2[A: Read, B: Read]                     : Read[(A, B)]       = new Read(r => (r.read[A], r.read[B]))
    implicit def tuple3[A: Read, B: Read, C: Read]            : Read[(A, B, C)]    = new Read(r => (r.read[A], r.read[B], r.read[C]))
    implicit def tuple4[A: Read, B: Read, C: Read, D: Read]   : Read[(A, B, C, D)] = new Read(r => (r.read[A], r.read[B], r.read[C], r.read[D]))
    implicit val boolean                                      : Read[Boolean]      = string map {s =>
      s.toLowerCase match {
        case "yes" | "true" | "1" => true
        case "no" | "false" | "0" => false
        case _ => s.toBoolean
      }
    }
  }
}

import scala.collection.mutable

object problem_C{
  class Graph[T] {
    type Vertex = T
    type GraphMap = Map[Vertex, Set[Vertex]]
    var g:GraphMap = Map()

    def DFS: Option[mutable.Map[Vertex, Int]] = {

      val colors = mutable.Map[Vertex, Int]()
      def nextColor(color: Int) = if (color == 1) 2 else 1
      def dfs(color: Int, v: Vertex): Boolean = {
        if (colors.get(v).isDefined) {
          colors(v) == color
        }
        else {
          colors += (v -> color)
          g(v).forall(dfs(nextColor(color),_))
        }
      }

      if (g.keys.forall(v => if (colors.get(v).isEmpty) dfs(1,v) else true))
        Some(colors)
      else
        None
    }

    def toCF(ans: Option[mutable.Map[Int, Int]]) = ans match {
      case None => "-1"
      case Some(map) =>
        val (list1t, list2t) = map.toList.partition(_._2 == 1)
        val list1 = list1t.map(_._1)
        val list2 = list2t.map(_._1)

        val str = new StringBuffer("")

        str.append(list1.length).append("\n")
        list1.foreach(str.append(_).append(" "))
        str.append("\n").append(list2.length).append("\n")
        list2.foreach(str.append(_).append(" "))

        str.toString
    }

  }

  def main(args: Array[String]) = {

    val scanner = new java.util.Scanner(System.in)
    val n = scanner.nextInt()
    val m = scanner.nextInt()

    val edge = new Array[(Int,Int)](m)

    0 to m-1 foreach {edge(_) = (scanner.nextInt, scanner.nextInt)}

    val intGraph = new Graph[Int]

    val adjacencyList =
      (edge ++ edge.map { case (a, b) => (b, a) })
      .groupBy[Int] {_._1}
      .map(x => x match {case (k,seq) => (k, seq.map(_._2).toSet)})

    val isolatedPoints = (1 until n+1).filter(adjacencyList.get(_).isEmpty).map((_, Set[Int]()))

    intGraph.g = adjacencyList ++ isolatedPoints

    //scary
    println(intGraph.toCF(intGraph.DFS))

  }

}

import scala.collection.mutable

object problem_C_2{
  class Graph {
    var g: Array[mutable.Set[Int]] = Array()

    def DFS: Option[mutable.Map[Int, Int]] = {

      val colors = mutable.Map[Int, Int]()
      def nextColor(color: Int) = if (color == 1) 2 else 1
      def dfs(color: Int, v: Int): Boolean = {
        if (colors.get(v).isDefined) {
          colors(v) == color
        }
        else {
          colors += (v -> color)
          g(v).forall(dfs(nextColor(color),_))
        }
      }

      if ((1 to g.length - 1) forall { i => if (colors.get(i).isEmpty) dfs(1,i) else true }) {
        Some(colors)
      }
      else{
        None
      }

    }

    def toCF(ans: Option[mutable.Map[Int, Int]]) = ans match {
      case None => "-1"
      case Some(map) =>

        //if (g.length > 50000) println("i'm here1")

        val (list1t, list2t) = map.toList.partition(_._2 == 1)
        val list1 = list1t.map(_._1)
        val list2 = list2t.map(_._1)

        val str = new StringBuffer("")

        //if (g.length > 50000) println("i'm here2")

        str.append(list1.length).append("\n")
        list1.foreach(str.append(_).append(" "))
        str.append("\n").append(list2.length).append("\n")
        list2.foreach(str.append(_).append(" "))

        //if (g.length > 50000) println("i'm here3")

        str.toString
    }

  }

  def main(args: Array[String]) = {

    val scanner = new java.util.Scanner(System.in)
    val n = scanner.nextInt()
    val m = scanner.nextInt()

    val adjacencyList = Array.fill[mutable.Set[Int]](n + 1)(mutable.Set())
    0 to m-1 foreach {t =>
      val i = scanner.nextInt; val j = scanner.nextInt
      adjacencyList(i).add(j)
      adjacencyList(j).add(i)
    }

    val graph = new Graph
    graph.g = adjacencyList

    println(graph.toCF(graph.DFS))

  }

}

import scala.collection.mutable.ArrayBuffer

//https://codeforces.com/problemset/problem/687/A
object NPHardProblem {
  def main(args: Array[String]): Unit = {
    val in =scala.io.StdIn
    val arr=in.readLine().split(" ").map(_.toInt)
    val n=arr(0)
    val m=arr(1)
    val graph=Array.fill[ArrayBuffer[Int]](n)(new ArrayBuffer[Int]())
    for(i<- 0 until m){
      val edges=in.readLine().split(" ").map(_.toInt-1)
      graph(edges(0))+=(edges(1))
      graph(edges(1))+=(edges(0))
    }
    isBipartiteGraph(graph,n)
  }
  def isBipartiteGraph(graph: Array[ArrayBuffer[Int]],n:Int): Unit = {

    //The idea is to color the graph vertices in two color and two adjacent vertex can't have same color
    //Using DFS we will color the graph; if a vertex is having no color (0) then make it 1 and processed further
    //If we come across a vertex with ambiguity then we can say Bi-Partition is not possible
    val color = Array.fill[Int](n)(0)
    for (i <- 0 until n) {
      if (color(i) == 0) {
        color(i) = 1
      }
      if (!dfsToColorGraph(graph, i, color)) {
        println("-1")
        return
      }
    }

    var set1Count=0
    var set2Count=0
    var set1=ArrayBuffer[Int]()
    var set2=ArrayBuffer[Int]()
    for(i<- 0 until graph.length){
      if(color(i)==1){
        set1+=(i+1)
        set1Count+=1
      }else if(color(i)==2){
        set2+=(i+1)
        set2Count+=1
      }
    }
    println(set2Count)
    println(set2.mkString(" "))
    println(set1Count)
    println(set1.mkString(" "))
  }

  def dfsToColorGraph(graph: Array[ArrayBuffer[Int]], u: Int, color: Array[Int]): Boolean = {

    for (v <- 0 until graph(u).length) {
      if (color(graph(u)(v)) == 0) {
        color(graph(u)(v)) = (if (color(u) == 1) 2 else 1)
        if (!dfsToColorGraph(graph, graph(u)(v), color)) {
          return false
        }
      } else {
        if (color(u) == color(graph(u)(v))) {
          return false
        }
      }
    }

    return true
  }
}

import scala.collection.mutable.ArrayBuffer

object NPHardProblem {
  def main(args: Array[String]): Unit = {
    val in =scala.io.StdIn
    val arr=in.readLine().split(" ").map(_.toInt)
    val n=arr(0)
    val m=arr(1)
    val graph=Array.fill[ArrayBuffer[Int]](n)(new ArrayBuffer[Int]())
    for(i<- 0 until m){
      val edges=in.readLine().split(" ").map(_.toInt-1)
      graph(edges(0))+=(edges(1))
      graph(edges(1))+=(edges(0))
    }
    isBipartiteGraph(graph,n)
  }
  def isBipartiteGraph(graph: Array[ArrayBuffer[Int]],n:Int): Unit = {

    //The idea is to color the graph vertices in two color and two adjacent vertex can't have same color
    //Using DFS we will color the graph; if a vertex is having no color (0) then make it 1 and processed further
    //If we come across a vertex with ambiguity then we can say Bi-Partition is not possible
    val color = Array.fill[Int](n)(0)
    for (i <- 0 until n) {
      if (color(i) == 0) {
        color(i) = 1
      }
      if (!dfsToColorGraph(graph, i, color)) {
        println("-1")
        return
      }
    }

    var set1Count=0
    var set2Count=0
    var set1=ArrayBuffer[Int]()
    var set2=ArrayBuffer[Int]()
    for(i<- 0 until graph.length){
      if(color(i)==1){
        set1+=(i+1)
        set1Count+=1
      }else if(color(i)==2){
        set2+=(i+1)
        set2Count+=1
      }
    }
    println(set2Count)
    println(set2.mkString(" "))
    println(set1Count)
    println(set1.mkString(" "))
  }

  def dfsToColorGraph(graph: Array[ArrayBuffer[Int]], u: Int, color: Array[Int]): Boolean = {

    for (v <- 0 until graph(u).length) {
      if (color(graph(u)(v)) == 0) {
        color(graph(u)(v)) = (if (color(u) == 1) 2 else 1)
        if (!dfsToColorGraph(graph, graph(u)(v), color)) {
          return false
        }
      } else {
        if (color(u) == color(graph(u)(v))) {
          return false
        }
      }
    }

    return true
  }
}

object Solution extends App {
  val in = io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val graph = Array.fill(n){List.empty[Int]}
  val taken = Array.ofDim[Int](n)
  (1 to m).foreach { _ =>
    val Array(from, to) = in.next().split(' ').map(_.toInt - 1)
    graph(from) ::= to
    graph(to) ::= from
  }
  var stop = false
  val isGood = graph.indices.foldLeft(true){
    case (false, _) => false
    case (true, i) =>
      if (taken(i) == 0) {
        taken(i) = 1
        var expand = graph(i)
        var shouldBe = 2
        var good = true
        while (expand.nonEmpty) {
          if (expand.exists(j => taken(j) != 0 && taken(j) != shouldBe)) {
            expand = Nil
            good = false
          } else {
            expand = expand.filter(j => taken(j) == 0)
            expand.foreach(j => taken(j) = shouldBe)
            shouldBe = if (shouldBe == 1) 2 else 1
            expand = expand.flatMap(graph)
          }
        }
        good
      }
      else true
  }
  if (isGood) {
    val first = taken.indices.filter(i => taken(i) == 1)
    val second = taken.indices.filter(i => taken(i) == 2)
    println(first.size)
    println(first.map(i => i + 1).mkString(" "))
    println(second.size)
    println(second.map(i => i + 1).mkString(" "))
  } else {
    println(-1)
  }
}

object problem_C{
  def main(args: Array[String]) {
    val scanner = new java.util.Scanner(System.in)
    val n = scanner.nextInt()
    val m = scanner.nextInt()

    val colors: Array[Int] = new Array[Int](n + 1)
    val set = Array.fill[collection.mutable.Set[Int]](n + 1)(collection.mutable.Set())

    1 to m foreach {i =>
      val i = scanner.nextInt; val j = scanner.nextInt
      set(i).add(j)
      set(j).add(i)
    }

    var color = 1
    def dfs(v: Int): Boolean ={
      if (colors(v) != 0) {
        //println("vert" + v + " (" + colors(v) + "," + color +")")
        colors(v) == color
      }
      else {
        colors(v) = color
        color = if (color == 1) 2 else 1
        set(v).forall(dfs)
      }
    }

    def kek(): Boolean = {
      for(i <- 1 to n){
        if(colors(i) == 0)
          if(!dfs(i)) return  false
      }

      true
    }

    if (!kek()) println(-1)
    else {
      val t1 = colors.count(x => x == 1)
      println(t1)
      for(i <- 1 to n){
        if(colors(i) == 1) print(i + " ")
      }
      println()
      val t2 = colors.count(x => x == 2)
      println(t2)
      for(i <- 1 to n){
        if(colors(i) == 2) print(i + " ")
      }
    }

   // println(colors)
  }
}

import scala.collection.mutable

object problem_C_2{
  class Graph {
    var g: Array[mutable.Set[Int]] = Array()

    def DFS: Option[mutable.Map[Int, Int]] = {

      val colors = mutable.Map[Int, Int]()
      def nextColor(color: Int) = if (color == 1) 2 else 1
      def dfs(color: Int, v: Int): Boolean = {
        if (colors.get(v).isDefined) {
          colors(v) == color
        }
        else {
          colors += (v -> color)
          g(v).forall(dfs(nextColor(color),_))
        }
      }

      if ((1 to g.length - 1) forall { i => if (colors.get(i).isEmpty) dfs(1,i) else true }) {
        Some(colors)
      }
      else{
        None
      }

    }

    def toCF(ans: Option[mutable.Map[Int, Int]]) = ans match {
      case None => "-1"
      case Some(map) =>

        if (g.length > 50000) println("i'm here1")

        val (list1t, list2t) = map.toList.partition(_._2 == 1)
        val list1 = list1t.map(_._1)
        val list2 = list2t.map(_._1)

        val str = new StringBuffer("")

        if (g.length > 50000) println("i'm here2")

        str.append(list1.length).append("\n")
        list1.foreach(str.append(_).append(" "))
        str.append("\n").append(list2.length).append("\n")
        list2.foreach(str.append(_).append(" "))

        if (g.length > 50000) println("i'm here3")

        str.toString
    }

  }

  def main(args: Array[String]) = {

    val scanner = new java.util.Scanner(System.in)
    val n = scanner.nextInt()
    val m = scanner.nextInt()

    val adjacencyList = Array.fill[mutable.Set[Int]](n + 1)(mutable.Set())
    0 to m-1 foreach {t =>
      val i = scanner.nextInt; val j = scanner.nextInt
      adjacencyList(i).add(j)
      adjacencyList(j).add(i)
    }

    val graph = new Graph
    graph.g = adjacencyList

    println(graph.toCF(graph.DFS))

  }

}

import scala.collection.mutable.ArrayBuffer

object NPHardProblem {
  def main(args: Array[String]): Unit = {
    val in =scala.io.StdIn
    val arr=in.readLine().split(" ").map(_.toInt)
    val n=arr(0)
    val m=arr(1)
    val graph=Array.fill[Int](n,n)(0)
    for(i<- 0 until m){
      val edges=in.readLine().split(" ").map(_.toInt-1)
      graph(edges(0))(edges(1))=1
    }
    isBipartiteGraph(graph)
  }
  def isBipartiteGraph(graph: Array[Array[Int]]): Unit = {

    //The idea is to color the graph vertices in two color and two adjacent vertex can't have same color
    //Using DFS we will color the graph; if a vertex is having no color (0) then make it 1 and processed further
    //If we come across a vertex with ambiguity then we can say Bi-Partition is not possible
    val color = Array.fill[Int](graph.length)(0)
    for (i <- 0 until graph.length) {
      if (color(i) == 0) {
        color(i) = 1
      }
      if (!dfsToColorGraph(graph, i, color)) {
        println("-1")
        return
      }
    }

    var set1Count=0
    var set2Count=0
    var set1=ArrayBuffer[Int]()
    var set2=ArrayBuffer[Int]()
    for(i<- 0 until graph.length){
      if(color(i)==1){
        set1+=(i+1)
        set1Count+=1
      }else if(color(i)==2){
        set2+=(i+1)
        set2Count+=1
      }
    }
    println(set2Count)
    println(set2.mkString(" "))
    println(set1Count)
    println(set1.mkString(" "))
  }

  def dfsToColorGraph(graph: Array[Array[Int]], n: Int, color: Array[Int]): Boolean = {

    for (i <- 0 until graph.length if (graph(n)(i) == 1)) {
      if (color(i) == 0) {
        color(i) = (if (color(n) == 1) 2 else 1)
        if (!dfsToColorGraph(graph, i, color)) {
          return false
        }
      } else {
        if (color(n) == color(i)) {
          return false
        }
      }
    }

    return true
  }
}

import scala.collection.mutable.ArrayBuffer

object NPHardProblem {
  def main(args: Array[String]): Unit = {
    val in =scala.io.StdIn
    val arr=in.readLine().split(" ").map(_.toInt)
    val n=arr(0)
    val m=arr(1)
    val graph=Array.fill[Int](n,n)(0)
    for(i<- 0 until m){
      val edges=in.readLine().split(" ").map(_.toInt-1)
      graph(edges(0))(edges(1))=1
      graph(edges(1))(edges(0))=1
    }
    isBipartiteGraph(graph)
  }
  def isBipartiteGraph(graph: Array[Array[Int]]): Unit = {

    //The idea is to color the graph vertices in two color and two adjacent vertex can't have same color
    //Using DFS we will color the graph; if a vertex is having no color (0) then make it 1 and processed further
    //If we come across a vertex with ambiguity then we can say Bi-Partition is not possible
    val color = Array.fill[Int](graph.length)(0)
    for (i <- 0 until 2) {
      if (color(i) == 0) {
        color(i) = 1
      }
      if (!dfsToColorGraph(graph, i, color)) {
        println("-1")
        println(color.mkString(", "))
        return
      }
    }

    var set1Count=0
    var set2Count=0
    var set1=ArrayBuffer[Int]()
    var set2=ArrayBuffer[Int]()
    for(i<- 0 until graph.length){
      if(color(i)==1){
        set1+=(i+1)
        set1Count+=1
      }else if(color(i)==2){
        set2+=(i+1)
        set2Count+=1
      }
    }
    println(set2Count)
    println(set2.mkString(" "))
    println(set1Count)
    println(set1.mkString(" "))
  }

  def dfsToColorGraph(graph: Array[Array[Int]], n: Int, color: Array[Int]): Boolean = {

    for (i <- 0 until graph.length if (graph(n)(i) == 1)) {
      if (color(i) == 0) {
        color(i) = (if (color(n) == 1) 2 else 1)
        if (!dfsToColorGraph(graph, i, color)) {
          return false
        }
      } else {
        if (color(n) == color(i)) {
          return false
        }
      }
    }

    return true
  }
}

import scala.collection.mutable.ArrayBuffer

object NPHardProblem {
  def main(args: Array[String]): Unit = {
    val in =scala.io.StdIn
    val arr=in.readLine().split(" ").map(_.toInt)
    val n=arr(0)
    val m=arr(1)
    val graph=Array.fill[Int](n,n)(0)
    for(i<- 0 until m){
      val edges=in.readLine().split(" ").map(_.toInt-1)
      graph(edges(0))(edges(1))=1
    }
    isBipartiteGraph(graph)
  }
  def isBipartiteGraph(graph: Array[Array[Int]]): Unit = {

    //The idea is to color the graph vertices in two color and two adjacent vertex can't have same color
    //Using DFS we will color the graph; if a vertex is having no color (0) then make it 1 and processed further
    //If we come across a vertex with ambiguity then we can say Bi-Partition is not possible
    val color = Array.fill[Int](graph.length)(0)
    for (i <- 0 until 2) {
      if (color(i) == 0) {
        color(i) = 1
      }
      if (!dfsToColorGraph(graph, i, color)) {
        println("-1")
        return
      }
    }

    var set1Count=0
    var set2Count=0
    var set1=ArrayBuffer[Int]()
    var set2=ArrayBuffer[Int]()
    for(i<- 0 until graph.length){
      if(color(i)==1){
        set1+=(i+1)
        set1Count+=1
      }else if(color(i)==2){
        set2+=(i+1)
        set2Count+=1
      }
    }
    println(set2Count)
    println(set2.mkString(" "))
    println(set1Count)
    println(set1.mkString(" "))
  }

  def dfsToColorGraph(graph: Array[Array[Int]], n: Int, color: Array[Int]): Boolean = {

    for (i <- 0 until graph.length if (graph(n)(i) == 1)) {
      if (color(i) == 0) {
        color(i) = (if (color(n) == 1) 2 else 1)
        if (!dfsToColorGraph(graph, i, color)) {
          return false
        }
      } else {
        if (color(n) == color(i)) {
          return false
        }
      }
    }

    return true
  }
}

import scala.collection.mutable.ArrayBuffer

//https://codeforces.com/problemset/problem/687/A
object NPHardProblem {
  def main(args: Array[String]): Unit = {
    val in =scala.io.StdIn
    val arr=in.readLine().split(" ").map(_.toInt)
    val n=arr(0)
    val m=arr(1)
    val graph=Array.fill[ArrayBuffer[Int]](n)(new ArrayBuffer[Int]())
    for(i<- 0 until m){
      val edges=in.readLine().split(" ").map(_.toInt-1)
      graph(edges(0))+=(edges(1))
      graph(edges(1))+=(edges(0))
    }
    isBipartiteGraph(graph,n)
  }
  def isBipartiteGraph(graph: Array[ArrayBuffer[Int]],n:Int): Unit = {

    //The idea is to color the graph vertices in two color and two adjacent vertex can't have same color
    //Using DFS we will color the graph; if a vertex is having no color (0) then make it 1 and processed further
    //If we come across a vertex with ambiguity then we can say Bi-Partition is not possible
    val color = Array.fill[Int](n)(0)
    for (i <- 0 until 2) {
      if (color(i) == 0) {
        color(i) = 1
      }
      if (!dfsToColorGraph(graph, i, color)) {
        println("-1")
        return
      }
    }

    var set1Count=0
    var set2Count=0
    var set1=ArrayBuffer[Int]()
    var set2=ArrayBuffer[Int]()
    for(i<- 0 until graph.length){
      if(color(i)==1){
        set1+=(i+1)
        set1Count+=1
      }else if(color(i)==2){
        set2+=(i+1)
        set2Count+=1
      }
    }
    println(set2Count)
    println(set2.mkString(" "))
    println(set1Count)
    println(set1.mkString(" "))
  }

  def dfsToColorGraph(graph: Array[ArrayBuffer[Int]], u: Int, color: Array[Int]): Boolean = {

    for (v <- 0 until graph(u).length) {
      if (color(graph(u)(v)) == 0) {
        color(graph(u)(v)) = (if (color(u) == 1) 2 else 1)
        if (!dfsToColorGraph(graph, graph(u)(v), color)) {
          return false
        }
      } else {
        if (color(u) == color(graph(u)(v))) {
          return false
        }
      }
    }

    return true
  }
}

import java.io._
import java.util.StringTokenizer

import scala.collection.mutable.ListBuffer
import scala.reflect.ClassTag

object Main {
  def main(args: Array[String]): Unit = {
    try {
      val (in, out) =
        if (isOnlineJudge) {
          (
            new FastScanner(new InputStreamReader(System.in)),
            new PrintWriter(System.out)
          )
        } else {
          (
            new FastScanner(new FileReader(new File("src/resource/problem.in"))),
            new PrintWriter(new File("src/resource/problem.out"))
          )
        }
      new C360A(in, out).solve()
      out.flush()
      out.close()
    } catch {
      case e: IOException => e.printStackTrace()
    }
  }

  private[this] val isOnlineJudge = true

  class FastScanner(val streamReader: InputStreamReader) {
    private[this] val reader = new BufferedReader(streamReader, 32768)
    private[this] var tokenizer: StringTokenizer = _

    @inline private[this] final def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = Integer.parseInt(next())

    def nextLong(): Long = java.lang.Long.parseLong(next())

    def nextChar(): Char = next().charAt(0)

    def ni(): Int = nextInt()

    def nl(): Long = nextLong()

    def nc(): Char = nextChar()

    def ns(): String = next()

    def ns(n: Int): Array[Char] = ns().toCharArray

    def na(n: Int, offset: Int = 0): Array[Int] = map(n)(_ => ni() + offset)

    def na2(n: Int, offset: Int = 0): (Array[Int], Array[Int]) = {
      val A1, A2 = Array.ofDim[Int](n)
      REP(n) { i =>
        A1(i) = ni() + offset
        A2(i) = ni() + offset
      }
      (A1, A2)
    }

    def nm(n: Int, m: Int): Array[Array[Int]] = {
      val A = Array.ofDim[Int](n, m)
      REP(n) { i =>
        REP(m) { j =>
          A(i)(j) = ni()
        }
      }
      A
    }

    def nal(n: Int): Array[Long] = map(n)(_ => nl())

    def nm_c(n: Int, m: Int): Array[Array[Char]] = map(n)(_ => ns(m))
  }

  def REP(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = offset
    val N = n + offset
    while (i < N) {
      f(i);
      i += 1
    }
  }

  def REP_r(n: Int, offset: Int = 0)(f: Int => Unit): Unit = {
    var i = n - 1 + offset
    while (i >= offset) {
      f(i);
      i -= 1
    }
  }

  def TO(from: Int, to: Int)(f: Int => Unit): Unit = {
    REP(to - from + 1, from)(f)
  }

  def map[@specialized A: ClassTag](n: Int, offset: Int = 0)(f: Int => A): Array[A] = {
    val res = Array.ofDim[A](n)
    REP(n)(i => res(i) = f(i + offset))
    res
  }

  def sumL(as: Array[Int]): Long = {
    var s = 0L
    REP(as.length)(i => s += as(i))
    s
  }

  def cumSum(as: Array[Int]): Array[Long] = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

class C360A(fScanner: Main.FastScanner, out: java.io.PrintWriter) {

  import Main._
  import fScanner._

  def solve(): Unit = {
    val n = ni()
    val m = ni()

    g = Array.fill[ListBuffer[Int]](n)(new ListBuffer[Int])

    REP(m) { _ =>
      val u = ni()
      val v = ni()

      g(u-1) += v-1
      g(v-1) += u-1
    }

    marked = Array.fill(n)(-1)
    REP(n) { i =>
      if(marked(i) == -1) {
        marked(i) = 0
        fill(i)
      }
    }

    var yes = true
    REP(n) { i =>
      val c = marked(i)
      yes = g(i).forall(p => marked(p) == (c^1))
    }
    if(!yes) {
      out.println(-1)
    } else {
      val x = marked.zipWithIndex.filter(_._1 == 0).map(_._2 + 1)
      out.println(x.length)
      out.println(x.mkString(" "))
      val y = marked.zipWithIndex.filter(_._1 == 1).map(_._2 + 1)
      out.println(y.length)
      out.println(y.mkString(" "))
    }
  }

  var g: Array[ListBuffer[Int]] = _
  var marked: Array[Int] = _

  def fill(u: Int) {
    val x = marked(u)
    g(u).foreach { f =>
      if(marked(f) == -1) {
        marked(f) = x^1
        fill(f)
      }
    }
  }
}

object A687 {
  def mark(
    edges: Array[Seq[Int]],
    color: Array[Int],
    now: Int,
    colorToAssign: Int
  ): Boolean = {
    //println(s"Coloring $now the color $colorToAssign")
    color(now) = colorToAssign

    val nextColor = 3 - colorToAssign

    edges(now).map {
      case next if (color(next) == 0) =>
        if (!mark(edges, color, next, nextColor)) return false
      case next if (color(next) != nextColor) =>
        return false
      case _ => // no op
    }

    return true
  }

  def main(args: Array[String]) = {
    val n :: m :: rest = readLine.split(' ').map { _.toInt }.toList
    val edges = Array.ofDim[Seq[Int]](n)

    (0 until n).map { case node => edges(node) = Seq[Int]()}

    (1 to m).map { case l =>
      val u :: v :: rest = readLine.split(' ').map { _.toInt}.toList
      edges(u - 1) = edges(u - 1) :+ (v - 1)
      edges(v - 1) = edges(v - 1) :+ (u - 1)
    }

    val color = Array.ofDim[Int](n)

    val result = (0 until n).map { case node =>
      if (color(node) == 0) mark(edges, color, node, 1)
    }
    .exists(_ == false)

    if (result) {
      println(-1)
    } else {
      println(color.count(_ == 1))
      println(color.filter(_ == 1).mkString(" "))
      println(color.count(_ == 2))
      println(color.filter(_ == 2).mkString(" "))
    }
  }
}


import java.util.Scanner
import java.io._

object A {
    def main(args: Array[String]) {
      val sc: Scanner = new Scanner(new File("input.txt"))
      val n: Int = sc.nextInt()
      val m: Int = sc.nextInt()
      var b: Boolean = true
      if (n<m)b=false
      var np: Int = 0
      var mp: Int = 0
      var s:String = ""
      for (i <- 0 until n+m) {
        if (i % 2 == 0 && b && np < n) {s=s+"B";np=np+1}
        else if (i % 2 == 0 && mp < m) {s=s+"G";mp=mp+1}
        else if (i % 2 !=0 && b && mp < m) {s=s+"G";mp=mp+1}
        else if (np < n ) {s=s+"B";np=np+1}
        else if (mp < m ) {s=s+"G";mp=mp+1}
      }
      val bw: BufferedWriter = new BufferedWriter(new FileWriter("output.txt"))
      bw.write(s)
      bw.close()
    }
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter("output.txt")
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		out.println("GB"*m+"G"*(n-m))
	else
        out.println("BG"*n+"B"*(m-n))
    out.close
}

import scala.io.Source
import java.io.PrintWriter
import java.io.File

object BoysGirls extends App {
    val it = Source.fromFile("input.txt").getLines
    val writer = new PrintWriter(new File("output.txt" ))
    val ss = it.next.split(" ")
    val iss = ss.map(_.toInt)
    val nb = iss(0)
    val ng = iss(1)

    def printc(s:String, n:Int) =
      for (i <- 0 until n) {
        writer.print(s)

      }

    // println("nb,ng = " + nb + " " + ng)
    if (nb == ng) printc("GB", ng)
	else if (nb > ng) {
		printc( "BG", ng);
		printc( "B", (nb-ng))
	} else {
		printc( "GB", nb)
		printc( "G", (ng-nb) )
	}
    writer.close()
}

import scala.io.Source

object Solution extends App {
  val in = Source.fromFile("input.txt").getLines()
  val Array(b, g) = in.next().split(' ').map(_.toInt)
  val p = new java.io.PrintWriter("output.txt")
  if (b > g)
    p.println("BG" * Math.min(b, g) + "B" * (b - g))
  else
    p.println("GB" * Math.min(b, g) + "G" * (g - b))
  p.close()
}

import java.util.Scanner
import java.io._

object A {
    def main(args: Array[String]) {
      val sc: Scanner = new Scanner(new File("input.txt"))
      val n: Int = sc.nextInt()
      val m: Int = sc.nextInt()
      var b: Boolean = true
      if (n<m)b=false
      var np: Int = 0
      var mp: Int = 0
      var s:String = ""
      for (i <- 0 until n+m) {
        if (i % 2 == 0 && b && np < n) {s+"B";np=np+1}
        else if (i % 2 == 0 && mp < m) {s+"G";mp=mp+1}
        else if (i % 2 !=0 && b && mp < m) {s+"G";mp=mp+1}
        else if (np < n ) {s+"B";np=np+1}
      }
      val bw: BufferedWriter = new BufferedWriter(new FileWriter("output.txt"))
      bw.write(s)
      bw.close()
    }
}

import java.util.Scanner
import java.io._

object A {
    def main(args: Array[String]) {
      val sc: Scanner = new Scanner(new File("input.txt"))
      val n: Int = sc.nextInt()
      val m: Int = sc.nextInt()
      var b: Boolean = true
      if (n<m)b=false
      var np: Int = 0
      var mp: Int = 0
      var s:String = ""
      for (i <- 0 until n+m) {
        if (i % 2 == 0 && b && np < n) {s=s+"B";np=np+1}
        else if (i % 2 == 0 && mp < m) {s=s+"G";mp=mp+1}
        else if (i % 2 !=0 && b && mp < m) {s=s+"G";mp=mp+1}
        else if (np < n ) {s=s+"B";np=np+1}
      }
      val bw: BufferedWriter = new BufferedWriter(new FileWriter("output.txt"))
      bw.write(s)
      bw.close()
    }
}

import java.util.Scanner
import java.io._

object A {
    def main(args: Array[String]) {
      val sc: Scanner = new Scanner(new File("input.txt"))
      val n: Int = sc.nextInt()
      val m: Int = sc.nextInt()
      var b: Boolean = true
      if (n<m)b=false
      var np: Int = 0
      var mp: Int = 0
      var s:String = ""
      for (i <- 0 until n+m) {
        if (i % 2 == 0 && b && np < n) {s+"B";np=np+1}
        else if (i % 2 == 0 && mp < m) {s+"G";mp=mp+1}
        else if (i % 2 !=0 && b && mp < m) {s+"G";mp=mp+1}
        else if (np < n ) {s+"B";np=np+1}
      }
      val bw: BufferedWriter = new BufferedWriter(new FileWriter("output.txt"))
      bw.write(s+"\n")
      bw.close()
    }
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter("output.txt")
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		out.println("GB"*m+"B"*(n-m))
	else
        out.println("BG"*n+"G"*(m-n))
    out.close
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter(new File("output.txt"))
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		print("BG"*m+"B"*(n-m))
	else
        print("GB"*n+"G"*(m-n))
    out.close
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter("output.txt")
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		println("BG"*m+"B"*(n-m))
	else
        println("GB"*n+"G"*(m-n))
    out.close
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter("output.txt")
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		out.println("BG"*m+"B"*(n-m))
	else
        out.println("GB"*n+"G"*(m-n))
    out.close
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter("output.txt")
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		print("BG"*m+"B"*(n-m))
	else
        print("GB"*n+"G"*(m-n))
    out.close
}

import java.io.PrintWriter
import java.io.File
import java.util.Scanner

object test2 extends App {
	val sc=new Scanner(new File("input.txt"))
	val out=new PrintWriter("output.txt")
	val m=sc.nextInt
	val n=sc.nextInt
	if(m<=n)
		println("BG"*m+"B"*(n-m))
	else
        println("GB"*n+"G"*(m-n))
}


import scala.collection.mutable
import scala.io.StdIn

/**
  * @author traff
  */

object Main extends App {
  val n = StdIn.readLine().toInt

  val a = StdIn.readLine().split(" ").map(_.toInt)

  var i = n

  var m = mutable.HashSet[Int]()

  for (j <- 1 to n) {
    if (a(j-1) == i) {
      print(a(j-1))
      i-=1
      while (m.contains(i)) {
        print(s" $i")
        m.remove(i)
        i-=1
      }

    } else {
      m.add(a(j-1))
    }
    println()
  }
}

import scala.collection.mutable.ArrayBuffer

object Task1 extends App {
  var pos = 0
  val n = readInt()
  val rawData = readLine()
  val intArray = rawData.split(" ").map(x => x.toInt)
  val data = new ArrayBuffer[Pair[Int, Int]]
  for(i <- 0.until(n)) {
    data.+=(new Pair(i, intArray(i)))
  }
  val sortedData = data.sortWith(_._2 > _._2)
  sortedData.foreach(data => {
    val currPos = data._1
    while (currPos > pos) {
      println()
      pos += 1
    }
    print(data._2 + " ")
  })
}


import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine.toCharArray
  val nodes = mutable.ArrayBuffer[Array[Node]]()
  nodes += s.map(c => if (c == ')') closingNode else openingNode)

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += Array.ofDim[Node](len / 2 + 1)
    for (j <- 0 until len by 2) {
      nodes.last(j >> 1) = if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1)
    }
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
      if (l == (l >> level) << level && r + 1 == ((r + 1) >> level) << level) nodes(level)(l >> level)
      else if (l0 == r0) calc(l, r, nextLevel)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

object C extends App {

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

  Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  case class SegTree(as: Array[Node]) {

    val n = as.length
    val t = Array.ofDim[Node](4 * Integer.highestOneBit(n))
    build(1, 0, n - 1)

    def build(v: Int, tl: Int, tr: Int) {
      if (tl == tr) t(v) = as(tl)
	  else {
		val tm = (tl + tr) >> 1
		val v2 = v << 1
		build(v2, tl, tm)
		build(v2 + 1, tm + 1, tr)
		t(v) = t(v2) + t(v2 + 1)
	  }
    }

    def query(l: Int, r: Int, v: Int = 1, tl: Int = 0, tr: Int = n - 1): Node = {
    	if (l > r) Node()
    	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)
    	}
    }

  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine.toCharArray
  val nodes = SegTree(s.map(c => if (c == ')') closingNode else openingNode))

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(nodes.query(l - 1, r - 1).paired)
  }

  Console.flush
}

/**
** http://codeforces.com/contest/380/problem/C
**/

object Main extends App {
	import scala.io.StdIn._
	Console.setOut(new java.io.BufferedOutputStream(Console.out))

    val data = readLine().toCharArray
    val tree = new SegmentTree(data)
    tree.buildSegment()

    val p = readInt()
    for( _ <- 0 to p - 1) {
    	val Array(l, r) = readLine().split(" ").map(_.toInt)
	    println(tree.query(l-1, r-1).balanced)
    }
    Console.flush
}

case class Node(open: Int = 0, balanced: Int = 0, closed: Int = 0) {

	def balanced(other: Node): Int = {
		math.min(open, other.closed)
	}

}
object Node {
	def of(lNode: Node, rNode: Node): Node = {
		val matched = lNode.balanced(rNode)
		Node(lNode.open + rNode.open - matched,
				lNode.balanced + rNode.balanced + 2 * matched,
				lNode.closed + rNode.closed - matched)
	}
}

class SegmentTree(data: Array[Char]) {

	val treeSize = 4 * Integer.highestOneBit(data.size)
    val treeArray = Array.ofDim[Node](treeSize)

	def buildSegment() = {
		def buildLoop(vertex: Int, leftId: Int, rightId: Int): Unit = {
			if(leftId == rightId) {
				if(data(leftId) == '(') {
					treeArray(vertex) = Node(open = 1)
				} else {
					treeArray(vertex) = Node(closed = 1)
				}
			} else {
				val mid = leftId + (rightId - leftId)/2
				val leftV = 2 * vertex
				val rightV = 2 * vertex + 1
				buildLoop(leftV, leftId, mid)
				buildLoop(rightV, mid+1, rightId)

				val minBalanced = treeArray(leftV).balanced(treeArray(rightV))
				val leftNode = treeArray(leftV)
				val rightNode = treeArray(rightV)

				val leftParan = leftNode.open + rightNode.open - minBalanced
				val balancedParan = 2 * minBalanced + leftNode.balanced + rightNode.balanced
				val rightParan = leftNode.closed + rightNode.closed - minBalanced

				treeArray(vertex) = Node(leftParan, balancedParan, rightParan)
			}
		}

		buildLoop(1, 0, data.size - 1)
	}

	def query(l: Int, r: Int, vertex: Int = 1, begin: Int = 0, end: Int = data.size - 1): Node = {
		// println(s"$vertex: $begin $end")

		if(begin > r || l > end) {
			// println("out")
			Node(0, 0, 0)
		} else if(l <= begin && end <= r) {
			val res = treeArray(vertex)
			// println("ret: "+ res)
			res
		} else {
			val mid = begin + (end - begin)/2
			// println(s"mid: $mid")
			val lNode = query(l, math.min(r, mid), 2 * vertex, begin, mid)
			val rNode = query(math.max(l, mid+1), r, 2 * vertex + 1, mid+1, end)
			Node.of(lNode, rNode)
		}
	}

	def pprint() = {
	 	println(treeArray.mkString(" "))
	}
}

import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine

  val nodes = mutable.ArrayBuffer[IndexedSeq[Node]]()
  nodes += s.collect { case ')' => closingNode case '(' => openingNode }

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += (0 until len by 2).map(j => if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1))
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    //println(s"l=$l r=$r level=$level")
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
     // println(s"l0=$l0 r0=$r0")
      if (l == (l >> level) << level && r + 1 == ((r + 1) >> level) << level) nodes(level)(l >> level)
      else if (/*r - l + 1 <= (1 << nextLevel)*/ l0 == r0) calc(l, r, nextLevel)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  case class SegTree(as: Array[Node]) {

    val n = as.length
    val t = Array.ofDim[Node](4 * Integer.highestOneBit(n))
    build(1, 0, n - 1)

    def build(v: Int, tl: Int, tr: Int) {
      if (tl == tr) t(v) = as(tl)
	  else {
		val tm = (tl + tr) >> 1
		val v2 = v << 1
		build(v2, tl, tm)
		build(v2 + 1, tm + 1, tr)
		t(v) = t(v2) + t(v2 + 1)
	  }
    }

    def query(l: Int, r: Int, v: Int = 1, tl: Int = 0, tr: Int = n - 1): Node = {
    	if (l > r) Node()
    	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)
    	}
    }

  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine.toCharArray
  val nodes = SegTree(s.map(c => if (c == ')') closingNode else openingNode))

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(nodes.query(l - 1, r - 1).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine.toCharArray
  val nodes = mutable.ArrayBuffer[Array[Node]]()
  nodes += s.map(c => if (c == ')') closingNode else openingNode)

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += Array.ofDim[Node](len / 2 + 1)
    for (j <- 0 until len by 2) {
      nodes.last(j >> 1) = if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1)
    }
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
      if (l == (l >> level) << level && r + 1 == ((r + 1) >> level) << level) nodes(level)(l >> level)
      else if (l0 == r0) calc(l, r, nextLevel)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

  def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val t = tokenizeLine; Array.fill(n)(t.nextToken.toInt) }
  def readLongs(n: Int) = { val t = tokenizeLine; Array.fill(n)(t.nextToken.toLong) }
  def readBigs(n: Int) = { val t = tokenizeLine; Array.fill(n)(BigInt(t.nextToken)) }

  Console.setOut(new java.io.BufferedOutputStream(Console.out))

  val s = readLine

  val st = mutable.Stack[Char]()

  val cnts = Array.ofDim[Int](s.length)
  var cnt = 0

  val cnts2 = Array.ofDim[Int](s.length)
  var cnt2 = 0

  val uncloseds = Array.ofDim[Int](s.length)
  var unclosed = 0

  val unopeneds = Array.ofDim[Int](s.length)
  var unopened = 0

  val depths = Array.ofDim[Int](s.length)

  for (i <- s.indices) {
    val c = s(i)
    depths(i) = 2 * st.size
    if (c == '(') {
      uncloseds(i) = unclosed
      unclosed += 2
    } else {
      unclosed = Math.max(unclosed - 2, 0)
      uncloseds(i) = unclosed
    }
    if (c == ')' && st.headOption == Some('(')) {
      cnt += 2
      st.pop
    } else st.push(c)
    cnts(i) = cnt
  }

  st.clear
  for (i <- s.indices.reverse) {
    val c = s(i)
    if (c == ')') {
      unopeneds(i) = unopened
      unopened += 2
    } else {
      unopened = Math.max(unopened - 2, 0)
      unopeneds(i) = unopened
    }
    if (c == '(' && st.headOption == Some(')')) {
      cnt2 += 2
      st.pop
    } else st.push(c)
    cnts2(i) = cnt2
  }

//  println(cnts.mkString(" "))
//  println(depths.mkString(" "))
//  println(uncloseds.mkString(" "))
//  println(unopeneds.mkString(" "))

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2).map(_ - 1)
    val ans = Math.min(cnts(r) - cnts(l), cnts2(l) - cnts2(r))
    println(ans)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine

  val nodes = mutable.ArrayBuffer[IndexedSeq[Node]]()
  nodes += s.collect { case ')' => closingNode case '(' => openingNode }

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += (0 until len by 2).map(j => if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1))
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    //println(s"l=$l r=$r level=$level")
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
     // println(s"l0=$l0 r0=$r0")
      if (r - l + 1 <= (1 << nextLevel)) calc(l, r, nextLevel)
      else if (l == (l >> level) << level && r + 1 == ((r + 1) >> level) << level) nodes(level)(l >> level)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine

  val nodes = mutable.ArrayBuffer[Array[Node]]()
  nodes += s.toCharArray.map(c => if (c == ')') closingNode else openingNode)

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += Array.ofDim[Node](len / 2 + 1)
    for (j <- 0 until len by 2) {
      nodes.last(j >> 1) = if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1)
    }
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    //println(s"l=$l r=$r level=$level")
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
     // println(s"l0=$l0 r0=$r0")
      if (r - l + 1 <= (1 << nextLevel)) calc(l, r, nextLevel)
      else if (l == (l >> level) << level && r + 1 == ((r + 1) >> level) << level) nodes(level)(l >> level)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine

  val nodes = mutable.ArrayBuffer[Array[Node]]()
  nodes += s.toCharArray.map(c => if (c == ')') closingNode else openingNode)

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += Array.ofDim[Node](len / 2 + 1)
    for (j <- 0 until len by 2) {
      nodes.last(j >> 1) = if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1)
    }
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    //println(s"l=$l r=$r level=$level")
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
     // println(s"l0=$l0 r0=$r0")
      if (r - l + 1 <= (1 << nextLevel)) calc(l, r, nextLevel)
      else if (l == (l >> level) << level && r + 1 == ((r + 1) >> level << level)) nodes(level)(l >> level)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine

  val nodes = mutable.ArrayBuffer[Array[Node]]()
  nodes += s.toCharArray.map(c => if (c == ')') closingNode else openingNode)

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += Array.ofDim[Node](len / 2 + 1)
    for (j <- 0 until len by 2) {
      nodes.last(j >> 1) = if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1)
    }
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
      if (r - l + 1 == 1 << level) nodes(level)(l >> level)
      else if (r - l + 1 > (1 << nextLevel)) calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
      else calc(l, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

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

  //Console.setOut(new java.io.BufferedOutputStream(Console.out))

  case class Node(opening: Int = 0, closing: Int = 0, paired: Int = 0) {
    def +(other: Node) = {
      val matches = this.opening min other.closing
      Node(this.opening + other.opening - matches,
        this.closing + other.closing - matches,
        this.paired + other.paired + 2 * matches)
    }
  }

  val openingNode = Node(opening = 1)
  val closingNode = Node(closing = 1)

  val s = readLine

  val nodes = mutable.ArrayBuffer[IndexedSeq[Node]]()
  nodes += s.collect { case ')' => closingNode case '(' => openingNode }

  var len = nodes(0).length
  var i = 0
  while (len >= 1) {
    nodes += (0 until len by 2).map(j => if (j + 1 >= len) nodes(i)(j) else nodes(i)(j) + nodes(i)(j + 1))
    i += 1
    len /= 2
  }
  val maxLevel = i

  def calc(l: Int, r: Int, level: Int): Node = {
    //println(s"l=$l r=$r level=$level")
    if (level == 0) nodes(level)(l)
    else {
      val nextLevel = level - 1
      val l0 = l >> nextLevel
      val r0 = r >> nextLevel
     // println(s"l0=$l0 r0=$r0")
      if (r - l + 1 <= (1 << nextLevel)) calc(l, r, nextLevel)
      else if (l == (l >> level) << level && r + 1 == l + ((r - l + 1) >> level) << level) nodes(level)(l >> level)
      else calc(l, (r0 << nextLevel) - 1, nextLevel) + calc(r0 << nextLevel, r, nextLevel)
    }
  }

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2)
    println(calc(l - 1, r - 1, maxLevel).paired)
  }

  Console.flush
}

import scala.collection._

object C extends App {

  def tokenizeLine = new java.util.StringTokenizer(readLine)
  def readInts(n: Int) = { val t = tokenizeLine; Array.fill(n)(t.nextToken.toInt) }
  def readLongs(n: Int) = { val t = tokenizeLine; Array.fill(n)(t.nextToken.toLong) }
  def readBigs(n: Int) = { val t = tokenizeLine; Array.fill(n)(BigInt(t.nextToken)) }

  Console.setOut(new java.io.BufferedOutputStream(Console.out))

  val s = readLine

  val st = mutable.Stack[Char]()

  val cnts = Array.ofDim[Int](s.length)
  var cnt = 0

  val cnts2 = Array.ofDim[Int](s.length)
  var cnt2 = 0

  val uncloseds = Array.ofDim[Int](s.length)
  var unclosed = 0

  val unopeneds = Array.ofDim[Int](s.length)
  var unopened = 0

  val depths = Array.ofDim[Int](s.length)

  for (i <- s.indices) {
    val c = s(i)
    depths(i) = 2 * st.size
    if (c == '(') {
      uncloseds(i) = unclosed
      unclosed += 2
    } else {
      unclosed = Math.max(unclosed - 2, 0)
      uncloseds(i) = unclosed
    }
    if (c == ')' && st.headOption == Some('(')) {
      cnt += 2
      st.pop
    } else st.push(c)
    cnts(i) = cnt
  }

  st.clear
  for (i <- s.indices.reverse) {
    val c = s(i)
    if (c == ')') {
      unopeneds(i) = unopened
      unopened += 2
    } else {
      unopened = Math.max(unopened - 2, 0)
      unopeneds(i) = unopened
    }
    if (c == '(' && st.headOption == Some(')')) {
      cnt2 += 2
      st.pop
    } else st.push(c)
    cnts2(i) = cnt2
  }

//  println(cnts.mkString(" "))
//  println(depths.mkString(" "))
//  println(uncloseds.mkString(" "))
  //println(unopeneds.mkString(" "))

  val m = readInt

  for (i <- 0 until m) {
    val Array(l, r) = readInts(2).map(_ - 1)
    val ans = cnts(r) - cnts(l) - (if (l == 0) 0 else uncloseds(l) - uncloseds(r))
    println(ans)
  }

  Console.flush
}


import scala.io.StdIn

object Main extends App {
  val n = StdIn.readInt()
  for (_ <- 0 until n) {
    val number: BigInt = BigInt(StdIn.readLine())
    println(if (number % 2050 != 0) -1 else (number / 2050).toString.split("").map(_.toInt).sum)
  }
}

object CF1517A extends App {
    def readLong: Long = scala.io.StdIn.readLine.toLong
  def readInt: Int = scala.io.StdIn.readLine.toInt

  var T = readInt
    for (t <- 0 until T) {
      var x: Long = 205000000000000000L
      var n = readLong
      var ans = 0
      while (x >= 2050) {
        while (n >= x) {
          ans += 1
          n -= x
        }
        x /= 10
      }
      if (n == 0) {
        println(ans)
      } else {
        println(-1)
      }
    }
}

object cf1517a {

  def readInt(): Int = {
		Console.in.readLine().toInt
	}

  def readLong(): Long= {
		Console.in.readLine().toLong
	}

	def readInts(): Array[Int] = {
		val line = Console.in.readLine()
		line.split(' ').map( _.toInt)
	}

	def main(args: Array[String]): Unit = {
		val cases = readInt()
		var nCase = 0
		val res = for (nCase <- 1 to cases) yield {
			var v = readLong()
			var res = 0L
			var cSubstractor = 205000000000000000L
			while ( (v > 0) && (cSubstractor >= 2050L) ) {
				if (v >= cSubstractor) {
					res += v/cSubstractor
					v -= cSubstractor*(v/cSubstractor)
				}
				cSubstractor /= 10
			}
			if (v == 0) res else -1L
    }

		res.foreach( println(_))
  }
}

import scala.collection._
import scala.collection.mutable.TreeSet
import scala.collection.mutable.ArrayBuffer
import scala.io.StdIn._
import scala.util._

// https://codeforces.com/contest/977/problem/F

object Sum {
  def main(args: Array[String]): Unit = {
    val n = readInt()

    (0 until n).foreach(_ => {
      var v = readLong()

      var mul = 2050l
      while (10l * mul <= v) {
        mul *= 10l
      }

      var count = 0
      while (mul >= 2050 && v >= 0) {
        if (mul <= v) {
          v -= mul
          count += 1
        } else {
          mul /= 10
        }
      }

      if (v == 0) {
        println(count)
      } else {
        println(-1)
      }
    })
  }
}

object CF1517A extends App {
    def readLong: Long = scala.io.StdIn.readLine.toLong
  def readInt: Int = scala.io.StdIn.readLine.toInt

  var T = readInt
    for (t <- 0 until T) {
      var x: Long = 20500000000000000L
      var n = readLong
      var ans = 0
      while (x >= 2050) {
        while (n >= x) {
          ans += 1
          n -= x
        }
        x /= 10
      }
      if (n == 0) {
        println(ans)
      } else {
        println(-1)
      }
    }
}

object cf1517a {

  def readInt(): Int = {
		Console.in.readLine().toInt
	}

  def readLong(): Long= {
		Console.in.readLine().toLong
	}

	def readInts(): Array[Int] = {
		val line = Console.in.readLine()
		line.split(' ').map( _.toInt)
	}

	def main(args: Array[String]): Unit = {
		val cases = readInt()
		var nCase = 0
		val res = for (nCase <- 1 to cases) yield {
			var v = readLong()
			var res = 0L
			var cSubstractor = 20500000000000000L
			while ( (v > 0) && (cSubstractor >= 2050L) ) {
				if (v >= cSubstractor) {
					res += v/cSubstractor
					v -= cSubstractor*(v/cSubstractor)
				}
				cSubstractor /= 10
			}
			if (v == 0) res else -1L
    }

		res.foreach( println(_))
  }
}


object Solution extends App {
  val in = scala.io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val (coun, color) = (1 to n).foldLeft(Map.empty[Int, Int], Map.empty[(Int, Int), Int]){
    case ((count, colors), el) =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
      (count + (b -> (count.getOrElse(b, 0) + 1)), colors + ((b, a) -> (colors.getOrElse((b, a), 0) + 1)))
  }
  val (coun2, color2) = (1 to m).foldLeft(Map.empty[Int, Int], Map.empty[(Int, Int), Int]){
    case ((count, colors), el) =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
      (count + (b -> (count.getOrElse(b, 0) + 1)), colors + ((b, a) -> (colors.getOrElse((b, a), 0) + 1)))
  }

  val count = coun.foldLeft(0) {
    case(acc, (size, count)) => acc + Math.min(count, coun2.getOrElse(size, 0))
  }

  val col = color.foldLeft(0) {
    case(acc, (key, count)) => acc + Math.min(count, color2.getOrElse(key, 0))
  }

  println(s"$count $col")

}

object Main {
  import scala.collection.{mutable => mu}

  def main(args: Array[String]) {
    val nm = readLine().split(" ").map(_.toInt)
    val n = nm(0)
    val m = nm(1)

    val a1 = (1 to n).map(_ => readLine().split(" ").map(_.toInt))
    val a2 = (1 to m).map(_ => readLine().split(" ").map(_.toInt))

    val m1 = mu.Map[Int, mu.Map[Int, Int]]()
    val m2 = mu.Map[Int, mu.Map[Int, Int]]()

    a1.foreach { t =>
      val m = m1.getOrElse(t(1), mu.Map[Int, Int]())
      m1(t(1)) = m
      val prev = m.getOrElse(t(0), 0)
      m(t(0)) = prev + 1
    }

    a2.foreach { t =>
      val m = m2.getOrElse(t(1), mu.Map[Int, Int]())
      m2(t(1)) = m
      val prev = m.getOrElse(t(0), 0)
      m(t(0)) = prev + 1
    }

    var all = 0
    var good = 0
    for( (d, cols) <- m1) {
      val m = m2.getOrElse(d, mu.Map.empty[Int, Int])
      all += cols.values.sum.min(m.values.sum)
      good += cols.map(t => m.getOrElse(t._1, 0).min(t._2)).sum
    }

    print(all + " " + good)
  }
}

import scala.collection.mutable.Map
object Main {
  def readLineOfNums(): Array[Int] = readLine().split(" ").map(_.toInt)
  def prepareMaps(n: Int): (Map[Int, Int], Map[(Int, Int), Int]) = {
    val mapGeneral = Map[Int, Int]()
    val mapPerfect = Map[(Int, Int), Int]()
    for (i <- 1 to n) {
      val Array(y, x) = readLineOfNums()
      if (mapGeneral.contains(x))
        mapGeneral(x) += 1
      else
        mapGeneral += (x -> 1)
      if (mapPerfect.contains((x, y)))
        mapPerfect((x, y)) += 1
      else
        mapPerfect += ((x, y) -> 1)
    }
    (mapGeneral, mapPerfect)
  }
  def main(args: Array[String]) = {
    val Array(n, m) = readLineOfNums()
    val (generalF, perfectF) = prepareMaps(n)
    val (generalK, perfectK) = prepareMaps(m)
    var sumG = 0
    for ((x, y) <- generalF)
      if (generalK.contains(x))
        sumG += List(y, generalK(x)).min
    var sumP = 0
    for(((x,y), z) <- perfectF)
      if (perfectK.contains((x,y)))
        sumP += List(z, perfectK((x, y))).min
    println(sumG.toString + " " + sumP.toString)
  }
}

object Solution extends App {
  val in = scala.io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val (coun, color) = (1 to n).foldLeft(Map.empty[Int, Int], Map.empty[(Int, Int), Int]){
    case ((count, colors), el) =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
      (count + (b -> (count.getOrElse(b, 0) + 1)), colors + ((b, a) -> (colors.getOrElse((b, a), 0) + 1)))
  }
  val c = (1 to m).foldLeft(0, 0, coun, color) {
    case (acc@(pair, goodPair, d, col), el) =>
      val Array(a, b) = in.next().split(' ').map(_.toInt)
      val dCount = d.getOrElse(b, 0)
      val colCount = col.getOrElse((b, a), 0)

      if (dCount > 0) {
        if (colCount > 0) {
          (pair + 1, goodPair + 1, d + (b -> (dCount - 1)), col + ((b, a) -> (colCount - 1)))
        } else {
          (pair + 1, goodPair + 1, d + (b -> (dCount - 1)), col)
        }
      } else {
        acc
      }
  }

  println(s"${c._1} ${c._2}")

}

object Solution extends App {
  val in = scala.io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val (coun, color) = (1 to n).foldLeft(Map.empty[Int, Int], Map.empty[(Int, Int), Int]){
    case ((count, colors), el) =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
      (count + (b -> (count.getOrElse(b, 0) + 1)), colors + ((b, a) -> (colors.getOrElse((b, a), 0) + 1)))
  }
  val c = (1 to m).foldLeft(0, 0, coun, color) {
    case (acc@(pair, goodPair, d, col), el) =>
      val Array(a, b) = in.next().split(' ').map(_.toInt)
      val dCount = d.getOrElse(b, 0)
      val colCount = col.getOrElse((b, a), 0)

      if (dCount > 0) {
        if (colCount > 0) {
          (pair + 1, goodPair + 1, d + (b -> (dCount - 1)), col + ((b, a) -> (colCount - 1)))
        } else {
          (pair + 1, goodPair, d + (b -> (dCount - 1)), col)
        }
      } else {
        acc
      }
  }

  println(s"${c._1} ${c._2}")

}

object Solution extends App {
  val in = scala.io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val f = (1 to n).map{_ =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
    (b, a)
  }.sorted.toList
  val c = (1 to m).map{_ =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
    (b, a)
  }.sorted.toList

  def sol(f: List[(Int, Int)], c: List[(Int, Int)], sum: Int = 0, b: Int = 0): (Int, Int) = {
    if (f.isEmpty || c.isEmpty) (sum, b)
    else if (f.head._1 > c.head._1)
      sol(f, c.tail, sum, b)
    else if (f.head._1 < c.head._1)
      sol(f.tail, c, sum, b)
    else if (f.head._2 == c.head._2)
      sol(f.tail, c.tail, sum + 1, b + 1)
    else
      sol(f.tail, c.tail, sum + 1, b)
  }

  val res = sol(f, c)
  println(s"${res._1} ${res._2}")

}

object Solution extends App {
  val in = scala.io.Source.stdin.getLines()
  val Array(n, m) = in.next().split(' ').map(_.toInt)
  val (coun, color) = (1 to n).foldLeft(Map.empty[Int, Int], Map.empty[(Int, Int), Int]){
    case ((count, colors), el) =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
      (count + (b -> (count.getOrElse(b, 0) + 1)), colors + ((b, a) -> (colors.getOrElse((b, a), 0) + 1)))
  }
  val (coun2, color2) = (1 to n).foldLeft(Map.empty[Int, Int], Map.empty[(Int, Int), Int]){
    case ((count, colors), el) =>
    val Array(a, b) = in.next().split(' ').map(_.toInt)
      (count + (b -> (count.getOrElse(b, 0) + 1)), colors + ((b, a) -> (colors.getOrElse((b, a), 0) + 1)))
  }

  val count = coun.foldLeft(0) {
    case(acc, (size, count)) => acc + Math.min(count, coun2.getOrElse(size, 0))
  }

  val col = color.foldLeft(0) {
    case(acc, (key, count)) => acc + Math.min(count, color2.getOrElse(key, 0))
  }

  println(s"$count $col")

}


import java.util.TreeSet
import scala.collection.mutable.ArrayBuilder

object F extends App {

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

  case class Pair(c: Int, i: Int) extends Comparable[Pair] {

    private final val weight = c * 100000L + i

    def compareTo(other: Pair): Int = java.lang.Long.compare(weight, other.weight)

  }

  val Array(n) = readInts(1)
  val xs, ys = Array.ofDim[Pair](n)

  for (i <- 0 until n) {
    val Array(x, y) = readInts(2)
    xs(i) = Pair(x, i)
    ys(i) = Pair(y, i)
  }

  def recurse(keepIdsByX: TreeSet[Pair], keepIdsByY: TreeSet[Pair], separateIds: Array[Int]): Int = {

    val separateByX, separateByY = new TreeSet[Pair]

    for (i <- separateIds) {
      separateByX.add(xs(i))
      keepIdsByX.remove(xs(i))
      separateByY.add(ys(i))
      keepIdsByY.remove(ys(i))
    }

    count(separateByX, separateByY) + count(keepIdsByX, keepIdsByY)
  }

  def count(keepIdsByX: TreeSet[Pair], keepIdsByY: TreeSet[Pair]): Int = {

    val left = keepIdsByX.iterator
    val right = keepIdsByX.descendingIterator
    val top = keepIdsByY.iterator
    val bottom = keepIdsByY.descendingIterator

    var Pair(prevLeftX, leftI) = left.next
    var Pair(prevTopY, topI) = top.next
    var Pair(prevRightX, rightI) = right.next
    var Pair(prevBottomY, bottomI) = bottom.next

    val leftIds, rightIds, topIds, bottomIds = new ArrayBuilder.ofInt
    leftIds += leftI
    rightIds += rightI
    topIds += topI
    bottomIds += bottomI

    var done = false
    var separateIds = Array.empty[Int]

    while (!done && left.hasNext) {

      if (!done) {
        val p = left.next
        if (prevLeftX < p.c - 1) {
          separateIds = leftIds.result
          done = true
        } else {
          leftIds += p.i
          prevLeftX = p.c
        }
      }

      if (!done) {
        val p = right.next
        if (prevRightX > p.c + 1) {
          separateIds = rightIds.result
          done = true
        } else {
          rightIds += p.i
          prevRightX = p.c
        }
      }

      if (!done) {
        val p = top.next
        if (prevTopY < p.c - 1) {
          separateIds = topIds.result
          done = true
        } else {
          topIds += p.i
          prevTopY = p.c
        }
      }

      if (!done) {
        val p = bottom.next
        if (prevBottomY > p.c + 1) {
          separateIds = bottomIds.result
          done = true
        } else {
          bottomIds += p.i
          prevBottomY = p.c
        }
      }

      if (prevLeftX >= prevRightX && prevTopY >= prevBottomY) done = true
    }

    if (separateIds.nonEmpty) recurse(keepIdsByX, keepIdsByY, separateIds)
    else 1
  }

  val allByX, allByY = new TreeSet[Pair]

  for (i <- 0 until n) {
    allByX.add(xs(i))
    allByY.add(ys(i))
  }

  println(count(allByX, allByY))
}

import java.util.TreeSet
import scala.collection.mutable.ArrayBuilder

object F extends App {

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

  case class Pair(c: Int, id: Int) extends Comparable[Pair] {

    def compareTo(other: Pair): Int =
      if (c < other.c) -1
      else if (c > other.c) 1
      else if (id < other.id) -1
      else if (id > other.id) 1
      else 0

  }

  val Array(n) = readInts(1)
  val xs, ys = Array.ofDim[Pair](n)

  for (i <- 0 until n) {
    val Array(x, y) = readInts(2)
    xs(i) = Pair(x, i)
    ys(i) = Pair(y, i)
  }

  def recurse(keepIdsByX: TreeSet[Pair], keepIdsByY: TreeSet[Pair], separateIds: Array[Int]): Int = {

    val separateByX, separateByY = new TreeSet[Pair]

    for (i <- separateIds) {
      separateByX.add(xs(i))
      keepIdsByX.remove(xs(i))
      separateByY.add(ys(i))
      keepIdsByY.remove(ys(i))
    }

    count(separateByX, separateByY) + count(keepIdsByX, keepIdsByY)
  }

  def count(keepIdsByX: TreeSet[Pair], keepIdsByY: TreeSet[Pair]): Int = {

    val left = keepIdsByX.iterator
    val right = keepIdsByX.descendingIterator
    val top = keepIdsByY.iterator
    val bottom = keepIdsByY.descendingIterator

    var Pair(prevLeftX, leftI) = left.next
    var Pair(prevTopY, topI) = top.next
    var Pair(prevRightX, rightI) = right.next
    var Pair(prevBottomY, bottomI) = bottom.next

    val leftIds, rightIds, topIds, bottomIds = new ArrayBuilder.ofInt
    leftIds += leftI
    rightIds += rightI
    topIds += topI
    bottomIds += bottomI

    var done = false
    var separateIds = Array.empty[Int]

    while (!done && left.hasNext) {

      if (!done) {
        val p = left.next
        if (prevLeftX < p.c - 1) {
          separateIds = leftIds.result
          done = true
        } else {
          leftIds += p.id
          prevLeftX = p.c
        }
      }

      if (!done) {
        val p = right.next
        if (prevRightX > p.c + 1) {
          separateIds = rightIds.result
          done = true
        } else {
          rightIds += p.id
          prevRightX = p.c
        }
      }

      if (!done) {
        val p = top.next
        if (prevTopY < p.c - 1) {
          separateIds = topIds.result
          done = true
        } else {
          topIds += p.id
          prevTopY = p.c
        }
      }

      if (!done) {
        val p = bottom.next
        if (prevBottomY > p.c + 1) {
          separateIds = bottomIds.result
          done = true
        } else {
          bottomIds += p.id
          prevBottomY = p.c
        }
      }

      if (prevLeftX >= prevRightX && prevTopY >= prevBottomY) done = true
    }

    if (separateIds.nonEmpty) recurse(keepIdsByX, keepIdsByY, separateIds)
    else 1
  }

  val allByX, allByY = new TreeSet[Pair]

  for (i <- 0 until n) {
    allByX.add(xs(i))
    allByY.add(ys(i))
  }

  println(count(allByX, allByY))
}