Thanos wants to destroy the avengers base, but he needs to destroy the avengers along with their base.Let we represent their base with an array, where each position can be occupied by many avengers, but one avenger can occupy only one position. Length of their base is a perfect power of $$$2$$$. Thanos wants to destroy the base using minimum power. He starts with the whole base and in one step he can do either of following:   if the current length is at least $$$2$$$, divide the base into $$$2$$$ equal halves and destroy them separately, or  burn the current base. If it contains no avenger in it, it takes $$$A$$$ amount of power, otherwise it takes his $$$B \cdot n_a \cdot l$$$ amount of power, where $$$n_a$$$ is the number of avengers and $$$l$$$ is the length of the current base. Output the minimum power needed by Thanos to destroy the avengers' base.

The first line contains four integers $$$n$$$, $$$k$$$, $$$A$$$ and $$$B$$$ ($$$1 \leq n \leq 30$$$, $$$1 \leq k \leq 10^5$$$, $$$1 \leq A,B \leq 10^4$$$), where $$$2^n$$$ is the length of the base, $$$k$$$ is the number of avengers and $$$A$$$ and $$$B$$$ are the constants explained in the question. The second line contains $$$k$$$ integers $$$a_{1}, a_{2}, a_{3}, \ldots, a_{k}$$$ ($$$1 \leq a_{i} \leq 2^n$$$), where $$$a_{i}$$$ represents the position of avenger in the base.

Output one integer — the minimum power needed to destroy the avengers base.

NoteConsider the first example.One option for Thanos is to burn the whole base $$$1-4$$$ with power $$$2 \cdot 2 \cdot 4 = 16$$$.Otherwise he can divide the base into two parts $$$1-2$$$ and $$$3-4$$$.For base $$$1-2$$$, he can either burn it with power $$$2 \cdot 1 \cdot 2 = 4$$$ or divide it into $$$2$$$ parts $$$1-1$$$ and $$$2-2$$$.For base $$$1-1$$$, he can burn it with power $$$2 \cdot 1 \cdot 1 = 2$$$. For $$$2-2$$$, he can destroy it with power $$$1$$$, as there are no avengers. So, the total power for destroying $$$1-2$$$ is $$$2 + 1 = 3$$$, which is less than $$$4$$$. Similarly, he needs $$$3$$$ power to destroy $$$3-4$$$. The total minimum power needed is $$$6$$$.

object Main {
  def main(args: Array[String]): Unit = {
    val s = new Main()
    s.solve()
    s.out.flush()
  }
}

class Main {
  import java.io._
  import java.util.StringTokenizer

  import scala.collection.mutable
  import scala.util.Sorting
  import math.{abs, max, min}
  import mutable.{ArrayBuffer, ListBuffer}
  import scala.reflect.ClassTag

  val MOD = 1000000007
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val K, M, AA, BB = ni()
    val A = na(M, -1)
    sort(A)

    // [l, r)
    def countAvengers(l: Int, r: Int): Int = {
      lowerBound(A, r) - lowerBound(A, l)
    }

    // [l, r)
    def calc(l: Int, r: Int, num: Int): Long = {
//      val num = countAvengers(l, r)

//      debug(s"$l $r num=$num")

      if (num == 0) AA // 一人もいなかったら即時破壊するのがいい
      else if (r - l == 1) {
        // サイズが1の場合はもう分割できない
        if(num > 0) BB.toLong * num * (r - l) else AA
      } else {
        val planA = {
          val mid = (l + r) / 2
          val numL = countAvengers(l, mid)
          calc(l, mid, numL) + calc(mid, r, num - numL)
        }
        val planB = BB.toLong * num * (r - l)

//        debug(s"$l $r $planA $planB")

        min(planA, planB)
      }
    }

    // アベンジャーが数少ないのでdfsがlogK * Kぐらいの回数ですむはず
    val ans = calc(0, 1 << K, M)

    out.println(ans)
  }

  // あえてコピペ
  // 要はcountLt
  // a >= x  [x-2, x-1, x, x, x, x+1] の 2
  def lowerBound(a: Array[Int], x: Int): Int = {
    def step(l: Int, h: Int): Int = {
      if (h - l == 1) h
      else {
        val mid = (l + h) / 2
        if (a(mid) >= x) step(l, mid)
        else step(mid, h)
      }
    }

    step(-1, a.length)
  }

  def sort(a: Array[Int]): Array[Int] = {
    val n = a.length
    REP(n) { i =>
      val j = scala.util.Random.nextInt(n - i) + i
      val tmp = a(i)
      a(i) = a(j)
      a(j) = tmp
    }
    Sorting.stableSort(a)
    a
  }

  def debug(as: Array[Boolean]): Unit = {
    System.err.println(as.map(x => if(x) "1" else "0").mkString)
  }

  def debug(as: Array[Int]): Unit = {
    System.err.println(as.mkString(" "))
  }

  def debug(as: Array[Long]): Unit = {
    System.err.println(as.mkString(" "))
  }

  def debug(s: String): Unit = {
    System.err.println(s)
  }

  def debug(num: Long): Unit = {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next().toInt
    def nextLong(): Long = next().toLong
    def nextChar(): Char = next().charAt(0)
  }
  val sc = new InputReader(System.in)
  def ni(): Int = sc.nextInt()
  def nl(): Long = sc.nextLong()
  def nc(): Char = sc.nextChar()
  def ns(): String = sc.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 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]) = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {
  //find first index greater or equal to n
  //return array length if no such index exists
  //search range is [start,end)
  def binsearch(a:Array[Int],start:Int,end:Int,n:Long):Int= {
    assert(end > start, "end should be bigger index than start")
    assert(a.length >= end)
    if(end - start>2){
      val m = (start+end)/2
      if (a(m)>=n){binsearch(a,start,m,n)}else{binsearch(a,m,end,n)}
    }
    else if(end - start ==2){
      if(a(start)>=n){start}else if(a(end-1)>=n){end-1}else{end}
    }else{ //end - start==1
      if(a(start) >= n){start}else{end}
    }
  }

  def howManySmaller(sortedArray:Array[Int],range:(Int,Int),n:Long)={
    //println(s"array in binsearch ${sortedArray.mkString(",")}")
    //println(s"range ${range}")
    //println(s"range ${range}")
    //println(s"${n}")
    val j = binsearch(sortedArray,range._1,range._2,n)
    j - range._1
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }
  //(start,end) - range of sortedIndices, with indices that reside in baseRange
  //populOnTheLeft - how many indices there is on the left from baseRange
  case class PopulationInfo(start:Int,end:Int,populOnTheLeft:Int)
  case class Parameters(A:Int,B:Int,popul:Int)

  def minPower3(baseRange:(Long,Long),
                sortedIndices:Array[Int],
                populData:PopulationInfo,
                p:Parameters
               ):Long={
    assert(baseRange._2-baseRange._1>=1,"base range lower than 1")

    val population = p.popul

    ((baseRange._2-baseRange._1,population)) match {
      case (length, pop) if length == 1 => powerTo1Shot(pop, length, p.A, p.B)
      case (length, 0) if length >= 1 => p.A
      case (length, pop) if length >= 2 => {
        val leftHalfBase = (baseRange._1,(baseRange._1+length/2))
        val rightHalfBase = (baseRange._1+length/2,baseRange._2)
        val breakPoint = binsearch(sortedIndices,populData.start,populData.end,baseRange._1+length/2)
        val populationLeft = breakPoint - populData.populOnTheLeft//ok
        val populationRight = pop - populationLeft
        def tests() {
          println(s"total pop ${p.popul}")
          println(sortedIndices.mkString(","))
          println(baseRange)
          println(s"breakPoint ${breakPoint}")
          println(s"popul on the left ${populData.populOnTheLeft}")
          println(s"ppopuleft ${populationLeft}")
          println(s"ppopulright ${populationRight}")
          println(s"---NEXT----")
        }
        //tests()
        val popDataL = PopulationInfo(populData.start, breakPoint, populData.populOnTheLeft)
        val popDataR = PopulationInfo(breakPoint, populData.end, populData.populOnTheLeft+populationLeft)

        min(
          powerTo1Shot(pop, length, p.A, p.B),
          minPower3(leftHalfBase,sortedIndices,popDataL,Parameters(p.A,p.B,populationLeft))+
          minPower3(rightHalfBase,sortedIndices,popDataR,Parameters(p.A,p.B,populationRight))
        )
      }
    }
    }

  def minPowerMain(n:Int,indices:Array[Int],A:Int,B:Int,k:Int):Long ={
    assert(indices.length==k)
    val baseRange = (0.toLong, math.pow(2,n).toLong)
    val indicesSorted = indices.sorted.map(_-1)
    val popInfo = PopulationInfo(0,k,0)

    val p = Parameters(A,B,k)
    minPower3(baseRange,indicesSorted,popInfo,p)
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val minPower = minPowerMain(n,indices, A, B, k)
    println(minPower)
  }

}

object test extends App{
  import C537v2._
  def runTests()= {
    println(howManySmaller(Array(1),(0,1),2)==1)
    println(howManySmaller(Array(1),(0,1),0)==0)
    println(howManySmaller(Array(0,1,2,3,4,5),(2,5),4)==2)
    println(howManySmaller(Array(0,1,2,3,4,5),(3,4),4)==1)
    println(howManySmaller(Array(0,1,2,3,4,5),(0,6),7)==6)
    println(howManySmaller(Array(0,1,2,3,4,5),(0,6),4)==4)

  }
  runTests()

/*
val n = 30
val k = 88704
val A = 1
val B = 2140
val Len = math.pow(2,n).toInt
  //val indices = List(1,3)
//val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(198987)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len)).sorted
val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len)+1).map(_-1)
  //indices.sorted.foreach(print)
  //println("\n--------------------")
//val indices = Array(858,765)
//val indices = Array(858,765)

  val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
val t4 = System.nanoTime()
  val minPower2 = minimalPower2(indicesSorted, 0, Len, A, B,(0,k))
val t5 = System.nanoTime()

  println(minPower)
  println(minPower2)
  println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  println(s"rest: ${(t3-t2)*1.0/1e9}")
  println(s"whole ${(t3-t1)*1.0/1e9}")
  println(s"sorting ${(t4-t3)*1.0/1e9}")
  println(s"bin search ${(t5-t4)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  //println(minimalPower2(Array(1,7), 0, 8, 1, 2))
  //println(minimalPower2(8,Array(1,1),1,2))
  //println(minimalPower2(8,Array(1,1),1,2))

*/
}

object scratch3 extends App{
  import C537v2._
  //testing howManySmaller3, get left, right ranges for population table
  val A = Array(3,3,5,7).sorted
  val r = 2
  //println(howManySmaller3(A,(0,4),r))
  //testing minPower3

  val sortedIndices = Array(1,3)
  val p = Parameters(1,2,sortedIndices.length)
  val baseRange = (0l,4l)
  val populData = PopulationInfo(0,4,0)
  /*
  val baseRange = (0l,4l)
  val populData = PopulationInfo(0,4,0)
  */
  /*
  val baseRange = (0l,2l)
  val populData = PopulationInfo(0,3,0)
  */

  //println(minPower3(baseRange,sortedIndices,populData,p))
  //println(s"minPowL${minPower3(leftHalfBase,sortedIndices,popDataL,p)}")
  //println(minPowerMain(2,Array(1,1,1),A=1,B=2,k=3)==8)
  //println(minPowerMain(2,Array(1,2),A=1,B=2,k=2)==5)
  println(minPowerMain(2,Array(1,3),A=1,B=2,k=2)==6)
  println(minPowerMain(3,Array(1,7),A=1,B=2,k=2)==8)
  println(minPowerMain(3,Array(7,8),A=5,B=1,k=2)==12)
  //println(s"minPowLL${minPower3((0,2),sortedIndices,PopulationInfo(0,3,0),p)}")

}

object testttt extends App{
  val a = Array(1,2,3)
  println(a.take(2).length)
}

object Main {
  def main(args: Array[String]): Unit = {
    val s = new Main()
    s.solve()
    s.out.flush()
  }
}

class Main {
  import java.io._
  import java.util.StringTokenizer

  import scala.collection.mutable
  import scala.util.Sorting
  import math.{abs, max, min}
  import mutable.{ArrayBuffer, ListBuffer}
  import scala.reflect.ClassTag

  val MOD = 1000000007
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val K, M, AA, BB = ni()
    val A = na(M, -1)
    sort(A)

    // [l, r)
    def countAvengers(l: Int, r: Int): Int = {
      lowerBound(A, r) - lowerBound(A, l)
    }

    // [l, r)
    def calc(l: Int, r: Int): Long = {
      val num = countAvengers(l, r)

//      debug(s"$l $r num=$num")

      if (num == 0) AA // 一人もいなかったら即時破壊するのがいい
      else if (r - l == 1) {
        // サイズが1の場合はもう分割できない
        if(num == 1) BB else AA
      } else {
        val planA = {
          val mid = (l + r) / 2
          calc(l, mid) + calc(mid, r)
        }
        val planB = BB.toLong * num * (r - l)

//        debug(s"$l $r $planA $planB")

        min(planA, planB)
      }
    }

    // アベンジャーが数少ないのでdfsがlogK * Kぐらいの回数ですむはず
    val ans = calc(0, 1 << K)

    out.println(ans)
  }

  // あえてコピペ
  // 要はcountLt
  // a >= x  [x-2, x-1, x, x, x, x+1] の 2
  def lowerBound(a: Array[Int], x: Int): Int = {
    def step(l: Int, h: Int): Int = {
      if (h - l == 1) h
      else {
        val mid = (l + h) / 2
        if (a(mid) >= x) step(l, mid)
        else step(mid, h)
      }
    }

    step(-1, a.length)
  }

  def sort(a: Array[Int]): Array[Int] = {
    val n = a.length
    REP(n) { i =>
      val j = scala.util.Random.nextInt(n - i) + i
      val tmp = a(i)
      a(i) = a(j)
      a(j) = tmp
    }
    Sorting.stableSort(a)
    a
  }

  def debug(as: Array[Boolean]): Unit = {
    System.err.println(as.map(x => if(x) "1" else "0").mkString)
  }

  def debug(as: Array[Int]): Unit = {
    System.err.println(as.mkString(" "))
  }

  def debug(as: Array[Long]): Unit = {
    System.err.println(as.mkString(" "))
  }

  def debug(s: String): Unit = {
    System.err.println(s)
  }

  def debug(num: Long): Unit = {
    System.err.println(num)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next().toInt
    def nextLong(): Long = next().toLong
    def nextChar(): Char = next().charAt(0)
  }
  val sc = new InputReader(System.in)
  def ni(): Int = sc.nextInt()
  def nl(): Long = sc.nextLong()
  def nc(): Char = sc.nextChar()
  def ns(): String = sc.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 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]) = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def howManySmaller(a: Array[Int], left:Int, right:Int, n:Long): Int = {
    //to not get out of bounds error
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => a.length //if right is smaller, everything is
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => howManySmaller(a, left, mid, n)
      case (le, mi, _) if mi <= n => howManySmaller(a, mid, right, n)
    }
  }

  def minimalPower2(Len: Long, indicesSorted:Array[Int], A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length
    val mid = Len / 2
    val populationLeft = if(indicesSorted.length >0) {
      howManySmaller(indicesSorted, 0, indicesSorted.length, mid)
    }else{
      0
    }
      val minPow = (populationWhole, Len,indicesSorted.length) match {
      //case (0, length,_) if length == 0 => 0
        case (0,_,_) => A
      case (0, length,_) if length > 0 => {
        println(s"A: ${length}")
        A
      }
      case (_, length,_) if length == 1 => {
        /*
        println(s"popul ${populationWhole}")
        println(s"len ${length}")
        println(s"A ${A}")
        println(s"B ${B}")
        println(s"powTo1Shot ${powerTo1Shot(populationWhole, length, A, B)} ")
        println("jeb")
        */
        powerTo1Shot(populationWhole, length, A, B)}
      case (_, length,_) if length >= 2 => {
        //val aa = indicesSorted.take(populationLeft)
        //aa.foreach(x=>println(s"${x}, a"))
        //val bb = indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt)
        //aa.foreach(x=>println(s"${x}, b"))
        indicesSorted.take(populationLeft)
        min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(Len / 2, indicesSorted.take(populationLeft), A, B) + minimalPower2(Len / 2, indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt), A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val Len = math.pow(2, n).toLong
    //val populTree: Option[Tree] = populationTree(indices, n,Len)
    //val minPower = minimalPower(Len, populTree, A, B)
    val minPower = minimalPower2(Len,indices,A,B)
    println(minPower)
  }

}

object test extends App{
  import C537v2._

val n = 3
val k = 2
val A = 1
val B = 2

val indices = Array(1,7)

/*
val n = 30
val k = 10000
val A = 78
val B = 9765
*/
  //val indices = List(1,3)
val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(1000)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(Len,indices,A,B)
val t4 = System.nanoTime()

  //println(minPower)
  //println(minPower2)
  //println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  //println(s"rest: ${(t3-t2)*1.0/1e9}")
  //println(s"whole ${(t3-t1)*1.0/1e9}")
  //println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  println(minimalPower2(8,Array(1,7),1,2))
  //println(minimalPower2(8,Array(1,1),1,2))

}

object scratch2 extends App{

  def findFirstLarger(a: Array[Int],left:Int,right:Int, n:Long): Int = {
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => -1
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => findFirstLarger(a, left, mid, n)
      case (le, mi, _) if mi <= n => findFirstLarger(a, mid, right, n)
    }
  }
 //println(findFirstLarger(Array(1,7),0,2,4))
  val a = Array(1,2,3)
  //println(findFirstLarger(a,0,a.length-1,4))
  assert(findFirstLarger(Array(1,2,3,5,6,7),0,a.length-1,4)==3)
  assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  assert(findFirstLarger(Array(1,8),0,a.length-1,4) == 1)
  //assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)

}

object scratch3 extends App{
  val a1 = Array(1,7)
  val a2 = a1.take(1)
  val a3 = a1.drop(1)
  a2.length
  a3.length
  println(a2(0))
  println(a3(0))

}

import scala.math._
import scala.io.StdIn._

object C537{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,binaryString.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,binaryString.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Double = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = populationTree match {
      case None => A
      case Some(tree) => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }

 /*
  val n = 3
  val k = 2
  val A = 1
  val B = 2

  val indices = Array(1,7)

  val Len = math.pow(2,n).toInt
  val populTree:Option[Tree]= populationTree(indices.toList,Len)

  val minPower = minimalPower(Len,populTree,A,B)
  //println(populTree.get.value)

  println(minPower)
  println(growTree(Some(Tree(None,None,0)),"1"))

  */
}

object scratch extends App{
  println("ok")

}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def howManySmaller(a: Array[Int], left:Int, right:Int, n:Long): Int = {
    //to not get out of bounds error
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2
    if(a.length == 0){
      0
    }else {
      (a(left), a(mid), a(right2)) match {
        case (le, mi, ri) if ri <= n => a.length //if right is smaller, everything is
        case (le, _, _) if le > n => left
        case (le, mi, _) if le == mi => right2
        case (le, mi, _) if mi > n => howManySmaller(a, left, mid, n)
        case (le, mi, _) if mi <= n => howManySmaller(a, mid, right, n)
      }
    }
  }

  def minimalPower2(indicesSorted: Array[Int], start: Long, Len: Long, A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length

    val mid = start + Len / 2
    val breakPoint = howManySmaller(indicesSorted, 0, indicesSorted.length, mid)

    val indicesLeft = indicesSorted.take(breakPoint)
    val indicesRight = indicesSorted.drop(breakPoint)

      val minPow = (populationWhole, Len,indicesSorted.length) match {
        case (0,_,_) => A
      case (0, length,_) if length > 0 => {
        A
      }
      case (_, length,_) if length == 1 => {
        powerTo1Shot(populationWhole, length, A, B)}
      case (_, length,_) if length >= 2 => {
        min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(indicesLeft, start, Len / 2, A, B) +
          minimalPower2(indicesRight,start+Len/2 , Len / 2, A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val Len = math.pow(2, n).toLong
    //val populTree: Option[Tree] = populationTree(indices, n,Len)
    //val minPower = minimalPower(Len, populTree, A, B)
    val minPower = minimalPower2(indices, 0, Len, A, B)
    println(minPower)
  }

}

object test extends App{
  import C537v2._

val n = 3
val k = 2
val A = 1
val B = 2

val indices = Array(1,7)

/*
val n = 30
val k = 10000
val A = 78
val B = 9765
*/
  //val indices = List(1,3)
val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(1000)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(indices, 0, Len, A, B)
val t4 = System.nanoTime()

  //println(minPower)
  //println(minPower2)
  //println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  //println(s"rest: ${(t3-t2)*1.0/1e9}")
  //println(s"whole ${(t3-t1)*1.0/1e9}")
  //println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  println(minimalPower2(Array(1,7), 0, 8, 1, 2))
  //println(minimalPower2(8,Array(1,1),1,2))

}

object scratch2 extends App{

  def findFirstLarger(a: Array[Int],left:Int,right:Int, n:Long): Int = {
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => -1
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => findFirstLarger(a, left, mid, n)
      case (le, mi, _) if mi <= n => findFirstLarger(a, mid, right, n)
    }
  }
 //println(findFirstLarger(Array(1,7),0,2,4))
  val a = Array(1,2,3)
  //println(findFirstLarger(a,0,a.length-1,4))
  assert(findFirstLarger(Array(1,2,3,5,6,7),0,a.length-1,4)==3)
  assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  assert(findFirstLarger(Array(1,8),0,a.length-1,4) == 1)
  //assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)

}

object scratch3 extends App{
  val a = Array(1)
  val b = a.drop(1)
  println(b)

}

import scala.math._
import scala.io.StdIn._

object C537{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,s.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,s.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Double = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree,Len) match {
      case (None,_) => A
      case (Some(tree), length) if length == 1 =>  powerTo1Shot(length, populationWhole, A, B)
      case (Some(tree),length) if length>=2 => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }

}

import scala.math._
import scala.io.StdIn._

object C537{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,tree.value+1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,s.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,s.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Int = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree,Len) match {
      case (None,_) => A
      case (Some(tree), length) if length == 1 =>  powerTo1Shot(length, populationWhole, A, B)
      case (Some(tree),length) if length>=2 => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }
  /*
  val n = 3
  val k = 2
  val A = 1
  val B = 2

  val indices = List(1,7)
  val Len = math.pow(2,n).toInt
  val populTree:Option[Tree]= populationTree(indices.toList,Len)
  val minPower = minimalPower(Len,populTree,A,B)
  println(populTree)
  println(minPower)
  */
}

import scala.math._
import scala.io.StdIn._

object C537{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,binaryString.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,binaryString.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Double = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree,Len) match {
      case (None,_) => A
      case (Some(tree), length) if length == 1 =>  powerTo1Shot(length, populationWhole, A, B)
      case (Some(tree),length) if length>=2 => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }

  val n = 2
  val k = 2
  val A = 1
  val B = 2

  val indices = Array(1,3)

  val Len = math.pow(2,n).toInt
  val populTree:Option[Tree]= populationTree(indices.toList,Len)

  val minPower = minimalPower(Len,populTree,A,B)
  //println(populTree.get.value)

  println(minPower)
  println(growTree(Some(Tree(None,None,0)),"11"))

}

object scratch extends App{
  println("ok")

}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def howManySmaller(a: Array[Int], left:Int, right:Int, n:Long): Int = {
    //to not get out of bounds error
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => a.length //if right is smaller, everything is
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => howManySmaller(a, left, mid, n)
      case (le, mi, _) if mi <= n => howManySmaller(a, mid, right, n)
    }
  }

  def minimalPower2(Len: Long, indicesSorted:Array[Int], A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length
    val mid = Len / 2
    val populationLeft = if(indicesSorted.length >0) {
      howManySmaller(indicesSorted, 0, indicesSorted.length, mid)
    }else{
      0
    }
      val minPow = (populationWhole, Len,indicesSorted.length) match {
      //case (0, length,_) if length == 0 => 0
        case (0,_,_) => A
      case (0, length,_) if length > 0 => {
        println(s"A: ${length}")
        A
      }
      case (_, length,_) if length == 1 => {
        println(s"popul ${populationWhole}")
        println(s"len ${length}")
        println(s"A ${A}")
        println(s"B ${B}")
        println(s"powTo1Shot ${powerTo1Shot(populationWhole, length, A, B)} ")
        println("jeb")
        powerTo1Shot(populationWhole, length, A, B)}
      case (_, length,_) if length >= 2 => {
        val aa = indicesSorted.take(populationLeft)
        aa.foreach(x=>println(s"${x}, a"))
        val bb = indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt)
        aa.foreach(x=>println(s"${x}, b"))
        indicesSorted.take(populationLeft)
        min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(Len / 2, indicesSorted.take(populationLeft), A, B) + minimalPower2(Len / 2, indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt), A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val Len = math.pow(2, n).toLong
    //val populTree: Option[Tree] = populationTree(indices, n,Len)
    //val minPower = minimalPower(Len, populTree, A, B)
    val minPower = minimalPower2(Len,indices,A,B)
    println(minPower)
  }

}
/*
object test extends App{
  import C537v2._

val n = 3
val k = 2
val A = 1
val B = 2

val indices = Array(1,7)

/*
val n = 30
val k = 10000
val A = 78
val B = 9765
*/
  //val indices = List(1,3)
val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(1000)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(Len,indices,A,B)
val t4 = System.nanoTime()

  //println(minPower)
  //println(minPower2)
  println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  println(s"rest: ${(t3-t2)*1.0/1e9}")
  println(s"whole ${(t3-t1)*1.0/1e9}")
  println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  println(minimalPower2(8,Array(1,7),1,2))
  //println(minimalPower2(8,Array(1,1),1,2))

}

object scratch2 extends App{

  def findFirstLarger(a: Array[Int],left:Int,right:Int, n:Long): Int = {
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => -1
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => findFirstLarger(a, left, mid, n)
      case (le, mi, _) if mi <= n => findFirstLarger(a, mid, right, n)
    }
  }
 //println(findFirstLarger(Array(1,7),0,2,4))
  /*
  println(findFirstLarger(a,0,a.length-1,4))
  assert(findFirstLarger(Array(1,2,3,5,6,7),0,a.length-1,4)==3)
  assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  assert(findFirstLarger(Array(1,8),0,a.length-1,4) == 1)
  //assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  */
}

object scratch3 extends App{
  val a1 = Array(1,7)
  val a2 = a1.take(1)
  val a3 = a1.drop(1)
  a2.length
  a3.length
  println(a2(0))
  println(a3(0))

}
*/

import scala.math._
import scala.io.StdIn._

object C537{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,tree.value+1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,s.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,s.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Double = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree,Len) match {
      case (None,_) => A
      case (Some(tree), length) if length == 1 =>  powerTo1Shot(length, populationWhole, A, B)
      case (Some(tree),length) if length>=2 => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }
  /*
  val n = 2
  val k = 2
  val A = 1
  val B = 2

  val indices = List(1,1)
  val Len = math.pow(2,n).toInt
  val populTree:Option[Tree]= populationTree(indices.toList,Len)
  val minPower = minimalPower(Len,populTree,A,B)
  println(populTree)
  println(minPower)
  */
}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {
  //find first index greater or equal to n
  //return array length if no such index exists
  //search range is [start,end)
  def binsearch(a:Array[Int],start:Int,end:Int,n:Long):Int={
    assert(end>start,"end should be bigger index than start")
    if(end-start>=2) {
      var s = start
      var e = end
      var m = (start + end) / 2

      while (s < m) {
        ((a(m) < n)) match {
          case true => {s = m}
          case false => e = m
        }
        m = (s + e) / 2
      }

      m+1
    }else{
      (a(start)<n)match{
        case true => end
        case false => start
      }
    }
  }

  def howManySmaller(sortedArray:Array[Int],range:(Int,Int),n:Long)={
    //println(s"array in binsearch ${sortedArray.mkString(",")}")
    //println(s"range ${range}")
    //println(s"range ${range}")
    //println(s"${n}")
    val j = binsearch(sortedArray,range._1,range._2,n)
    j - range._1
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }
  //(start,end) - range of sortedIndices, with indices that reside in baseRange
  //populOnTheLeft - how many indices there is on the left from baseRange
  case class PopulationInfo(start:Int,end:Int,populOnTheLeft:Int)
  case class Parameters(A:Int,B:Int,popul:Int)

  def minPower3(baseRange:(Long,Long),
                sortedIndices:Array[Int],
                populData:PopulationInfo,
                p:Parameters
               ):Long={
    assert(baseRange._2-baseRange._1>=1,"base range lower than 1")

    val population = p.popul

    ((baseRange._2-baseRange._1,population)) match {
      case (length, pop) if length == 1 => powerTo1Shot(pop, length, p.A, p.B)
      case (length, 0) if length >= 1 => p.A
      case (length, pop) if length >= 2 => {
        val leftHalfBase = (baseRange._1,(baseRange._1+length/2))
        val rightHalfBase = (baseRange._1+length/2,baseRange._2)
        val breakPoint = binsearch(sortedIndices,populData.start,populData.end,baseRange._1+length/2)
        val populationLeft = breakPoint - populData.populOnTheLeft//ok
        val populationRight = pop - populationLeft
/*
        println(s"total pop ${p.popul}")
        println(sortedIndices.mkString(","))
        println(baseRange)
        println(s"breakPoint ${breakPoint}")
        println(s"popul on the left ${populData.populOnTheLeft}")
        println(s"ppopuleft ${populationLeft}")
        println(s"ppopulright ${populationRight}")
        println(s"---NEXT----")
*/
        val popDataL = PopulationInfo(populData.start, breakPoint, populData.populOnTheLeft)
        val popDataR = PopulationInfo(breakPoint, populData.end, populData.populOnTheLeft+populationLeft)

        min(
          powerTo1Shot(pop, length, p.A, p.B),
          minPower3(leftHalfBase,sortedIndices,popDataL,Parameters(p.A,p.B,populationLeft))+
          minPower3(rightHalfBase,sortedIndices,popDataR,Parameters(p.A,p.B,populationRight))
        )
      }
    }
    }

  def minPowerMain(n:Int,indices:Array[Int],A:Int,B:Int,k:Int):Long ={
    assert(indices.length==k)
    val baseRange = (0.toLong, math.pow(2,n).toLong)
    val indicesSorted = indices.sorted.map(_-1)
    val popInfo = PopulationInfo(0,k,0)

    val p = Parameters(A,B,k)
    minPower3(baseRange,indicesSorted,popInfo,p)
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val minPower = minPowerMain(n,indices, A, B, k)
    println(minPower)
  }

}

object test extends App{
  import C537v2._
  def runTests()= {
    println(howManySmaller(Array(1),(0,1),2)==1)
    println(howManySmaller(Array(1),(0,1),0)==0)
    println(howManySmaller(Array(0,1,2,3,4,5),(2,5),4)==2)
    println(howManySmaller(Array(0,1,2,3,4,5),(3,4),4)==1)
    println(howManySmaller(Array(0,1,2,3,4,5),(0,6),7)==6)
    println(howManySmaller(Array(0,1,2,3,4,5),(0,6),4)==4)
  }
  runTests()

/*
val n = 30
val k = 88704
val A = 1
val B = 2140
val Len = math.pow(2,n).toInt
  //val indices = List(1,3)
//val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(198987)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len)).sorted
val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len)+1).map(_-1)
  //indices.sorted.foreach(print)
  //println("\n--------------------")
//val indices = Array(858,765)
//val indices = Array(858,765)

  val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
val t4 = System.nanoTime()
  val minPower2 = minimalPower2(indicesSorted, 0, Len, A, B,(0,k))
val t5 = System.nanoTime()

  println(minPower)
  println(minPower2)
  println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  println(s"rest: ${(t3-t2)*1.0/1e9}")
  println(s"whole ${(t3-t1)*1.0/1e9}")
  println(s"sorting ${(t4-t3)*1.0/1e9}")
  println(s"bin search ${(t5-t4)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  //println(minimalPower2(Array(1,7), 0, 8, 1, 2))
  //println(minimalPower2(8,Array(1,1),1,2))
  //println(minimalPower2(8,Array(1,1),1,2))

*/
}

object scratch3 extends App{
  import C537v2._
  //testing howManySmaller3, get left, right ranges for population table
  val A = Array(3,3,5,7).sorted
  val r = 2
  //println(howManySmaller3(A,(0,4),r))
  //testing minPower3

  val sortedIndices = Array(1,3)
  val p = Parameters(1,2,sortedIndices.length)
  val baseRange = (0l,4l)
  val populData = PopulationInfo(0,4,0)
  /*
  val baseRange = (0l,4l)
  val populData = PopulationInfo(0,4,0)
  */
  /*
  val baseRange = (0l,2l)
  val populData = PopulationInfo(0,3,0)
  */

  //println(minPower3(baseRange,sortedIndices,populData,p))
  //println(s"minPowL${minPower3(leftHalfBase,sortedIndices,popDataL,p)}")
  println(minPowerMain(2,Array(1,1,1),A=1,B=2,k=3)==8)
  println(minPowerMain(2,Array(1,2),A=1,B=2,k=2)==5)
  println(minPowerMain(2,Array(1,3),A=1,B=2,k=2)==6)
  println(minPowerMain(3,Array(1,7),A=1,B=2,k=2)==8)

  //println(s"minPowLL${minPower3((0,2),sortedIndices,PopulationInfo(0,3,0),p)}")

}

object testttt extends App{
  val a = Array(1,2,3)
  println(a.take(2).length)
}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def findFirstLarger(a: Array[Int],left:Int,right:Int, n:Long): Int = {
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => -1
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => findFirstLarger(a, left, mid, n)
      case (le, mi, _) if mi <= n => findFirstLarger(a, mid, right, n)
    }
  }

  def minimalPower2(Len: Long, indicesSorted:Array[Int], A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length
    val mid = Len / 2
    val populationLeft = if(indicesSorted.length >0) {
      math.max(findFirstLarger(indicesSorted, 0, indicesSorted.length, mid),0)
    }else{
      0
    }
      val minPow = (populationWhole, Len,indicesSorted.length) match {
      //case (0, length,_) if length == 0 => 0
        case (0,_,_) => A
      case (0, length,_) if length > 0 => A
      case (_, length,_) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (_, length,_) if length >= 2 => {
        min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(Len / 2, indicesSorted.take(populationLeft), A, B) + minimalPower2(Len / 2, indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt), A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val Len = math.pow(2, n).toLong
    //val populTree: Option[Tree] = populationTree(indices, n,Len)
    //val minPower = minimalPower(Len, populTree, A, B)
    val minPower = minimalPower2(Len,indices,A,B)
    println(minPower)
  }

}

object test extends App{
  import C537v2._
/*
val n = 3
val k = 2
val A = 1
val B = 2
*/
//val indices = Array(1,7)

val n = 30
val k = 10000
val A = 78
val B = 9765

  //val indices = List(1,3)
val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(1000)
val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(Len,indices,A,B)
val t4 = System.nanoTime()

  //println(minPower)
  //println(minPower2)
  println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  println(s"rest: ${(t3-t2)*1.0/1e9}")
  println(s"whole ${(t3-t1)*1.0/1e9}")
  println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  println(minimalPower2(8,Array(1,7),1,2))

}

object scratch2 extends App{

  def findFirstLarger(a: Array[Int],left:Int,right:Int, n:Long): Int = {
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => -1
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => findFirstLarger(a, left, mid, n)
      case (le, mi, _) if mi <= n => findFirstLarger(a, mid, right, n)
    }
  }
 println(findFirstLarger(Array(1,7),0,2,4))
  /*
  println(findFirstLarger(a,0,a.length-1,4))
  assert(findFirstLarger(Array(1,2,3,5,6,7),0,a.length-1,4)==3)
  assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  assert(findFirstLarger(Array(1,8),0,a.length-1,4) == 1)
  //assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  */
}

object scratch3 extends App{
  val a1 = Array(1,7)
  val a2 = a1.take(1)
  val a3 = a1.drop(1)
  a2.length
  a3.length
  println(a2(0))
  println(a3(0))

}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def howManySmaller(a: Array[Int], n: Long): Int = {
    if(a.length >= 2){
      var start = 0
      var end = a.length-1

      var loopGuard = 0
      if(a(end)<n){
        end+1
      }else if(a(start)>=n){0} else {
        while (end - start >= 2 && loopGuard < 1e10) {
          val mid = (start + end) / 2
          if (a(mid) < n) {
            start = mid
          } else {
            end = mid
          }
          loopGuard = loopGuard + 1
        }
        end
      }

    } else if(a.length == 1){
      if(a(0)<=n){1}else{0}
    }else{
      0
    }
  }

  def minimalPower2(indicesSorted: Array[Int], start: Long, Len: Long, A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length

    val mid = start + Len / 2

      val minPow = (populationWhole, Len,indicesSorted.length) match {
        //case (_, 0,_) => 0
        case (0, length,_) if length>=1 => A
        case (_, length,_)if length==1 => powerTo1Shot(populationWhole, length, A, B)
      case (_, length,_) if length>=2 => {
        val breakPoint = howManySmaller(indicesSorted, mid)

        //println("--ss---")
        //indicesSorted.foreach(print)
        //print("\n")
        //println(s"mid ${mid}")
        //println(s"break point ${breakPoint}")

        //println("-----")
        val indicesLeft = indicesSorted.take(breakPoint)
        val indicesRight = indicesSorted.drop(breakPoint)
        //println(s"powLeft: ${minimalPower2(indicesLeft, start, Len / 2, A, B)}")
        //println(s"powRight: ${minimalPower2(indicesRight, start, Len / 2, A, B)}")

        min(

        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(indicesLeft, start, Len / 2, A, B) +
          minimalPower2(indicesRight,start+Len/2 , Len / 2, A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ")
      .map(_.toInt)
      .map(_-1) // so that they are in the range 0 to 2^n-1

    val Len = math.pow(2, n).toLong
    val populTree: Option[Tree] = populationTree(indices, n,Len)
    val minPower = minimalPower(Len, populTree, A, B)
    //val minPower = minimalPower2(indices, 0, Len, A, B)
    println(minPower)
  }

}

object test extends App{
  import C537v2._

val n = 30
val k = 100000
val A = 5
val B = 2089
val Len = math.pow(2,n).toInt
  //val indices = List(1,3)
//val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(19907)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len)).sorted
val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len/2)+math.pow(2,29).toInt)
  //indices.foreach(println)
  //println("--------------------")
//val indices = Array(858,765)
//val indices = Array(858,765)

  val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(indicesSorted.map(_-1), 0, Len, A, B)
val t4 = System.nanoTime()

  println(minPower)
  println(minPower2)
  //println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  //println(s"rest: ${(t3-t2)*1.0/1e9}")
  //println(s"whole ${(t3-t1)*1.0/1e9}")
  //println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  //println(minimalPower2(Array(1,7), 0, 8, 1, 2))
  //println(minimalPower2(8,Array(1,1),1,2))

}

object scratch3 extends App{
  import C537v2._

  val a = Array(0,1,1,2)
  val len = 4
  val breakPoint = howManySmaller(a, 1l)
  println(howManySmaller(Array(0,1,1,2), 1l)==3)
  println(howManySmaller(Array(0,1,1,2), 2l))
  println(howManySmaller(Array(0,1,1,2), 2l))
  println(minimalPower2(Array(0,1,1,2,3), 0, 4, 1, 2))
  println(minimalPower2(Array(5,7), 4, 4, 1, 2))
}

object testttt extends App{
  val a = Array(1,2,3)
  println(a.take(2).length)
}

import scala.math._
import scala.io.StdIn._

object C537{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,binaryString.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,binaryString.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Double = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree,Len) match {
      case (None,_) => A
      case (Some(tree), length) if length == 1 =>  powerTo1Shot(length, populationWhole, A, B)
      case (Some(tree),length) if length>=2 => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }

}

import scala.math._
import scala.io.StdIn._

object C537 extends App{

  case class Tree(left: Option[Tree], right: Option[Tree], value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T,binaryString) match {
      case (None,"") => Some(Tree(None,None,1))
      case (Some(tree),"") => Some(Tree(None,None,tree.value+1)) //??
      case (None,s) if s(0) == '0' => Some(Tree(growTree(None,s.tail), None, 1))
      case (None,s) if s(0) == '1' => Some(Tree(None, growTree(None,s.tail), 1))
      case (Some(tree),s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right,tree.value +1))
      case (Some(tree),s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail),tree.value +1))
    }
  }

  def populationTree(indices: List[Int],Len:Int): Option[Tree] = {
    val indices2binary = indices.map(_-1).map(_+Len).map(_.toBinaryString.tail)
    indices2binary.foldLeft[Option[Tree]](Some(Tree(None,None,0)))((T:Option[Tree], binStr) => growTree(T, binStr))
  }

  def powerTo1Shot(population: Int, Len: Int, A: Int, B: Int) = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Int, populationTree: Option[Tree], A: Int, B: Int): Double = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree,Len) match {
      case (None,_) => A
      case (Some(tree), length) if length == 1 =>  powerTo1Shot(length, populationWhole, A, B)
      case (Some(tree),length) if length>=2 => min(
        powerTo1Shot(Len, populationWhole, A, B),
        minimalPower(Len / 2, tree.left, A, B)+ minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }
/*
  def main(args: Array[String]) {
     val Array(n,k,a,b) = readLine.split(" ").map(_.toInt)
     val A = a
     val B = b
     val indices = readLine.split(" ").map(_.toInt)

     val Len = math.pow(2,n).toInt
     val populTree:Option[Tree]= populationTree(indices.toList,Len)
     val minPower = minimalPower(Len,populTree,A,B)
     println(minPower)
  }
*/
  val n = 2
  val k = 2
  val A = 1
  val B = 2

  val indices = List(1,1)
  val Len = math.pow(2,n).toInt
  val populTree:Option[Tree]= populationTree(indices.toList,Len)
  val minPower = minimalPower(Len,populTree,A,B)
  println(populTree)
  println(minPower)
}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def howManySmaller(a: Array[Int], left:Int, right:Int, n:Long): Int = {
    //to not get out of bounds error
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => a.length //if right is smaller, everything is
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => howManySmaller(a, left, mid, n)
      case (le, mi, _) if mi <= n => howManySmaller(a, mid, right, n)
    }
  }

  def minimalPower2(Len: Long, indicesSorted:Array[Int], A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length
    val mid = Len / 2
    val populationLeft = if(indicesSorted.length >0) {
      howManySmaller(indicesSorted, 0, indicesSorted.length, mid)
    }else{
      0
    }
      val minPow = (populationWhole, Len,indicesSorted.length) match {
      //case (0, length,_) if length == 0 => 0
        case (0,_,_) => A
      case (0, length,_) if length > 0 => {
        println(s"A: ${length}")
        A
      }
      case (_, length,_) if length == 1 => {
        println(s"popul ${populationWhole}")
        println(s"len ${length}")
        println(s"A ${A}")
        println(s"B ${B}")
        println(s"powTo1Shot ${powerTo1Shot(populationWhole, length, A, B)} ")
        println("jeb")
        powerTo1Shot(populationWhole, length, A, B)}
      case (_, length,_) if length >= 2 => {
        val aa = indicesSorted.take(populationLeft)
        aa.foreach(x=>println(s"${x}, a"))
        val bb = indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt)
        aa.foreach(x=>println(s"${x}, b"))
        indicesSorted.take(populationLeft)
        min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(Len / 2, indicesSorted.take(populationLeft), A, B) + minimalPower2(Len / 2, indicesSorted.drop(populationLeft).map(i=>(i-Len/2).toInt), A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ").map(_.toInt)

    val Len = math.pow(2, n).toLong
    //val populTree: Option[Tree] = populationTree(indices, n,Len)
    //val minPower = minimalPower(Len, populTree, A, B)
    val minPower = minimalPower2(Len,indices,A,B)
    println(minPower)
  }

}

object test extends App{
  import C537v2._
/*
val n = 3
val k = 2
val A = 1
val B = 2
*/
//val indices = Array(1,7)

val n = 30
val k = 10000
val A = 78
val B = 9765

  //val indices = List(1,3)
val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(1000)
val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(Len,indices,A,B)
val t4 = System.nanoTime()

  //println(minPower)
  //println(minPower2)
  println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  println(s"rest: ${(t3-t2)*1.0/1e9}")
  println(s"whole ${(t3-t1)*1.0/1e9}")
  println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  //println(minimalPower2(8,Array(1,7),1,2))
  println(minimalPower2(8,Array(1,1),1,2))

}

object scratch2 extends App{

  def findFirstLarger(a: Array[Int],left:Int,right:Int, n:Long): Int = {
    val right2 = if (right >= a.length) {
      a.length - 1
    } else {
      right
    }
    val mid = (left + right2) / 2

    (a(left), a(mid), a(right2)) match {
      case (le, mi, ri) if ri <= n => -1
      case (le, _, _) if le > n => left
      case (le, mi, _) if le == mi => right2
      case (le, mi, _) if mi > n => findFirstLarger(a, left, mid, n)
      case (le, mi, _) if mi <= n => findFirstLarger(a, mid, right, n)
    }
  }
 //println(findFirstLarger(Array(1,7),0,2,4))
  /*
  println(findFirstLarger(a,0,a.length-1,4))
  assert(findFirstLarger(Array(1,2,3,5,6,7),0,a.length-1,4)==3)
  assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  assert(findFirstLarger(Array(1,8),0,a.length-1,4) == 1)
  //assert(findFirstLarger(Array(1),0,a.length-1,4) == -1)
  */
}

object scratch3 extends App{
  val a1 = Array(1,7)
  val a2 = a1.take(1)
  val a3 = a1.drop(1)
  a2.length
  a3.length
  println(a2(0))
  println(a3(0))

}

import scala.io.StdIn.readLine
import scala.math.min

object C537v2 {

  case class Tree(var left: Option[Tree], var right: Option[Tree], var value: Int) {
    def leftValOrElse(default: Int): Int = {
      left match {
        case None => default
        case Some(tree) => tree.value
      }
    }

    def rightValOrElse(default: Int) = {
      right match {
        case None => default
        case Some(tree) => tree.value
      }
    }
  }

  /*
  def growTree(T: Option[Tree], binaryString: String): Option[Tree] = {
    (T, binaryString) match {
      case (None, "") => Some(Tree(None, None, 1))
      case (Some(tree), "") => Some(Tree(None, None, tree.value + 1)) //??
      case (None, s) if s(0) == '0' => Some(Tree(growTree(None, s.tail), None, 1))
      case (None, s) if s(0) == '1' => Some(Tree(None, growTree(None, s.tail), 1))
      case (Some(tree), s) if s(0) == '0' => Some(Tree(growTree(tree.left, s.tail), tree.right, tree.value + 1))
      case (Some(tree), s) if s(0) == '1' => Some(Tree(tree.left, growTree(tree.right, s.tail), tree.value + 1))
    }
  }
  */
  def growTree(T: Option[Tree], position: Long, binaryRepresentationLen: Int,Len:Long): Option[Tree] = {
    val firstDigit = position >>> (binaryRepresentationLen-1) & 1
    val otherDigits = position & (Len-1) //sets first bit to 0

    (T, firstDigit,binaryRepresentationLen) match {
      case (None, _,0) => Some(Tree(None, None, 1))
      case (Some(tree), _,0) => Some(Tree(None, None, tree.value + 1)) //??
      case (None, d,_) if d == 0 => Some(Tree(growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), None, 1))
      case (None, d,_) if d == 1 => Some(Tree(None, growTree(None, otherDigits,binaryRepresentationLen-1,Len/2), 1))
      case (Some(tree), d,_) if d == 0 => Some(Tree(growTree(tree.left, otherDigits,binaryRepresentationLen-1,Len/2), tree.right, tree.value + 1))
      case (Some(tree), d,_) if d == 1 => Some(Tree(tree.left, growTree(tree.right, otherDigits,binaryRepresentationLen-1,Len/2), tree.value + 1))
    }
  }

  def populationTree(indices: Array[Int], binaryRepLen:Int ,Len: Long): Option[Tree] = {
    //indices.map(_ - 1).foldLeft[Option[Tree]](Some(Tree(None, None, 0)))((T: Option[Tree], pos) => growTree(T, pos,binaryRepLen,Len))

    var i = 0
    var T:Option[Tree] = Some(Tree(None, None, 0))
    while(i<indices.length){
      T = growTree(T, indices(i)-1,binaryRepLen,Len)
      i=i+1
    }
    T
  }

  def powerTo1Shot(population: Int, Len: Long, A: Int, B: Int): Long = {
    population match {
      case 0 => A
      case na if na > 0 => na * Len * B
    }
  }

  def minimalPower(Len: Long, populationTree: Option[Tree], A: Int, B: Int): Long = {
    val populationWhole = populationTree match {
      case None => 0
      case Some(tree) => tree.value
    }

    val minPow = (populationTree, Len) match {
      case (None, _) => A
      case (Some(tree), length) if length == 1 => powerTo1Shot(populationWhole, length, A, B)
      case (Some(tree), length) if length >= 2 => min(
        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower(Len / 2, tree.left, A, B) + minimalPower(Len / 2, tree.right, A, B)
      )
    }
    //println(minPow)
    minPow

  }

  def howManySmaller(a: Array[Int], n: Long): Int = {
    if(a.length >= 2){
      var start = 0
      var end = a.length-1

      var loopGuard = 0
      if(a(end)<n){
        end+1
      }else if(a(start)>=n){0} else {
        while (end - start >= 2 && loopGuard < 1e10) {
          val mid = (start + end) / 2
          if (a(mid) < n) {
            start = mid
          } else {
            end = mid
          }
          loopGuard = loopGuard + 1
        }
        end
      }

    } else if(a.length == 1){
      if(a(0)<=n){1}else{0}
    }else{
      0
    }
  }

  def minimalPower2(indicesSorted: Array[Int], start: Long, Len: Long, A: Int, B: Int): Long = {

    val populationWhole = indicesSorted.length

    val mid = start + Len / 2

      val minPow = (populationWhole, Len,indicesSorted.length) match {
        //case (_, 0,_) => 0
        case (0, length,_) if length>=1 => A
        case (_, length,_)if length==1 => powerTo1Shot(populationWhole, length, A, B)
      case (_, length,_) if length>=2 => {
        val breakPoint = howManySmaller(indicesSorted, mid)

        //println("--ss---")
        //indicesSorted.foreach(print)
        //print("\n")
        //println(s"mid ${mid}")
        //println(s"break point ${breakPoint}")

        //println("-----")
        val indicesLeft = indicesSorted.take(breakPoint)
        val indicesRight = indicesSorted.drop(breakPoint)
        //println(s"powLeft: ${minimalPower2(indicesLeft, start, Len / 2, A, B)}")
        //println(s"powRight: ${minimalPower2(indicesRight, start, Len / 2, A, B)}")

        min(

        powerTo1Shot(populationWhole, Len, A, B),
        minimalPower2(indicesLeft, start, Len / 2, A, B) +
          minimalPower2(indicesRight,start+Len/2 , Len / 2, A, B)
      )
      }
    }
    //println(minPow)
    minPow
  }

  def main(args: Array[String]) {
    val Array(n, k, a, b) = readLine.split(" ").map(_.toInt)
    val A = a
    val B = b
    val indices = readLine.split(" ")
      .map(_.toInt)
      .map(_-1) // so that they are in the range 0 to 2^n-1

    val Len = math.pow(2, n).toLong
    //val populTree: Option[Tree] = populationTree(indices, n,Len)
    //val minPower = minimalPower(Len, populTree, A, B)
    val minPower = minimalPower2(indices, 0, Len, A, B)
    println(minPower)
  }

}

object test extends App{
  import C537v2._

val n = 20
val k = 700
val A = 19
val B = 278
val Len = math.pow(2,n).toInt
  //val indices = List(1,3)
//val Len = math.pow(2,n).toInt

val rnd =  new scala.util.Random(10067)
//val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len))
val indices = (1 to k).toArray.map(i=>rnd.nextInt(Len)+1).sorted
  //indices.foreach(println)
  //println("--------------------")
//val indices = Array(858,765)
//val indices = Array(858,765)

  val t1 = System.nanoTime()
  val populTree:Option[Tree]= populationTree(indices,n,Len)
  //indices.sorted
val t2 = System.nanoTime()
  val minPower = minimalPower(Len,populTree,A,B)
val t3  = System.nanoTime()
  val indicesSorted = indices.sorted
  val minPower2 = minimalPower2(indicesSorted.map(_-1), 0, Len, A, B)
val t4 = System.nanoTime()

  println(minPower)
  println(minPower2)
  //println(s"tree: ${(t2-t1)*1.0/1e9}, which is ${(t2-t1)*1.0/(t3-t1)} of total time")
  //println(s"rest: ${(t3-t2)*1.0/1e9}")
  //println(s"whole ${(t3-t1)*1.0/1e9}")
  //println(s"bin search ${(t4-t3)*1.0/1e9}")
  //println(minimalPower2(4,Array(1),1,2))
  //println(minimalPower2(4,Array(3),1,2))
  //println(powerTo1Shot(2,8,1,2))
  //println(minimalPower2(Array(1,7), 0, 8, 1, 2))
  //println(minimalPower2(8,Array(1,1),1,2))

}

object scratch3 extends App{
  import C537v2._

  val a = Array(0,1,1,2)
  val len = 4
  val breakPoint = howManySmaller(a, 1l)
  println(howManySmaller(Array(0,1,1,2), 1l)==3)
  println(howManySmaller(Array(0,1,1,2), 2l))
  println(howManySmaller(Array(0,1,1,2), 2l))
  println(minimalPower2(Array(0,1,1,2,3), 0, 4, 1, 2))
  println(minimalPower2(Array(5,7), 4, 4, 1, 2))
}

object testttt extends App{
  val a = Array(1,2,3)
  println(a.take(2).length)
}


You are given a 4x4 grid. You play a game — there is a sequence of tiles, each of them is either 2x1 or 1x2. Your task is to consequently place all tiles from the given sequence in the grid. When tile is placed, each cell which is located in fully occupied row or column is deleted (cells are deleted at the same time independently). You can place tile in the grid at any position, the only condition is that tiles (and tile parts) should not overlap. Your goal is to proceed all given figures and avoid crossing at any time.

The only line contains a string $$$s$$$ consisting of zeroes and ones ($$$1 \le |s| \le 1000$$$). Zero describes vertical tile, one describes horizontal tile.

Output $$$|s|$$$ lines — for each tile you should output two positive integers $$$r,c$$$, not exceeding $$$4$$$, representing numbers of smallest row and column intersecting with it. If there exist multiple solutions, print any of them.

NoteFollowing image illustrates the example after placing all three tiles:    Then the first row is deleted:

object Main {
  def main(args: Array[String]): Unit = {
    val s = new Main()
    s.solve()
    s.out.flush()
  }
}

class Main {
  import java.io._
  import java.util.StringTokenizer

  import scala.collection.mutable
  import scala.util.Sorting
  import math.{abs, max, min}
  import mutable.{ArrayBuffer, ListBuffer}
  import scala.reflect.ClassTag

  val MOD = 1000000007
  val out = new PrintWriter(System.out)

  def solve(): Unit = {
    val S = ns().map(_ == '0') // true == vertical
    var v = false
    var h = false
    REP(S.length) { i =>
      if (S(i)) {
        if (v) {
          out.println("3 1")
          v = false
        } else {
          out.println("1 1")
          v = true
        }
      } else {
        if (h) {
          out.println("4 1")
          h = false
        } else {
          out.println("4 3")
          h = true
        }
      }
    }
  }

  def debug(as: Array[Boolean]): Unit = {
    System.err.println(as.map(x => if(x) "1" else "0").mkString)
  }

  def debug(as: Array[Int]): Unit = {
    System.err.println(as.mkString(" "))
  }

  def debug(as: Array[Long]): Unit = {
    System.err.println(as.mkString(" "))
  }

  def debug(s: String): Unit = {
    System.err.println(s)
  }

  class InputReader(val stream: InputStream) {
    private val reader = new BufferedReader(new InputStreamReader(stream), 32768)
    private var tokenizer: StringTokenizer = _

    def next(): String = {
      while (tokenizer == null || !tokenizer.hasMoreTokens)
        tokenizer = new StringTokenizer(reader.readLine)
      tokenizer.nextToken
    }

    def nextInt(): Int = next().toInt
    def nextLong(): Long = next().toLong
    def nextChar(): Char = next().charAt(0)
  }
  val sc = new InputReader(System.in)
  def ni(): Int = sc.nextInt()
  def nl(): Long = sc.nextLong()
  def nc(): Char = sc.nextChar()
  def ns(): String = sc.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 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]) = {
    val cum = Array.ofDim[Long](as.length + 1)
    REP(as.length) { i =>
      cum(i + 1) = cum(i) + as(i)
    }
    cum
  }
}

object Main {

  def main(args: Array[String]) {
    val std = scala.io.StdIn

    val n = std.readLine()

    var hasVert = false
    var hasHor = false
    for (i <- 0 until n.length) {
      n(i) match {
        case '0' if hasVert =>
          hasVert = false
          println(3 + " " + 1)
        case '0' =>
          hasVert = true
          println(1 + " " + 1)
        case '1' if hasHor =>
          hasHor = false
          println(4 + " " + 1)
        case '1' =>
          hasHor = true
          println(4 + " " + 3)
      }
    }
  }
}