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, 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
  }
}

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)
}


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)
      }
    }
  }
}