object Taxi {
	var availableCars = collection.mutable.Map[Int,Int]((1,0), (2,0), (3,0))

			def addCar (index: Int) {
		availableCars += index -> (availableCars(index) + 1)
	}

	def removeCar (index: Int) {
		availableCars += index -> (availableCars(index) - 1)
	}

	def main (args: Array[String]) {
		val scanner = new java.util.Scanner(System.in)
				val n = scanner.nextInt
				var number = 0
				for (i <- 1 to n) {
					val current = scanner.nextInt
							current match {
							case 4 =>
							number = number + 1
							case 3 =>
							if (availableCars(1) > 0) {
								removeCar(1)
								number = number + 1
							}
							else {
								addCar(3)
							}
							case 2 =>
							if (availableCars(2) > 0) {
								removeCar(2)
								number = number + 1
							}
							else {
								addCar(2)
							}
							case 1 =>
							if (availableCars(3) > 0) {
								removeCar(3)
								number = number + 1
							}
							else {
								addCar(1)
							}
					}
				}

		while (availableCars(3) > 0 && availableCars(1) > 0) {
			number = number + 1
					removeCar(3)
					removeCar(1)
		}
		while (availableCars(2) > 1) {
			val div2 = availableCars(2) / 2
					number = number + div2
					availableCars += 2 -> availableCars(2) % 2
		}
		if (availableCars(2) == 1) {
			removeCar(2)
			if (availableCars(1) >= 2) {
				removeCar(1)
				removeCar(1)
			}
			else {
				availableCars += 1 -> 0
			}
			number = number + 1
		}

		number = number + availableCars(1) / 4
		availableCars += 1 -> availableCars(1) % 4
				if (availableCars(1) > 0)
				{
				  number = number + 1
				  availableCars += 1 -> 0

				}
/**
				println("------------")
				println("number: "+number)
				println("availableCars: "+availableCars)
				println("------------")
		**/
				println(number+availableCars(3)+availableCars(2)+availableCars(1))
	}
}

import java.util.Scanner
import java.io.PrintWriter
import scala.annotation.tailrec
import scala.collection.mutable
import scala.util.Random

object P158B extends App {
  val sc = new Scanner(System.in)
  val out = new PrintWriter(System.out)

  val N = sc.nextInt
  val g = Array.fill(5)(0)
  val s = List.fill(N)(sc.nextInt)
  s foreach (g(_) += 1)

  var t = g(4) + g(3)
  g(1) -= g(3)
  t += g(2) / 2
  if (g(2) % 2 == 1) {
    t += 1
    g(1) -= 2
  }
  if (g(1) > 0) t += (g(1) - 1) / 4 + 1

  out.println(t)
  out.close
}

import java.util.Scanner

object R158_B extends App {
  val sc = new Scanner(System.in)

  val n = sc.nextInt()
  val groups = for(i <- 0 until n) yield sc.nextInt()

  println(process(groups))

  def process(groups:Seq[Int]):Int = {
    var a = new Array[Int](4)
    groups.foreach(g => {
      val k = g-1
      a(k)=a(k)+1
    })
    var c = 0
    c += a(3)
    c += a(2)
    if(a(2)<a(0)){
      a(0)=a(0)-a(2)
    }else{
      a(0)=0
    }
    c += a(1)/2
    if(a(1)%2==1){
      c += 1
      if(a(0)>2){
        a(0)=a(0)-2
      }else{
        a(0)=0
      }
    }
    c += (a(0)+3)/4
    c
  }
}

import java.util.Scanner

object B {
  val in = new Scanner(System.in)

  def main(args: Array[String]) {
    val n = in.nextInt()
    val s = Array.fill[Int](n)(in.nextInt())
    val count = Array.ofDim[Int](5)
    s.foreach((x) => count(x) += 1)
    var result = 0;
    result += count(4)
    result += count(3)
    count(1) = (count(1) - count(3)) max 0
    result += (2 * count(2) + count(1) + 3) / 4
    println(result)
  }
}

// CodeForces 158 B

object Taxi extends App {
  val ln0 = (Console.readLine()).split(" ") map (_.toInt)
  val n = ln0(0)
  val s = (Console.readLine()).split(" ") map (_.toInt)
  var nga:Array[Int] = Array.fill(5)(0)  // numbers of Taxi with given number of

  def countgroups():Unit = {
    for (val i <- 0 until n) {
      nga(s(i)) = nga(s(i)) + 1
    }
  }

  countgroups()
  var nt = nga(4)
  nt = nt + nga(3)
  if (nga(1) > nga(3)) {
    nga(1) = nga(1) - nga(3)
  } else {
    nga(1) = 0
  }
  val n1 = nga(1) + 2*nga(2)
  val n4 = n1/4
  nt = nt + n4
  if (n1 > n4*4) {
    nt = nt+1
  }
  println(nt)
}

object Taxi extends App {
  import java.util.{Scanner => Input}

  val in = new Input(System.in)
  val n = in nextInt
  val count = new Array[Int](5)
  for (i <- 1 to n)
    count(in nextInt) += 1

  var ans = count(4)

  def min = (x:Int, y:Int) => if (x < y) x else y

  ans += count(3)
  count(1) -= min(count(3), count(1))

  ans += count(2) / 2
  if (count(2) % 2 == 1) {
    ans += 1
    count(1) -= min(2, count(1))
  }

  ans += (count(1) + 3) / 4

  println(ans)
}

object Codeforces158B extends App{

  def TaxiNumber(ques:String):Int={
    var ans:Int=0
    val conv=ques.split(" ").map(_.toInt)
    var numset:Array[Int]=Array(0,0,0,0,0)
    for (i <- conv){
      numset(i)+=1
    }
    ans+=numset(4)
    if (numset(3)<=numset(1)){
      ans+=numset(3)
      var temp=numset(1)-numset(3)
      if (numset(2)%2==0){
        ans+=numset(2)/2
        ans+=temp/4
        if (temp%4!=0){
          ans+=1
        }
      }
      else{
        ans+=numset(2)/2+1
        temp-=2
        if (temp>0){
          ans+=temp/4
          if (temp%4!=0){
            ans+=1
          }
        }
      }
    }
    else{
      ans+=numset(3)
      ans+=numset(2)/2
      if (numset(2)%2==1){
        ans+=1
      }
    }
    return ans
  }

  val s:Int=scala.io.StdIn.readInt
  val k=scala.io.StdIn.readLine
  println(TaxiNumber(k))

}

import java.io._

object Easy {
  val reader = new BufferedReader(new InputStreamReader(System.in))
  def readInts = reader.readLine().split(" ").map(_.toInt)
  def main(args: Array[String]) {
    reader.readLine()
    val cnt = readInts.groupBy(x => x).mapValues(_.length)
    def c(x: Int) = cnt.getOrElse(x, 0)
    def ceil(a: Int, b: Int) = if (a % b == 0) a / b else a / b + 1
    println(c(4) + c(3) + c(2) / 2 + c(2) % 2 + ceil(Math.max(0, c(1) - c(3) - 2 * (c(2) % 2)), 4))
  }
}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val fTwo = counts(2) / 2

  val twoLeft = counts(2) * 2 % 4

  //четверки собранны
  val fFour = counts(4)

  //число скомбенированные 3 и 1
  val (fThreeOne, left:(Int, Int)) = if (counts(3) == counts(1)) (counts(3), (0, 0)) else {
    val min = counts(3).min(counts(1))
    (min, (Map(3 -> counts(3), 1 -> counts(1)).maxBy(_._2)._1, Math.abs(counts(3) - counts(1))))
  }
//  println(left)

  // комбинируем 2 с 1
  val (fTwoOne:Int, left1:(Int, Int)) = if (twoLeft != 0)  left match {

    case (0, 0) => (1, left)
    case (num: Int, count: Int) if num == 3 => (1, left)
    case (num: Int, count: Int) if num == 1 => if (count >= 2) (1, (num, count - 2)) else (1,(0, 0))

  } else (0, left)

  val fLeft = if (left1._1 == 3)  left1._2 else {
    if (left1._2 < 4 && left1._2 != 0) {
      1
    } else if (left1._2 == 0) {
      0
    } else {
      val modQ = if (left1._2 % 4 == 0) 0 else 1
      left1._2 / 4 + modQ
    }
  }
  println(fTwo + fFour + fLeft + fThreeOne + fTwoOne)

}

import scala.util.Sorting

object _158B extends App
{
  val n = readLine().toInt
  var fours = 0
  var threes = 0
  var twos = 0
  var ones = 0
  val groups = (readLine().split(" ") map (_.toInt)) foreach (x =>
  x match {
    case 4 => fours += 1
    case 3 => threes += 1
    case 2 => twos += 1
    case 1 => ones += 1
    case _ => println(x)
  })
  //println(fours + " " + threes + " " + twos + " " + ones)
  var ans = fours

  while (threes > 0) {
    if (ones > 0) {
      ans += 1
      threes -= 1
      ones -= 1
    } else {
      ans += 1
      threes -= 1
    }
  }

  while (twos > 0) {
    if (twos >= 2) {
      twos -= 2
      ans += 1
    } else if (ones >= 2) {
      twos -= 1
      ones -= 2
      ans += 1
    } else {
      twos -= 1
      if (ones >= 1)
        ones -= 1
      ans += 1
    }
  }

  while (ones >= 4) {
    ans += 1
    ones -= 4
  }
  if (ones > 0) {
    ans += 1
  }

  println(ans)
}

object Main {
  def main(args: Array[String]) {
    val n = readInt()
    val arr = readLine().split(" ").map(_.toInt)
    var g1, g2, g3, g4 = 0
    arr.foreach{
      case 1 => g1 += 1
      case 2 => g2 += 1
      case 3 => g3 += 1
      case 4 => g4 += 1
    }
    var ga = g4 + g3 + ((g2 + 1) / 2) + (((g1 - g3 - 2 * (g2 % 2)).max(0) + 3) / 4)
    println(ga)
  }
}

object P279D {

  def main ( args : Array[String] ) {
    readLine().split(" ").map(_.toInt);
    val A : Array[Int] = readLine().split(" ").map(_.toInt);
    val C4 = A.count(_ == 4)
    val C3 = A.count(_ == 3)
    var C2 = A.count(_ == 2)
    var C1 = A.count(_ == 1)

    C1 -= (C2 % 2) * 2
    if(C1 < 0) C1 = 0

    C1 -= C3
    if(C1 < 0) C1 = 0
    if(C1 == 0) C1 = -3
    if(C2 == 0) C2 = -1
    println (C4 + (C2 - 1) / 2 + 1 + (C1 - 1) / 4 + 1 + C3)

  }
}

import scala.io.StdIn._

object A_158 extends App {

  def sgn(i: Int) = if (i > 0) 1 else 0

  val n = readInt()
  val S = readLine().split(" ").map(_.toInt).groupBy(identity).mapValues(_.length).withDefaultValue(0)

  val restOnes = Math.max(0, S(1) - S(3))
  val answer = S(4) + S(3) + S(2) / 2 + (S(2) % 2 match {
    case 0 =>  restOnes / 4 + sgn(restOnes % 4)
    case 1 =>  1 + Math.max(0, restOnes - 2) / 4 + sgn(Math.max(0, restOnes - 2) % 4)
  })

  println(answer)
}

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

    import scala.io.StdIn

    val nGroups: Int = StdIn.readInt()
    val stringGroups: String = StdIn.readLine()

    /*var ones: Int = repetitions(stringGroups, "1")
    stringGroups = stringGroups.replace("1", "")
    var twos: Int = repetitions(stringGroups, "2")
    stringGroups = stringGroups.replace("2", "")
    var threes: Int = repetitions(stringGroups, "3")
    stringGroups = stringGroups.replace("3", "")
    var fours: Int = repetitions(stringGroups, "4")*/

    var counts: Array[Int] = repetitions(stringGroups)

    var count: Int = 0

    var ones: Int = counts(0)
    var twos: Int = counts(1)
    var threes: Int = counts(2)
    var fours: Int = counts(3)

    /*if (threes >= ones){
      println((fours + threes + Math.ceil(twos.asInstanceOf[Float]/2))
        .asInstanceOf[Int])
    } else {
      println((fours + threes + Math.ceil(twos.asInstanceOf[Float]/2) + Math
        .ceil((ones-threes).asInstanceOf[Float]/4)).asInstanceOf[Int])
    }*/

    count = fours
    count = count + threes
    if (threes > ones){
      ones = 0
    } else {
      ones = ones - threes
    }
    count = count + twos/2
    if (twos%2 == 0){
    } else {
      ones = ones + (twos%2)*2
    }
    count = count + Math.ceil(ones.asInstanceOf[Double]/4).asInstanceOf[Int]
    println(count)
  }

  def repetitions(string: String): Array[Int] ={
    val myString: String = string
    var count: Array[Int] = new Array[Int](4)

    for (i <- 0 until myString.length){
      myString.charAt(i) match {
        case '1' => count(0) = count(0) + 1
        case '2' => count(1) = count(1) + 1
        case '3' => count(2) = count(2) + 1
        case '4' => count(3) = count(3) + 1
        case _ =>
      }
    }

    count
  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))
    val (r1,r2) = (rem1/4, rem1 %4)

    val  (rems1, rems2) = ( (r2 + rem2*2 )/4, (rem1+rem2*2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + r1 + remss + rems1)
//
//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)
//    println("r1, r2" + (r1,r2))
//    println("remss:" + remss)

  }
}
// 1 1 1 1 1 1 1 1 1 1

import scala.io.StdIn.readLine
import scala.io.StdIn.readInt

object Taxi {

  def main(args: Array[String]) {
    val n = readInt
    val groups = readLine.split(' ').map(_.toInt)
    val fours = groups.count(_ == 4)
    val threes = groups.count(_ == 3)
    val twos = groups.count(_ == 2)
    val ones = groups.count(_ == 1)

    val twosRem = twos%2
    val threesRem = Math.max(threes - ones, 0)
    val onesRem = Math.max(ones - threes, 0)

    val taxis = (fours + twos/2) + Math.min(threes,ones) +
      (if (threes >= ones) threesRem + twosRem
         else (
           (2*twosRem + onesRem)/4 + (if ((2*twosRem + onesRem) % 4 == 0) 0 else 1)
             )
             )
    println(taxis)

  }

}

object main extends App {
    import java.io.{InputStream, PrintStream}
    import java.util.Scanner
    def solve(input: InputStream, output: PrintStream): Unit = {
    val sc = new Scanner(input)
    val n = sc.nextInt()
    val groups = (1 to n).map( _ => sc.nextInt())
    val counters =((1 to 4) map ( c => groups.count( _ == c))).toArray

    var c1 = counters(0)
    var c2 = counters(1)
    var c3 = counters(2)
    var c4 = counters(3)

    var result = c4
    if( c3 > c1){
      result += c1
      c3 -= c1
      c1 = 0
    }else{
      result += c3
      c1 -= c3
      c3 = 0
    }

    result += c2 / 2
    c2 %= 2

    if( c2 > (c1 +1)/2){
      //hay más grupos de 2 que pares de 1
      result += c2
      c1 = 0
      c2 = 0
    }else{
      result += c2
      c1 -= c2*2
      c2 = 0
    }

    result += (c1+3)/4
    result += c2 + c3
    output.println(result)
  }
    solve(System.in,System.out)
}

import scala.io.StdIn

object  Test {
  def main(args1: Array[String]) {
//    val args = StdIn.readLine().split(" ")
//    var (x: Long, y: Long) = (args(0).toLong, args(1).toLong)

    val count = StdIn.readInt

    val line = StdIn.readLine().split(" ").map(s => s.toInt)

    var l1 = line.filter(x => x == 1).length
    var l2 = line.filter(x => x == 2).length
    var l3 = line.filter(x => x == 3).length
    var l4 = line.filter(x => x == 4).length

    var res = l4.toLong
    if (l1 <= l3) {
      res += l3
      res += (l2 / 2) + l2 % 2
    } else {
      res += l3
      var left = l1 - l3
      l2 += (left / 2) + left % 2
      res += (l2 / 2) + l2 % 2
    }

    println(res)
  }

}

object OneFiveEightB {
	def main(args: Array[String]) {
		var array=new Array[Int](4)
		var n=readInt
		readLine.split(' ').foreach{x=>array(x.toInt-1)+=1}
		var fours=array(3)
		var threes=array(2)
		var twos=array(1)/2
		var rem2=array(1)%2
		var rem1=math.max(array(0)-array(2),0)
		var buff=0
		if(rem2!=0){
			twos+=1
			if(rem1>2){
				rem1-=2
				buff=rem1/4
				if(rem1%4!=0){
					buff+=1
				}
			}
		}else{
			if(rem1>0){
				buff=rem1/4
				if(rem1%4!=0){
					buff+=1
				}
			}
		}
		println(fours+threes+twos+buff)
	}
}

import scala.io.StdIn._

object Taxi {
  def main(args: Array[String]): Unit = {
    readInt()
    val groups = readLine().split(" ").groupBy(_.toInt).mapValues(_.length).withDefaultValue(0)
    val ones = Math.max(0, groups(1) - groups(3))
    val res = groups(4) + groups(3) + (groups(2) * 2 + ones + 3) / 4
    println(res)
  }
}

import scala.collection.mutable

object counter {

  def main(args: Array[String]) {
    val numOfParts = Console.readInt()
    var groupsMap: mutable.Map[Int, Int] = new mutable.HashMap[Int, Int]() {
      override def default(key: Int) = 0
    }
    Console.readLine().split(" ").map(_.toInt).toList.take(numOfParts).foreach(value => groupsMap.update(value, groupsMap(value) + 1));
    var result: Int = groupsMap(4)
    if (groupsMap(3) <= groupsMap(1)) {
      result += groupsMap(3)
      groupsMap.update(1, groupsMap(1) - groupsMap(3))
      groupsMap.update(3, 0)
    } else {
      result += groupsMap(3)
      groupsMap.update(1, 0)
      groupsMap.update(3, 0)
    }
    if (groupsMap(2) % 2 == 0) {
      result += groupsMap(2) / 2
      groupsMap.update(2, 0)
    } else {
      result += groupsMap(2) / 2
      if (groupsMap(1) > 1) {
        groupsMap.update(2, 0)
        groupsMap.update(1, groupsMap(1) - 2)
        result += 1
      } else {
        groupsMap.update(2, 0)
        groupsMap.update(1, 0)
        result += 1
      }
    }
    if(groupsMap(1) > 0){
      result += Math.ceil(groupsMap(1).toDouble / 4).toInt
    }
    println(result)
  }

}

/*input
8
2 3 4 4 2 1 3 1
*/

import java.util.Scanner
import scala.io.StdIn

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

		val n = StdIn.readInt();
		val arr = StdIn.readLine().split(" ").map( _.toInt );
		val count = arr.foldLeft(List(0,0,0,0,0)){(list: List[Int], x: Int) => {
				val newCount = for(i <- 0 to list.length-1) yield {
					if(i == x) list(i)+1 else list(i);
				}
				newCount.toList;
			}}
		if(count(3) >= count(1)) print(count(4) + count(3) + ceil(count(2),2))
		else{
			if( count(2) % 2 == 0 ) print(count(4) + count(3) + ceil(count(2),2) + ceil(count(1)-count(3),4))
			else print(count(4) + count(3) + ceil(count(2),2) + ceil(max(count(1)-count(3)-2,0),4))
		}
	}
	def ceil(a: Long, b:Long) : Long ={
		(if(a%b == 0) 0 else 1 ) + a/b;
	}
	def max(a: Int, b: Int) = if(a>b) a else b;
}

import scala.util.Sorting
import scala.io.StdIn

object App {

  def main(args: Array[String]) {

    val n = StdIn.readLine().toInt
    val A: Array[Int] = StdIn.readLine().split(" ").map(_.toInt)

    val M: scala.collection.mutable.Map[Int, Int] = scala.collection.mutable.Map[Int, Int](1->0,2->0,3->0,4->0)

    A.foreach(M(_) += 1)

    var ans = M(4)

    var m = math.min(M(1), M(3));

    M(1) = M(1) - m;
    M(3) = M(3) - m;
    ans += m
    ans += M(2) / 2;

    if (M(2) % 2 == 1) {
      ans+=1
      M(1) = math.max(0, M(1) - 2)
    }

    ans += M(1) / 4

    if (M(1) % 4 != 0)
      ans += 1

    ans += M(3)
    println(ans)

  }

}

object Main {

  def main(args: Array[String]): Unit = {
    val _ = readLine
    var res = 0;
    var count = new Array[Int](5)
    for(x <- readLine().split(" ").map(_.toInt))count(x) += 1
    count(1) = Math.max(0,count(1)-count(3))
    res = count(4)+count(3)+(count(2)*2+count(1)+3)/4
    print(res)
  }

}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    var children = readLine.split(" ").map(_.toInt)

    var ones: Int = children.count(_ == 1)
    var twos: Int = children.count(_ == 2)
    var threes: Int = children.count(_ == 3)

    val threesAndOnes = Math.min(threes, ones)              // 3 + 1
    ones              = Math.max(0, ones - threesAndOnes)   // Remaining 1s from 3 + 1 taxis
    threes            = Math.max(0, threes - threesAndOnes) // Remaining 3s from 3 + 1 taxis
    val twoAndTwo     = Math.floor(twos / 2).toInt          // 2 + 2
    twos              = Math.max(0, twos - twoAndTwo * 2)   // Remaining 2s from 2 + 2 taxis
    var twoAndOne     = Math.min(ones, twos)                // 2 + 1
    ones              = Math.max(0, ones - twoAndOne)       // Remaining 1s from 2 + 1 taxis
    twos              = Math.max(0, twos - twoAndOne)       // Remaining 2s from 2 + 1 taxis
    val twoAndOneAndOne = Math.min(twoAndOne, ones)         // 2 + 1 + 1
    ones              = Math.max(0, ones - twoAndOneAndOne) // Remaining 1s from 3 + 1 taxis
    twoAndOne         = Math.max(0, twoAndOne - twoAndOneAndOne) // Remaining 2 + 1s from 2 + 1 + 1 taxis
    val oneAndOne     = Math.floor(ones / 4).toInt          // 1 + 1 + 1 + 1
    ones              = Math.max(0, ones - oneAndOne * 4)   // Remaining 1s from 2 + 1 taxis

    if (twos < 4 && twos > 0) twos = 1
    if (ones < 4 && ones > 0) ones = 1

//    println(
//      "threesAndOnes: " + threesAndOnes      ,
//      "threes: " + threes                    ,
//      "twoAndTwo: " + twoAndTwo              ,
//      "twoAndOne: " + twoAndOne              ,
//      "twoAndOneAndOne: "+ twoAndOneAndOne   ,
//      "twos: " + twos                        ,
//      "oneAndOne: " + oneAndOne              ,
//      "ones: " + ones
//    )

    val taxis =
      children.count(_ == 4)      +
      threesAndOnes               +
      threes                      +
      twoAndTwo                   +
      twoAndOne                   +
      twoAndOneAndOne             +
      twos                        +
      oneAndOne                   +
      ones

    println(taxis)

    //    def left(taxi: Int): Int =
    //      if (taxi > 0) 1 else 0
    //    val filteredChildren: Array[Int] = children.filter(_ != 4).sorted
    //
    //    val taxis: (Int, Int) =
    //      filteredChildren
    //        .foldLeft((initialTaxis, 0))(                                     // Num taxis, current capacity
    //            (taxi, group) => {
//              filteredChildren(filteredChildren.indexOf(group)) = 0       // Current one will always be used somewhere
//
//              if (group != 0)
//                if (filteredChildren contains 4 - group) {                // Find best complement of group
//                  filteredChildren(filteredChildren.indexOf(4 - group)) = 0
//                  (taxi._1 + 1, taxi._2)
//                } else
//                    if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)       // Hop-on
//                    else if (taxi._2 + group == 4) (taxi._1 + 1, 0)           // Full taxi
//                    else (taxi._1 + 1, group)                                 // Allocate new taxi
//              else taxi
//          }
//        )
//
//    println(taxis._1 + left(taxis._2))
  }
}

import java.util.Scanner

object Taxi extends App {
  def parseInts(str: String, numIterations: Integer) = {
    val scanner = new Scanner(str)
    val res = (0 until numIterations) map (_ => scanner.nextInt())
    scanner.close()
    res
  }

  val Seq(numFamilies) = parseInts(Console.readLine(), 1)
  val families = parseInts(Console.readLine(), numFamilies)
  val groupings = Array.fill[Int](5)(0)

  families.foreach(fam => groupings(fam) = groupings(fam) + 1)

  var total = 0

  families.foreach(fam => {
    val remainder = 4 - fam
    var upperBound = remainder
    val lowerBound = 1

    if (groupings(fam) > 0) {
      groupings(fam) -= 1
      total += 1
      var famAdded = fam
      while (famAdded < 4 && lowerBound <= upperBound) {
        if ((famAdded + upperBound) <= 4 && groupings(upperBound) > 0) {
          groupings(upperBound) -= 1
          famAdded += upperBound
        } else {
          upperBound -= 1
        }
      }
    }
  })

  println(total)
}

import java.util.Scanner

object Taxi extends App {
  def parseInts(str: String, numIterations: Integer) = {
    val scanner = new Scanner(str)
    val res = (0 until numIterations) map (_ => scanner.nextInt())
    scanner.close()
    res
  }

  val MAX_FAMILY_SIZE = 4
  val MIN_FAMILY_SIZE = 1

  val Seq(numFamilies) = parseInts(Console.readLine(), 1)
  val families = parseInts(Console.readLine(), numFamilies)
  val familiesBySize = Array.fill[Int](5)(0)

  families.foreach(fam => familiesBySize(fam) = familiesBySize(fam) + 1)

  var total = 0

  def fitGroupsInTaxi(famBySize: Array[Int], famSize: Int): Unit = {
    if (familiesBySize(famSize) > 0) {
      // Decrement number of families at that size
      familiesBySize(famSize) -= 1
      total += 1
      var numInTaxi = famSize

      def placeInTaxi(maybePlaceInTaxi: Int, numIn: Int): Int = {
        numIn match {
          case MAX_FAMILY_SIZE => {
            numIn
          }
          case _ => {
            if ((numIn + maybePlaceInTaxi) <= MAX_FAMILY_SIZE && familiesBySize(maybePlaceInTaxi) > 0) {
              familiesBySize(maybePlaceInTaxi) -= 1
              placeInTaxi(maybePlaceInTaxi, numIn + maybePlaceInTaxi)
            } else numIn
          }
        }
        //        if (numInTaxi < MAX_FAMILY_SIZE && familiesBySize(maybePlaceInTaxi) > 0) {
        //          familiesBySize(maybePlaceInTaxi) -= 1
        //          numIn + maybePlaceInTaxi
        //        } else {numIn}
      }

      for {
        maybePlaceInTaxi <- (MAX_FAMILY_SIZE - famSize) to MIN_FAMILY_SIZE by -1

        //        while( < MAX_FAMILY_SIZE)
        if (numInTaxi < MAX_FAMILY_SIZE && familiesBySize(maybePlaceInTaxi) > 0)
      } yield {
        numInTaxi = placeInTaxi(maybePlaceInTaxi, numInTaxi)
        //        familiesBySize(maybePlaceInTaxi) -= 1
        //        numInTaxi += maybePlaceInTaxi
      }
    }
  }

  families.foreach(fam => fitGroupsInTaxi(familiesBySize, fam))

  println(total)
}

import java.util.Scanner
import collection.immutable.HashMap
import scala.math.min
import scala.math.max

/**
  * Created by dr0ff on 26/02/16.
  */
object Taxi extends App {

  val in = new Scanner(System.in)
  val totalGroups = in.nextLine().trim.toInt
  val groups = in.nextLine().trim.split(" ").map(_.toInt)

  print(getTotalCarsNum(groups))

  def getTotalCarsNum(groups: Array[Int]) = {
    val places = 4
    val counter = groups.foldLeft(new HashMap[Int, Int]()) {
      (c, x) => c + (x -> (c.getOrElse(x, 0) + 1))}
    val fours = counter.getOrElse(4, 0)
    val onesWithTriples = min(counter.getOrElse(1, 0), counter.getOrElse(3, 0))
    val triplesOnly = (counter.getOrElse(3, 0) - onesWithTriples)
    val deucesOnly: Int = counter.getOrElse(2, 0) / 2
    val deucesWithOnes = counter.getOrElse(2, 0) % 2
    val remainOnes = max(0, counter.getOrElse(1, 0) - onesWithTriples - 2 * deucesWithOnes)
    val onesOnly: Int =  remainOnes / places + min(remainOnes % places, 1)

    fours + onesWithTriples + triplesOnly + deucesOnly + deucesWithOnes + onesOnly
  }
}

import scala.io.StdIn._
import scala.util.Sorting
import java.lang.Math._

object Taxi_158B extends App {
  val n = readInt
  val chs = readLine.split(" ").map(_.toInt)

  val gchs = Map(1->0, 2->0, 3->0, 4->0) ++ chs.groupBy((a: Int) => a).map(a => (a._1 -> a._2.length))

  val gchs1 = Map(
      4 -> gchs(4),
      3 -> gchs(3),
      2 -> gchs(2),
      1 -> (gchs(1) - min(gchs(1), gchs(3)))
          )

  val gchs2 = Map(
      4 -> gchs1(4),
      3 -> gchs1(3),
      2 -> (gchs1(2) + (if (gchs1(1) > 1 && gchs1(2) % 2 != 0) 1 else 0)),
      1 -> (if (gchs1(1) > 0 && gchs1(2) > 0  && gchs1(2) % 2 != 0) gchs1(1) - min(gchs1(1), 2) else gchs1(1))
          )

  //println(gchs, gchs1, gchs2)
  val ans =
      gchs2(4) +
      gchs2(3) +
      gchs2(2) / 2 + (if (gchs2(2) % 2 != 0) 1 else 0) +
      gchs2(1) / 4 + (if (gchs2(1) % 4 != 0) 1 else 0)

  println(ans)
}

import scala.collection.mutable

object CF0158B extends App {

  val n = readInt()

  var s = readLine().split(" ").map(_.toInt).toList.sorted

  var count = 0

  var iter = s.reverseIterator
  var stack = new mutable.Stack[Int]()
  while (iter.hasNext ) {
    var it = iter.next()
    if(it == 4) {
      count += 1
    } else {
      if(stack.isEmpty) {
        stack.push(it)
      } else {
        var people = stack.top + it
        if (people == 4){
          stack.pop()
          count += 1
        } else if (people > 4) {
          stack.push(it)
        } else {
          stack.pop()
          stack.push(people)
        }
      }
    }
  }
  if(!stack.isEmpty) {
    while (!stack.isEmpty) {
      stack.pop()
      count += 1
    }
  }

  println(count)

}

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

object Taxi {

  def main(args: Array[String]) = {
    val br = new BufferedReader(new InputStreamReader(System.in))
    val numOfGroups = br.readLine().toInt
    val (ones, twos, threes, fours) = readGroups(br, numOfGroups)
    val res = numberOfTaxis(ones, twos, threes, fours)
    println(res)
  }

  def readGroups(br: BufferedReader, numOfGroups: Int): (Int, Int, Int, Int) = {
    val str = br.readLine()
    val tok = new StringTokenizer(str)
    var ones, twos, threes, fours = 0
    (1 to numOfGroups).foreach { _ =>
      val next = Integer.parseInt(tok.nextToken())
      next match {
        case 1 => ones += 1
        case 2 => twos += 1
        case 3 => threes += 1
        case _ => fours += 1
      }
    }
    (ones, twos, threes, fours)
  }

  def numberOfTaxis(ones: Int, twos: Int, threes: Int, fours: Int): Int = {
    val groupsOf3And1 = math.min(threes, ones)
    val groupsOf3 = threes - groupsOf3And1

    val remainingGroupsOf1 = ones - groupsOf3And1
    val (remainingGroupsOf1Paired, oddGroupsOf1) = divWithMod(remainingGroupsOf1, 2)
    val (groupsOf2, oddGroupsOf2) = divWithMod(twos + remainingGroupsOf1Paired, 2)

    val remaining = math.min(1, oddGroupsOf1 + oddGroupsOf2)

    fours + groupsOf3And1 + groupsOf3 + groupsOf2 + remaining
  }

  def divWithMod(x: Int, y: Int): (Int, Int) = {
    val r = x / y
    val m = x % y
    (r, m)
  }
}

import java.util.Scanner

object Taxi {

  def main(args: Array[String]) = {
    val sc = new Scanner(System.in)
    val numOfGroups = sc.nextInt()
    sc.nextLine()
    val groups = (1 to numOfGroups).map { _ => sc.nextInt() }.toList
    val res = numberOfTaxis(groups)
    println(res)
  }

  case class GroupType(size: Int, count: Int)

  def numberOfTaxis(groups: List[Int]): Int = {
    val groupsBySize = groups.groupBy(identity).map { case (size, values) => size -> values.size }.withDefault(_ => 0)

    val groupsOf4 = groupsBySize(4)
    val groupsOf3And1 = math.min(groupsBySize(3), groupsBySize(1))
    val groupsOf3 = groupsBySize(3) - groupsOf3And1

    val remainingGroupsOf1 = groupsBySize(1) - groupsOf3And1
    val (remainingGroupsOf1Paired, oddGroupsOf1) = divWithMod(remainingGroupsOf1, 2)
    val (groupsOf2, oddGroupsOf2) = divWithMod(groupsBySize(2) + remainingGroupsOf1Paired, 2)

    val remaining = math.min(1, oddGroupsOf1 + oddGroupsOf2)

    groupsOf4 + groupsOf3And1 + groupsOf3 + groupsOf2 + remaining
  }

  def divWithMod(x: Int, y: Int): (Int, Int) = {
    val r = x / y
    val m = x % y
    (r, m)
  }
}

import java.util.Scanner

import scala.annotation.tailrec

object Taxi {

  def main(args: Array[String]) = {
    val sc = new Scanner(System.in)
    val numOfGroups = sc.nextInt()
    sc.nextLine()
    val groups = (1 to numOfGroups).map { _ => sc.nextInt() }.toList
    val res = numberOfTaxis(groups)
    println(res)
  }

  case class GroupType(size: Int, count: Int)

  def numberOfTaxis(groups: List[Int]): Int = {
    @tailrec
    def numberOfTaxisRec(taxis: Int, groupTypes: Vector[GroupType]): Int = {
      if (groupTypes.isEmpty) taxis
      else if (groupTypes.head.count == 0) numberOfTaxisRec(taxis, groupTypes.tail)
      else {
        val (updatedGroupTypes, _) = groupTypes.foldLeft((Vector.empty[GroupType], 0)) { case ((upd, totalTaken), gt) =>
          val left = 4 - totalTaken
          val taken = math.min(gt.count, left / gt.size)
          (upd :+ gt.copy(count = gt.count - taken), totalTaken + taken * gt.size)
        }
        numberOfTaxisRec(taxis + 1, updatedGroupTypes)
      }
    }

    val groupTypes = groups
      .groupBy(identity)
      .map { case (size, values) => GroupType(size, values.size) }
      .toVector
      .sortBy(- _.size)
    numberOfTaxisRec(0, groupTypes)
  }
}

import java.util.Scanner

import scala.collection.mutable

object Taxi {

  def main(args: Array[String]) = {
    val sc = new Scanner(System.in)
    val numOfGroups = sc.nextInt()
    sc.nextLine()
    val groups = readGroups(sc, numOfGroups)
    val res = numberOfTaxis(groups)
    println(res)
  }

  def readGroups(sc: Scanner, numOfGroups: Int): mutable.HashMap[Int, Int] = {
    val res = mutable.HashMap[Int, Int](1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)
    (1 to numOfGroups).foreach { _ =>
      val next = sc.nextInt()
      res.update(next, res(next) + 1)
    }
    res
  }

  def numberOfTaxis(groupsBySize: mutable.HashMap[Int, Int]): Int = {
    val groupsOf4 = groupsBySize(4)
    val groupsOf3And1 = math.min(groupsBySize(3), groupsBySize(1))
    val groupsOf3 = groupsBySize(3) - groupsOf3And1

    val remainingGroupsOf1 = groupsBySize(1) - groupsOf3And1
    val (remainingGroupsOf1Paired, oddGroupsOf1) = divWithMod(remainingGroupsOf1, 2)
    val (groupsOf2, oddGroupsOf2) = divWithMod(groupsBySize(2) + remainingGroupsOf1Paired, 2)

    val remaining = math.min(1, oddGroupsOf1 + oddGroupsOf2)

    groupsOf4 + groupsOf3And1 + groupsOf3 + groupsOf2 + remaining
  }

  def divWithMod(x: Int, y: Int): (Int, Int) = {
    val r = x / y
    val m = x % y
    (r, m)
  }
}

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

import scala.collection.mutable

object Taxi {

  def main(args: Array[String]) = {
    val br = new BufferedReader(new InputStreamReader(System.in))
    val numOfGroups = br.readLine().toInt
    val groups = readGroups(br, numOfGroups)
    val res = numberOfTaxis(groups)
    println(res)
  }

  def readGroups(br: BufferedReader, numOfGroups: Int): mutable.HashMap[Int, Int] = {
    val str = br.readLine()
    val tok = new StringTokenizer(str)
    val res = mutable.HashMap[Int, Int](1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)
    (1 to numOfGroups).foreach { _ =>
      val next = Integer.parseInt(tok.nextToken())
      res.update(next, res(next) + 1)
    }
    res
  }

  def numberOfTaxis(groupsBySize: mutable.HashMap[Int, Int]): Int = {
    val groupsOf4 = groupsBySize(4)
    val groupsOf3And1 = math.min(groupsBySize(3), groupsBySize(1))
    val groupsOf3 = groupsBySize(3) - groupsOf3And1

    val remainingGroupsOf1 = groupsBySize(1) - groupsOf3And1
    val (remainingGroupsOf1Paired, oddGroupsOf1) = divWithMod(remainingGroupsOf1, 2)
    val (groupsOf2, oddGroupsOf2) = divWithMod(groupsBySize(2) + remainingGroupsOf1Paired, 2)

    val remaining = math.min(1, oddGroupsOf1 + oddGroupsOf2)

    groupsOf4 + groupsOf3And1 + groupsOf3 + groupsOf2 + remaining
  }

  def divWithMod(x: Int, y: Int): (Int, Int) = {
    val r = x / y
    val m = x % y
    (r, m)
  }
}

import scala.collection.mutable.ListBuffer

object task158B {
  def main(args:Array[String]) {
    val in=io.Source.stdin.getLines.toList
    val Array(n)=in(0).split(" ").map(_.toInt)
    val s=in(1).split(" ").map(_.toInt).toList
    var k1=0; var k2=0; var k3=0; var rv=0;
    for (a <- s) {
      a match {
        case 1 => k1+=1;
        case 2 => k2+=1;
        case 3 => k3+=1;
        case 4 => rv+=1;
      }
    }
    rv+=k3; if (k3>k1) { k1=0; } else { k1-=k3; }
    rv+=k2/2; k2=k2%2; if (k2==1) { rv+=1; k2=0; if (k1>=2) { k1-=2; } else { k1=0; } }
    rv+=k1/4; k1=k1%4; if (k1!=0) { rv+=1; }
    println(rv)
  }
}

object B00158 extends App {

  def oneIntLine = {
    val Seq(count) = parseInt(Console.readLine(), 1);
    count
  }

  def parseInt(str: String, count: Int): Seq[Int] = {
    val scanner = new java.util.Scanner(str)
    val res = (1 to count) map (_ => scanner.nextInt())
    scanner.close()
    res
  }
  def scanInts(count: Int): Seq[Int] = parseInt(Console.readLine, count)

  def frequency[T](seq: Seq[T]) = seq.groupBy(identity).mapValues(_.size).withDefaultValue(0)

  def partsNeededToCoverFull(fullLength: Int, partLength: Int) =
    Math.ceil(fullLength * 1.0 / partLength).toInt

  val count = oneIntLine
  val grouped = frequency(scanInts(count))
  val partialCount = grouped(4) + grouped(3) + partsNeededToCoverFull(grouped(2), 2)
  val vacantSeats = grouped(3) + (if (grouped(2) % 2 == 1) 2 else 0)
  val remainingSingles = if (grouped(1) > vacantSeats) grouped(1) - vacantSeats else 0
  val res = partialCount + partsNeededToCoverFull(remainingSingles, 4)
  println(res)
}

object pratise {
    def solve() {
        val n = readInt
        var res = 0
        var count = new Array[Int](5)
        for(i <- readLine().split(" ").map(_.toInt)) count(i) += 1
        count(1) = math.max(0,count(1) - count(3))
        res = count(4) + count(3) + (count(2)*2 + count(1) + 3) / 4
        println(res)
    }
    def main(args : Array[String]) {
        solve
    }
}

object cf extends App{
  val n = readInt()
  val arr = Array.fill[Int](5)(0)
  var nums = readLine().split(" ").map(_.toInt)
  for (i <- 0 to n-1) {
    val x = nums(i)
    arr(x) += 1
  }
  var res = 0
  res += arr(4)
  res += arr(3)
  arr(1) -= arr(3)
  arr(1) = arr(1).max(0)
  arr(3) = 0
  res += arr(2)/2
  arr(2) = arr(2) % 2
  arr(1) += arr(2)*2
  res += arr(1)/4
  if (arr(1) % 4 != 0) res += 1
  //make it go
  println(res)
}

import scala.io.StdIn.readLine
object Solution {
    def readLines(n: Int) = Iterator.continually(readLine).take(n).toIterable
    def group(s: Iterable[Int]) = s groupBy identity mapValues (_.size) withDefaultValue 0
    def solve(m: Map[Int, Int]) = {
        val singletonesLeft = math.max(m(1) - m(3), 0)
        val pairsLeft = m(2) % 2
        m(4) + m(3) + m(2) / 2 + (pairsLeft * 2 + singletonesLeft + 3) / 4
    }
    def main(args: Array[String]) = {
        val n = readLine.toInt
        val s = readLine split " " map (_.toInt)
        println(solve(group(s)))
    }
}

object Solution158B extends Application {

  def solution() {
    val n = _int
    val groups = 1.to(n).map(_ => _int).groupBy(x => x).mapValues(seq => seq.size)

    val n1 = groups.get(1).getOrElse(0)
    val n2 = groups.get(2).getOrElse(0)
    val n3 = groups.get(3).getOrElse(0)
    val n4 = groups.get(4).getOrElse(0)
    val res = n4 + n3 + (n2 / 2 + n2 % 2)
    val left = n1 - n3 - (2 * (n2 % 2))

    println(res + (if (left > 0) (left + 3) / 4 else 0))
  }

  //////////////////////////////////////////////////
  import java.util.Scanner
  val SC: Scanner = new Scanner(System.in)
  def _line: String = SC.nextLine
  def _int: Int = SC.nextInt
  def _long: Long = SC.nextLong
  def _string: String = SC.next
  solution()
}

import scala.collection.mutable._
import scala.math._
import scala.util.control.Breaks.break
import scala.util.control.Breaks.breakable
import java.util._
object Main extends App {
  val sc = new Scanner(System.in)
  val n = sc.nextInt
  val t = for(i <- 1 to n) yield sc.nextInt
  val tc = for(i <- 0 to 4) yield t.count(_ == i)
  println(tc(4) + tc(3) + (tc(2)+1)/2 + (3+max(0, tc(1) - tc(3) - 2*(tc(2) % 2)))/4)
}

import scala.io.StdIn
object TaxiTest {
  def main(args: Array[String]){
    val numberOfGroups = StdIn.readInt()
    val childrens = StdIn.readLine().split(" ").map(_.toInt)
    var count1 = childrens.count(_ == 1)
    var count2 = childrens.count(_ == 2)
    var count3 = childrens.count(_ == 3)
    var count4 = childrens.count(_ == 4)

    var res = count4
    while (count1 > 0 && count3 >0 ){
      res = res + 1
      count1  = count1 - 1
      count3 = count3  - 1
    }
    if(count2 > 0){
      res = res + count2/2
      count2 = count2 % 2
    }

    if(count1 > 0 ){
      if(count2 > 0){
        count1  = count1 + 2
      }
      res = res + count1/4
      if( count1 % 4 != 0 ) res = res + 1;
    }
    else if(count3 > 0){
      res = res +  count3
      if( count2 > 0){
        res = res + 1

      }
    }
    else if(count2 > 0){
      res = res +1
    }

    println(res)
  }
}

object Main {
	import java.{util=>ju}
	import scala.math._

	def main(args:Array[String])
	{
		val sc = new ju.Scanner(System.in)
		val n = sc.nextInt();
		val a = (1 to n).map(_ => sc.nextInt()).toList

		val res = count(a, (1 to 4).toList.map(_=>0))
		println(res(3)+res(2)+(res(1)+1)/2+(3+max(0, res(0)-res(2)-2*(res(1)%2)))/4)
	}

	def count(arr:List[Int], cnt:List[Int]):List[Int] =
	{
		arr match {
			case h::t if (h >= 1 & h <= 4) => count(t, cnt.updated(h-1, cnt(h-1)+1))
			case h::t => count(t, cnt)
			case Nil => cnt
		}
	}
}

object Main {
	import java.{util=>ju}
	import scala.math._

	def main(args:Array[String])
	{
		val sc = new ju.Scanner(System.in)
		val n = sc.nextInt();
		val a = (1 to n).map(_ => sc.nextInt()).toList

		//val res = count(a, (1 to 4).toList.map(_=>0))
		val res = (1 to 4).map{i => a.count(_==i)}.toList
		println(res(3)+res(2)+(res(1)+1)/2+(3+max(0, res(0)-res(2)-2*(res(1)%2)))/4)
	}

	def count(arr:List[Int], cnt:List[Int]):List[Int] =
	{
		arr match {
			case h::t if (h >= 1 & h <= 4) => count(t, cnt.updated(h-1, cnt(h-1)+1))
			case h::t => count(t, cnt)
			case Nil => cnt
		}
	}
}

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

    val n = std.readInt()
    val line = std.readLine().split(" ").map(_.toInt)
    val counts = new Array[Int](5)
    line.foreach(x => counts(x) += 1)
    val counts2 = (counts(2) + 1) / 2
    val singlesLeft = Math.max(0, counts(1) - counts(3) - (counts(2) % 2) * 2 )
    val result = counts(4) + counts(3) + counts2 + (singlesLeft + 3) / 4
    println(result)
  }
}

import scala.io.StdIn
import scala.language.implicitConversions

object B {
  implicit def toInt(b: Boolean) = if (b) 1 else 0

  def main(args: Array[String]) = {
    val n = StdIn.readLine.toInt
    val s = StdIn.readLine.split(" ").map(_.toInt)
    val freqMap: Map[Int, Int] = s.groupBy(x => x).mapValues(_.length)

    val ones = freqMap.getOrElse(1, 0)
    val twos = freqMap.getOrElse(2, 0)
    val threes = freqMap.getOrElse(3, 0)
    val fours = freqMap.getOrElse(4, 0)

    val mod = if (twos % 2 == 1) 2 else 0
    val ans = fours + threes + (twos + 1) / 2 + Math.max(ones - threes - mod + 3, 0) / 4
    println(ans)
  }
}

import scala.math._

object Taxy extends App{

  import scala.collection.mutable.Map
  val n = readInt
  val arr = readLine.split(" ").map(_.toInt)
  val mp = Map[Int, Int]()

  (1 to 4).foreach(x => mp(x) = 0)
  arr.foreach(x => mp(x) += 1)

  val four = mp(4)
  val third = mp(3)
    mp(1) = max(mp(1) - mp(3), 0)
  val second = mp(2) / 2 + max(if(min(2 * (mp(2) % 2), mp(1)) > 0) 1 else 0, mp(2) % 2)
    mp(1) = max(mp(1) - 2 * (mp(2) % 2), 0)
  val first = mp(1) / 4 + {if( (mp(1) % 4) != 0) 1 else 0}

  println(first + second + third + four)
}

import scala.collection.mutable.ListBuffer;

object Taxi {

  def main(args: Array[String]): Unit = {
    val n = readInt
    val l = Array.fill(5)(0)
    for(x <- readLine().split(" ").map(_.toInt)) l(x) += 1
    if(l(3) >= l(1))
      println(l(4) + l(3) + math.ceil(2*l(2).toDouble/4).toInt)
    else
      println(l(4) + l(3) +  math.ceil((2*l(2) + l(1)-l(3)).toDouble / 4).toInt )
  }

}

/**
 * Created by IntelliJ IDEA.
 * User: lizan
 * Date: 3/19/12
 * Time: 5:44 AM
 * To change this template use File | Settings | File Templates.
 */

import java.util.Scanner

object Main extends App{
  val scanner = new Scanner(io.Source.stdin.reader)

  val N = scanner.nextInt()
  val S = (1 to N).map(_ => scanner.nextInt).sorted

  val count = (0 to 4).map(x => S.count(_ == x))
  val alone = math.max(0, count(1) - count(3))
  val ans = count(4) + count(3) + (count(2) * 2 + alone + 3) / 4

  println(ans)
}

import scala.io.StdIn

object p158b extends App {

  private val n = StdIn.readLine.toInt
  val array=new Array[Int](5)

  val line=StdIn.readLine.split(" ").map(_.toInt).sortBy(identity).reverse
  for (i<- line ){
    array(i)+=1
  }

  var sum=array(4)
  if(array(3)>array(1)) {
    sum+=array(3)
    array(1)=0
  }
  else{
    sum+=array(3)
    array(1)-=array(3)
  }

  sum+=array(2)/2
  val remain=array(2)%2

  if(remain==1){
    if(array(1)>=2){
      array(1)-=2
      sum+=1
    }
    else if(array(1)==1){
      array(1)=0
      sum+=1
    }
    else{
      sum+=1
    }
  }

  sum+=array(1)/4
  val remain1=array(1)%4
  if(remain1>0){
    sum+=1
  }

  print(sum)
}

object B158 {
  @inline def tokenizeLine = new java.util.StringTokenizer(scala.io.StdIn.readLine)

  def readInts(n: Int) = {
    val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toInt)
  }

  def readLongs(n: Int) = {
    val tl = tokenizeLine; Array.fill(n)(tl.nextToken.toLong)
  }

  def readBigs(n: Int) = {
    val tl = tokenizeLine; Array.fill(n)(BigInt(tl.nextToken))
  }

  def main(args: Array[String]): Unit = {
    val Array(n) = readInts(1)
    val input = readInts(n)
    var Array(four, thr, two, one) = Array(4,3,2,1).map{x => input.count(_ == x)}

    var res = four
    four = 0

    val a = math.min(thr, one)
    res += a
    thr -= a
    one -= a
    res += thr
    thr = 0

    res += two/2
    two -= (two/2)*2

    val b = math.min(two, one/2)
    res += b
    two -= b
    one -= b*2

    val c = math.min(two, one)
    res += c
    two -= c
    one -= c

    res += two

    res += (if (one% 4 == 0) one/4 else (one/4)+1)
    one = 0

    println(res)
  }
}

import collection.mutable
import java.util.Scanner

object B extends App {
	val in = new Scanner(System.in)
	val n = in.nextInt()
	val s: mutable.Map[Int, Int] = mutable.HashMap().withDefaultValue(0)
	for (_ <- 1 to n) {
		val si = in.nextInt()
		s += si -> (s(si) + 1)
	}
	val numCars = {
		val remainingOne = 0 max (s(1) - s(3) - (if (s(2) % 2 == 0) 0 else 2))
		s(4) + s(3) + (s(2) + 1) / 2 + (remainingOne + 3) / 4
	}
	println(numCars)
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))
    val (r1,r2) = (rem1/4, rem1 %4)

    val  (rems1, rems2) = ( (r1 + rem2 )/4, (r1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + r1 + remss + rems1)

//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))
    val (r1,r2) = (rem1/4, rem1 %4)

    val  (rems1, rems2) = ( (r1 + rem2 )/4, (rem1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + r1 + remss + rems1)

    println("oat: " + oat)
    println("twos: " + twos)
    println("frs: " + frs)
    println("rems1: " + rems1)
    println("rems2: " + rems2)
    println("r1, r2" + (r1,r2))
    println("remss:" + remss)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))

    val (rems1, rems2) = ( (rem1 + rem2 )/4, (rem1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + rems1 + remss)

//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))
    val (r1,r2) = (rem1/4, rem1 %4)

    val  (rems1, rems2) = ( (r2 + rem2 )/4, (rem1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + r1 + remss + rems1)
//
//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)
//    println("r1, r2" + (r1,r2))
//    println("remss:" + remss)

  }
}
// 1 1 1 1 1 1 1 1 1 1

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

    println("frs" + (frs))

    val (rems1, rems2) = ( (rem1 + rem2 )/4, (rem1+rem2) % 4)

    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

    println("remsss" + remss)

    println(oat + twos + frs + rems1 + rems2)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))
    val (r1,r2) = (rem1/4, rem1 %4)

    val  (rems1, rems2) = ( (r1 + rem2 )/4, (r1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + r1 + remss + rems1)

//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))

    val (rems1, rems2) = ( (rem1 + rem2 )/4, (rem1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + rems1 + rems2)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

    val frs = counted.getOrElse(4,0)

    val (rems1, rems2) = ( (rem1 + rem2 )/4, rem1+rem2 % 4)

    val remss = if(rems2 > 0) 1 else 0

    println(oat + twos + frs + rems1 + rems2)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 2)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))
    val (r1,r2) = (rem1/4, rem1 %4)

    val  (rems1, rems2) = ( (r1 + rem2 )/4, (rem1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + r1 + remss + rems1)
//
//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)
//    println("r1, r2" + (r1,r2))
//    println("remss:" + remss)

  }
}

object Main {
  def main(args: Array[String]): Unit = {
    val n = readLine()
    val numbers = readLine().split(" ").map(_.toInt)

    val counted = numbers.groupBy(identity).mapValues(_.size)

    // (already allocated, remaining)
    val (oat,rem1) = if(counted.getOrElse(3,0) >= counted.getOrElse(1,0)) (counted.getOrElse(3,0),0) else (counted.getOrElse(3,0), counted.getOrElse(1,0) - counted.getOrElse(3,0))

//    println("aot rem1" + (oat,rem1))

    val (twos,rem2) = (counted.getOrElse(2,0) /2, counted.getOrElse(2,0) % 3)

//    println("twos, rem2" +(twos,rem2))

    val frs = counted.getOrElse(4,0)

//    println("frs" + (frs))

    val (rems1, rems2) = ( (rem1 + rem2 )/4, (rem1+rem2) % 4)

//    println( "rems1 rem2"  + (rems1,rems2))

    val remss = if(rems2 > 0) 1 else 0

//    println("remsss" + remss)

    println(oat + twos + frs + rems1 + remss)

//    println("oat: " + oat)
//    println("twos: " + twos)
//    println("frs: " + frs)
//    println("rems1: " + rems1)
//    println("rems2: " + rems2)

  }
}

import scala.io.StdIn

object  Test {
  def main(args1: Array[String]) {
//    val args = StdIn.readLine().split(" ")
//    var (x: Long, y: Long) = (args(0).toLong, args(1).toLong)

    val count = StdIn.readInt

    val line = StdIn.readLine().split(" ").map(s => s.toInt)

    var l1 = line.filter(x => x == 1).length
    var l2 = line.filter(x => x == 2).length
    var l3 = line.filter(x => x == 3).length
    var l4 = line.filter(x => x == 4).length

    var res = l4.toLong
    println(l4)
    if (l1 <= l3) {
      res += l3
      res += (l2 / 2) + l2 % 2
    } else {
      res += l3
      var left = l3 - l1
      l2 += (left / 2) + left % 2
      res += (l2 / 2) + l2 % 2
      println(l2)
    }

    println(res)
  }

}

import scala.io.StdIn

object  Test {
  def main(args1: Array[String]) {
//    val args = StdIn.readLine().split(" ")
//    var (x: Long, y: Long) = (args(0).toLong, args(1).toLong)

    val count = StdIn.readInt

    val line = StdIn.readLine().split(" ").map(s => s.toInt)

    var l1 = line.filter(x => x == 1).length
    var l2 = line.filter(x => x == 2).length
    var l3 = line.filter(x => x == 3).length
    var l4 = line.filter(x => x == 4).length

    var res = l4.toLong
    if (l1 <= l3) {
      res += l3
      res += (l2 / 2) + l2 % 2
    } else {
      res += l3
      var left = l3 - l1
      l2 += (left / 2) + left % 2
      res += (l2 / 2) + l2 % 2
    }

    println(res)
  }

}

object OneFiveEightB {
	def main(args: Array[String]) {
		var array=new Array[Int](4)
		var n=readInt
		readLine.split(' ').foreach{x=>array(x.toInt-1)+=1}
		var fours=array(3)
		var threes=array(2)
		var twos=array(1)/4
		var rem2=array(1)%4
		var rem1=math.max(array(0)-array(2),0)
		var buff=0
		if(rem2!=0){
			twos+=1
			if(rem1>2){
				rem1-=2
				buff=rem1/4
				if(rem1%4!=0){
					buff+=1
				}
			}
		}else{
			if(rem1>0){
				buff=rem1/4
				if(rem1%4!=0){
					buff+=1
				}
			}
		}
		println(fours+threes+twos+buff)
	}
}

import scala.io.StdIn._

object Taxi {
  def main(args: Array[String]): Unit = {
    readInt()
    val groups = readLine().split(" ").map(_.toInt).reduce(_ + _)
    val ans = math.ceil(groups / 4.0).asInstanceOf[Int]
    println(ans)
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    var children = readLine.split(" ").map(_.toInt)

    var ones: Int = children.count(_ == 1)
    var twos: Int = children.count(_ == 2)
    var threes: Int = children.count(_ == 3)

    val threesAndOnes = Math.min(threes, ones)              // 3 + 1
    ones              = Math.max(0, ones - threesAndOnes)   // Remaining 1s from 3 + 1 taxis
    threes            = Math.max(0, threes - threesAndOnes) // Remaining 3s from 3 + 1 taxis
    val twoAndTwo     = Math.floor(twos / 2).toInt          // 2 + 2
    twos              = Math.max(0, twos - twoAndTwo * 2)   // Remaining 2s from 2 + 2 taxis
    val twoAndOne     = Math.min(ones, twos)                // 2 + 1
    ones              = Math.max(0, ones - twoAndOne)       // Remaining 1s from 2 + 1 taxis
    twos              = Math.max(0, twos - twoAndOne)       // Remaining 2s from 2 + 1 taxis
    val oneAndOne     = Math.floor(ones / 4).toInt          // 1 + 1 + 1 + 1
    ones              = Math.max(0, ones - oneAndOne * 4)   // Remaining 1s from 2 + 1 taxis

    if (twos < 4 && twos > 0) twos = 1
    if (ones < 4 && ones > 0) ones = 1

//    println(
//      "threesAndOnes: " + threesAndOnes      ,
//      "threes: " + threes                    ,
//      "twoAndTwo: " + twoAndTwo              ,
//      "twoAndOne: " + twoAndOne              ,
//      "twos: " + twos                        ,
//      "oneAndOne: " + oneAndOne              ,
//      "ones: " + ones
//    )

    val taxis =
      children.count(_ == 4)      +
      threesAndOnes               +
      threes                      +
      twoAndTwo                   +
      twoAndOne                   +
      twos                        +
      oneAndOne                   +
      ones

    println(taxis)

    //    def left(taxi: Int): Int =
    //      if (taxi > 0) 1 else 0
    //    val filteredChildren: Array[Int] = children.filter(_ != 4).sorted
    //
    //    val taxis: (Int, Int) =
    //      filteredChildren
    //        .foldLeft((initialTaxis, 0))(                                     // Num taxis, current capacity
    //            (taxi, group) => {
//              filteredChildren(filteredChildren.indexOf(group)) = 0       // Current one will always be used somewhere
//
//              if (group != 0)
//                if (filteredChildren contains 4 - group) {                // Find best complement of group
//                  filteredChildren(filteredChildren.indexOf(4 - group)) = 0
//                  (taxi._1 + 1, taxi._2)
//                } else
//                    if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)       // Hop-on
//                    else if (taxi._2 + group == 4) (taxi._1 + 1, 0)           // Full taxi
//                    else (taxi._1 + 1, group)                                 // Allocate new taxi
//              else taxi
//          }
//        )
//
//    println(taxis._1 + left(taxis._2))
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    var children = readLine.split(" ").map(_.toInt)

    def left(taxi: Int): Int =
      if (taxi > 0) 1 else 0

    val initialTaxis: Int = children.count(_ == 4)

    val filteredChildren: Array[Int] = children.filter(_ != 4).sorted

    val taxis: (Int, Int) =
      filteredChildren
        .foldLeft((initialTaxis, 0))(                                   // Num taxis, current capacity
            (taxi, group) => {
              filteredChildren(filteredChildren.indexOf(group)) = 0

              if (group != 0)
                if (filteredChildren contains 4 - group) {                        // Find best complement of group
                  filteredChildren(filteredChildren.indexOf(4 - group)) = 0
                  (taxi._1 + 1, 0)
                } else
                    if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)   // Hop-on
                    else if (taxi._2 + group == 4) (taxi._1 + 1, 0)       // Full taxi
                    else (taxi._1 + 1, group)                             // Allocate new taxi
              else taxi
            }
          )

    println(taxis._1 + left(taxis._2))
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    val children = readLine.split(" ").map(_.toInt).sorted

    def left(taxi: Int): Int =
      if (taxi > 0 & taxi != 4) 1 else 0

    val taxis: (Int, Int) =
      children.foldLeft((0, 0))(
        (taxi, group) => {
          println(group, taxi)
          if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)   // Hop-on
          else if (taxi._2 + group == 4) (taxi._1 + 1, 0)       // Full taxi
          else (taxi._1 + 1, group)                             // Allocate new taxi
        }
      )

    println(taxis._1 + left(taxis._2))
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    var children = readLine.split(" ").map(_.toInt)

    var ones: Int = children.count(_ == 1)
    var twos: Int = children.count(_ == 2)
    var threes: Int = children.count(_ == 3)

    val threesAndOnes = Math.min(threes, ones)              // 3 + 1
    ones              = Math.max(0, ones - threesAndOnes)   // Remaining 1s from 3 + 1 taxis
    threes            = Math.max(0, threes - threesAndOnes) // Remaining 3s from 3 + 1 taxis
    val twoAndTwo     = Math.floor(twos / 2).toInt          // 2 + 2
    twos              = Math.max(0, twos - twoAndTwo * 2)   // Remaining 2s from 2 + 2 taxis
    var twoAndOne     = Math.min(ones, twos)                // 2 + 1
    ones              = Math.max(0, ones - twoAndOne)       // Remaining 1s from 2 + 1 taxis
    twos              = Math.max(0, twos - twoAndOne)       // Remaining 2s from 2 + 1 taxis
    val twoAndOneAndOne = Math.min(twoAndOne, ones)         // 2 + 1 + 1
    ones              = Math.max(0, ones - twoAndOneAndOne) // Remaining 1s from 3 + 1 taxis
    twoAndOne         = Math.max(0, twoAndOne - twoAndOneAndOne) // Remaining 2 + 1s from 2 + 1 + 1 taxis
    val oneAndOne     = Math.floor(ones / 4).toInt          // 1 + 1 + 1 + 1
    ones              = Math.max(0, ones - oneAndOne * 4)   // Remaining 1s from 2 + 1 taxis

    if (twos < 4 && twos > 0) twos = 1
    if (ones < 4 && ones > 0) ones = 1

    println(
      "threesAndOnes: " + threesAndOnes      ,
      "threes: " + threes                    ,
      "twoAndTwo: " + twoAndTwo              ,
      "twoAndOne: " + twoAndOne              ,
      "twoAndOneAndOne: "+ twoAndOneAndOne   ,
      "twos: " + twos                        ,
      "oneAndOne: " + oneAndOne              ,
      "ones: " + ones
    )

    val taxis =
      children.count(_ == 4)      +
      threesAndOnes               +
      threes                      +
      twoAndTwo                   +
      twoAndOne                   +
      twoAndOneAndOne             +
      twos                        +
      oneAndOne                   +
      ones

    println(taxis)

    //    def left(taxi: Int): Int =
    //      if (taxi > 0) 1 else 0
    //    val filteredChildren: Array[Int] = children.filter(_ != 4).sorted
    //
    //    val taxis: (Int, Int) =
    //      filteredChildren
    //        .foldLeft((initialTaxis, 0))(                                     // Num taxis, current capacity
    //            (taxi, group) => {
//              filteredChildren(filteredChildren.indexOf(group)) = 0       // Current one will always be used somewhere
//
//              if (group != 0)
//                if (filteredChildren contains 4 - group) {                // Find best complement of group
//                  filteredChildren(filteredChildren.indexOf(4 - group)) = 0
//                  (taxi._1 + 1, taxi._2)
//                } else
//                    if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)       // Hop-on
//                    else if (taxi._2 + group == 4) (taxi._1 + 1, 0)           // Full taxi
//                    else (taxi._1 + 1, group)                                 // Allocate new taxi
//              else taxi
//          }
//        )
//
//    println(taxis._1 + left(taxis._2))
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    val children = readLine.split(" ").map(_.toInt).sorted

    def left(taxi: Int): Int =
      if (taxi > 0 & taxi != 4) 1 else 0

    val taxis: (Int, Int) =
      children.foldLeft((0, 0))(    // Num taxis, current capacity
        (taxi, group) =>
          if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)   // Hop-on
          else if (taxi._2 + group == 4) (taxi._1 + 1, 0)       // Full taxi
          else (taxi._1 + 1, group)                             // Allocate new taxi
      )

    println(taxis._1 + left(taxis._2))
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    var children = readLine.split(" ").map(_.toInt)

    def left(taxi: Int): Int =
      if (taxi > 0) 1 else 0

    val ones: Int = children.count(_ == 1)
    val twos: Int = children.count(_ == 2)
    val threes: Int = children.count(_ == 3)

    val threeAndOnes    : Int = Math.min(threes, ones)              // 3 + 1 taxis
    val remainderThrees : Int = Math.max(0, threes - ones)          // Remainder 3s
    val remainderOnes   : Int = Math.max(0, ones - threes)          // Remainder 1s
    val twoAndTwo       : Int = Math.floor(twos / 2).toInt          // 2 + 2 taxis
    val remainderTwo    : Int = Math.max(0, twos - twoAndTwo)       // Remainder 2s
    val onesAndTwos     : Int = Math.min(remainderOnes, remainderTwo)  // 2 + 1 taxis
    val leftOnesOrTwos  : Int = Math.max(remainderOnes - onesAndTwos, remainderTwo - onesAndTwos)

//    println(
//      "threeAndOnes: " + threeAndOnes,
//      "remainderThrees: " + remainderThrees,
//      "remainderOnes: " + remainderOnes,
//      "twoAndTwo: " + twoAndTwo,
//      "remainderTwo: " + remainderTwo,
//      "onesAndTwos: " + onesAndTwos,
//      "leftOnesOrTwos: " + leftOnesOrTwos)

    val taxis: Int =
      children.count(_ == 4)  +    // Full taxis
      threeAndOnes            +    // 3 + 1 taxis
      remainderThrees         +    // 3 taxis
      onesAndTwos             +    // 2 + 1 taxis
      leftOnesOrTwos               // 1 or 2 taxis

    println(taxis)

    //    val filteredChildren: Array[Int] = children.filter(_ != 4).sorted
//
//    val taxis: (Int, Int) =
//      filteredChildren
//        .foldLeft((initialTaxis, 0))(                                     // Num taxis, current capacity
//            (taxi, group) => {
//              filteredChildren(filteredChildren.indexOf(group)) = 0       // Current one will always be used somewhere
//
//              if (group != 0)
//                if (filteredChildren contains 4 - group) {                // Find best complement of group
//                  filteredChildren(filteredChildren.indexOf(4 - group)) = 0
//                  (taxi._1 + 1, taxi._2)
//                } else
//                    if (taxi._2 + group < 4) (taxi._1, taxi._2 + group)       // Hop-on
//                    else if (taxi._2 + group == 4) (taxi._1 + 1, 0)           // Full taxi
//                    else (taxi._1 + 1, group)                                 // Allocate new taxi
//              else taxi
//          }
//        )
//
//    println(taxis._1 + left(taxis._2))
  }
}

object _158_B {

  def main(args: Array[String]){
    var N = readLine.toInt

    val children = readLine.split(" ").map(_.toInt)

    var result: Int = 0
    var taxi: Int = 0

    for (child <- children) {
      if (taxi == 4) {
        result = result + 1
        taxi = 0
      }

      val n = taxi + child
      if (n < 4) taxi = n
      else if (n > 4) {
        result = result + 1
        taxi = child
      } else if (n == 4) {
        taxi = 0
        result = result + 1
      }

    }

    if (taxi != 0) result = result + 1

    println(result)
  }
}

import java.util.Scanner

import scala.collection.mutable

object Taxi {

  def main(args: Array[String]) = {
    val sc = new Scanner(System.in)
    val groups = readGroups(sc)
    val res = numberOfTaxis(groups)
    println(res)
  }

  def readGroups(sc: Scanner): mutable.HashMap[Int, Int] = {
    val res = mutable.HashMap[Int, Int](1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)
    sc.nextLine().split(' ').foreach { _ =>
      val next = sc.nextInt()
      res.update(next, res(next) + 1)
    }
    res
  }

  def numberOfTaxis(groupsBySize: mutable.HashMap[Int, Int]): Int = {
    val groupsOf4 = groupsBySize(4)
    val groupsOf3And1 = math.min(groupsBySize(3), groupsBySize(1))
    val groupsOf3 = groupsBySize(3) - groupsOf3And1

    val remainingGroupsOf1 = groupsBySize(1) - groupsOf3And1
    val (remainingGroupsOf1Paired, oddGroupsOf1) = divWithMod(remainingGroupsOf1, 2)
    val (groupsOf2, oddGroupsOf2) = divWithMod(groupsBySize(2) + remainingGroupsOf1Paired, 2)

    val remaining = math.min(1, oddGroupsOf1 + oddGroupsOf2)

    groupsOf4 + groupsOf3And1 + groupsOf3 + groupsOf2 + remaining
  }

  def divWithMod(x: Int, y: Int): (Int, Int) = {
    val r = x / y
    val m = x % y
    (r, m)
  }
}

import java.util.Scanner

import scala.annotation.tailrec

object Taxi {

  def main(args: Array[String]) = {
    val sc = new Scanner(System.in)
    val numOfGroups = sc.nextInt()
    sc.nextLine()
    val groups = (1 to numOfGroups).map { _ => sc.nextInt() }.toList
    val res = numberOfTaxis(groups)
    println(res)
  }

  case class GroupType(size: Int, count: Int) {
    def dec: GroupType = copy(count = count - 1)
  }

  def numberOfTaxis(groups: List[Int]): Int = {
    @tailrec
    def numberOfTaxisRec(acc: Int, groupTypes: Vector[GroupType]): Int = {
      if (groupTypes.isEmpty) acc
      else if (groupTypes.head.count == 0) numberOfTaxisRec(acc, groupTypes.tail)
      else {
        val withoutMax = groupTypes.updated(0, groupTypes(0).dec)
        val complGroupTypeIdx = withoutMax.indexWhere(gt => gt.size + groupTypes.head.size <= 4 && gt.count > 0)
        val withoutMaxAndCompl =
          if (complGroupTypeIdx == -1) withoutMax
          else withoutMax.updated(complGroupTypeIdx, withoutMax(complGroupTypeIdx).dec)
        numberOfTaxisRec(acc + 1, withoutMaxAndCompl)
      }
    }

    val groupTypes = groups
      .groupBy(identity)
      .map { case (size, values) => GroupType(size, values.size) }
      .toVector
      .sortBy(- _.size)
    numberOfTaxisRec(0, groupTypes)
  }
}

import scala.collection.mutable.ListBuffer

object task158B {
  def encode[IntA](list: List[Int]):List[(Int,Int)] = {
    var l:List[(Int,Int)] = Nil
    l=(1,0)::l; l=(2,0)::l; l=(3,0)::l; l=(4,0)::l;
    list.foldLeft(l) { (r,c) =>
      r match {
        case (value, count) :: tail =>
          if (value == c) (c, count+1) :: tail
          else            (c, 1) :: r
        case Nil => (c, 1) :: r
      }
    }
  }

  def main(args:Array[String]) {
    val in=io.Source.stdin.getLines.toList
    val Array(n)=in(0).split(" ").map(_.toInt)
    val s=in(1).split(" ").map(_.toInt).toList
    var t=encode(s.sorted).sorted
    //println(t)
    var k1=t(0)._2; var k2=t(1)._2 ; val k3=t(2)._2; var rv=t(3)._2
    rv+=k3; if (k3>k1) { k1=0; } else { k1-=k3; }
    rv+=k2/2; k2=k2%2; if (k2==1) { rv+=1; k2=0; if (k1>=2) { k1-=2; } else { k1=0; } }
    rv+=k1/4; k1=k1%4; if (k1!=0) { rv+=1; }
    println(rv)
  }
}

object cf extends App{
  val n = readInt()
  val arr = Array.fill[Int](5)(0)
  var nums = readLine().split(" ").map(_.toInt)
  for (i <- 0 to n-1) {
    val x = nums(i)
    arr(x) += 1
  }
  var res = 0
  res += arr(4)
  res += arr(3)
  arr(1) -= arr(3)
  arr(1) = arr(1).max(0)
  arr(3) = 0
  res += arr(2)/2
  arr(2) = arr(2) % 2
  arr(1) += arr(2)
  res += arr(1)/4
  if (arr(1) % 4 != 0) res += 1
  //make it go
  println(res)
}

object cf extends App{
  val n = readInt()
  val arr = Array.fill[Int](5)(0)
  var nums = readLine().split(" ").map(_.toInt)
  for (i <- 0 to n-1) {
    val x = nums(i)
    arr(x) += 1
  }
  var res = 0
  res += arr(4)
  res += arr(3)
  arr(1) -= arr(3)
  arr(1) = arr(1).max(0)
  arr(3) = 0
  res += arr(2)/2
  arr(2) = arr(2) % 2
  arr(1) += arr(2)
  res += arr(1)/4
  if (arr(1) % 4 != 0) res += 1
  println(res)
}

object Solution158B extends Application {

  def solution() {
    val n = _int
    val groups = 1.to(n).map(_ => _int).groupBy(x => x).mapValues(seq => seq.size)

    val n1 = groups.get(1).getOrElse(0)
    val n2 = groups.get(2).getOrElse(0)
    val n3 = groups.get(3).getOrElse(0)
    val n4 = groups.get(4).getOrElse(0)
    val res = n4 + n3 + (n2 / 2 + n2 % 2)
    val left = n1 - n3 - (2 * n2%2)

    println(res + (if (left > 0) left / 4 else 0))
  }

  //////////////////////////////////////////////////
  import java.util.Scanner
  val SC: Scanner = new Scanner(System.in)
  def _line: String = SC.nextLine
  def _int: Int = SC.nextInt
  def _long: Long = SC.nextLong
  def _string: String = SC.next
  solution()
}

import scala.collection.mutable._
import scala.math._
import scala.util.control.Breaks.break
import scala.util.control.Breaks.breakable
import java.util._
object Main extends App {
  val sc = new Scanner(System.in)
  val n = sc.nextInt
  val t = for(i <- 1 to n) yield sc.nextInt
  val tc = for(i <- 0 to 4) yield t.count(_ == i)
  println(tc(4) + tc(3) + (tc(2)+1)/2 + (3+max(0, tc(1) - tc(3) - tc(2) % 2))/4)
}

import scala.collection.mutable._
import scala.math._
import scala.util.control.Breaks.break
import scala.util.control.Breaks.breakable
import java.util._
object Main extends App {
  val sc = new Scanner(System.in)
  val n = sc.nextInt
  val t = for(i <- 1 to n) yield sc.nextInt
  val tc = for(i <- 0 to 4) yield t.count(_ == i)
  println(tc(4) + tc(3) + (tc(2)+1)/2 + max(0, tc(1) - tc(3) - tc(2) % 2))
}

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

    val n = std.readInt()
    val line = std.readLine().split(" ").map(_.toInt)
    val counts = new Array[Int](5)
    line.foreach(x => counts(x) += 1)

    var counts2 = counts(2) / 2
    var notPairedCounts2 = counts(2) % 2
    val result = counts(4) + counts(3) + counts2 + notPairedCounts2 + Math.max(0, counts(1) - counts(3) - notPairedCounts2 * 2  )
    println(result)
  }
}

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

    val n = std.readInt()
    val line = std.readLine().split(" ").map(_.toInt)
    val counts = new Array[Int](5)
    line.foreach(x => counts(x) += 1)
    val counts2 = (counts(2) + 1) / 2
    val singlesLeft = Math.max(0, counts(1) - counts(3) - (counts2 % 2) * 2 )
    val result = counts(4) + counts(3) + counts2 + (singlesLeft + 3) / 4
    println(result)
  }
}

import scala.io.StdIn

object B {
  def main(args: Array[String]) = {
    val n = StdIn.readLine.toInt
    val s = StdIn.readLine.split(" ").map(_.toInt)
    val freqMap: Map[Int, Int] = s.groupBy(x => x).mapValues(_.length)

    var ans = freqMap.getOrElse(4, 0)
    ans += freqMap.getOrElse(3, 0)
    ans += (freqMap.getOrElse(2, 0) + 1) / 2
    ans += Math.max(freqMap.getOrElse(1, 0) - freqMap.getOrElse(3, 0) - (if (freqMap.getOrElse(2, 0) % 2 == 0) 0 else 1), 0)

    println(ans)
  }
}

import scala.io.StdIn
import scala.language.implicitConversions

object B {
  implicit def toInt(b: Boolean) = if (b) 1 else 0

  def main(args: Array[String]) = {
    val n = StdIn.readLine.toInt
    val s = StdIn.readLine.split(" ").map(_.toInt)
    val freqMap: Map[Int, Int] = s.groupBy(x => x).mapValues(_.length)

    val ones = freqMap.getOrElse(1, 0)
    val twos = freqMap.getOrElse(2, 0)
    val threes = freqMap.getOrElse(3, 0)
    val fours = freqMap.getOrElse(4, 0)

    val mod = twos % 2 == 1
    val ans = fours + threes + (twos + 1) / 2 + Math.max(ones - threes - mod, 0) / 4

    println(ans)
  }
}

import scala.io.StdIn
import scala.language.implicitConversions

object B {
  implicit def toInt(b: Boolean) = if (b) 1 else 0

  def main(args: Array[String]) = {
    val n = StdIn.readLine.toInt
    val s = StdIn.readLine.split(" ").map(_.toInt)
    val freqMap: Map[Int, Int] = s.groupBy(x => x).mapValues(_.length)

    val ones = freqMap.getOrElse(1, 0)
    val twos = freqMap.getOrElse(2, 0)
    val threes = freqMap.getOrElse(3, 0)
    val fours = freqMap.getOrElse(4, 0)

    val mod = twos % 2 == 1
    val ans = fours + threes + (twos + 1) / 2 + Math.max(ones - threes - mod + 3, 0) / 4
    println(ans)
  }
}

import scala.collection.mutable.ListBuffer;

object Taxi {

  def main(args: Array[String]): Unit = {
    val n = readInt
    val l = Array.fill(5)(0)
    for(x <- readLine().split(" ").map(_.toInt)) l(x) += 1
    if(l(3) >= l(1))
      println(l(4) + l(3) + math.ceil(l(2).toDouble/4).toInt)
    else
      println(l(4) + l(3) +  math.ceil((l(2) + l(1)-l(3)).toDouble / 4).toInt )
  }

}

import scala.collection.mutable.ListBuffer;

object Taxi {

  def main(args: Array[String]): Unit = {
    val n = readInt
    val l = Array.fill(n+1)(0)
    for(x <- readLine().split(" ").map(_.toInt)) l(x) += 1
    println(l(4) + l(3) + 2*l(2)/4 + l(3)-l(1)+3/4)

  }

}

import scala.collection.mutable.ListBuffer;

object Taxi {

  def main(args: Array[String]): Unit = {
    val n = readInt
    val l = Array.fill(5)(0)
    for(x <- readLine().split(" ").map(_.toInt)) l(x) += 1
    if(l(3) >= l(1))
      println(l(4) + l(3) + 2*l(2)/4 + (l(3)-l(1)+3)/4)
    else
      println(l(4) + l(3) + 2*l(2)/4 + (l(1)-l(3)+3)/4)
  }

}

import scala.collection.mutable.ListBuffer;

object Taxi {

  def main(args: Array[String]): Unit = {
    val n = readInt
    val l = Array.fill(5)(0)
    for(x <- readLine().split(" ").map(_.toInt)) l(x) += 1
    if(l(3) >= l(1))
      println(l(4) + l(3) + math.ceil(2*l(2).toDouble/4).toInt)
    else
      println(l(4) + l(3) +  math.ceil(2*l(2).toDouble/4).toInt + (l(1)-l(3)+3)/4)
  }

}

import scala.collection.mutable.ListBuffer;

object Taxi {

  def main(args: Array[String]): Unit = {
    val n = readInt
    val l = Array.fill(n+1)(0)
    for(x <- readLine().split(" ").map(_.toInt)) l(x) += 1
    println(l(4) + l(3) + 2*l(2)/4 + (math.max(l(3)-l(1), 0)+3)/4)

  }

}

import scala.io.StdIn

object p158b extends App {

  private val n = StdIn.readLine.toInt
  val array=new Array[Int](5)

  val line=StdIn.readLine.split(" ").map(_.toInt).sortBy(identity).reverse
  for (i<- line ){
    array(i)+=1
  }

  var sum=array(4)
  if(array(3)>array(1)) {
    sum+=array(3)
    array(1)=0
  }
  else{
    sum+=array(3)
    array(1)-=array(3)
  }

  sum+=array(2)/2
  val remain=array(2)%2

  if(remain==1){
    if(array(1)>2){
      array(1)-=2
      sum+=1
    }
    else{
      sum+=1
    }
  }

  sum+=array(1)/4
  val remain1=array(1)%4
  if(remain1>0){
    sum+=1
  }

  print(sum)
}

import scala.io.StdIn

object p158b extends App {

  private val n = StdIn.readLine.toInt
  val array=new Array[Int](5)

  val line=StdIn.readLine.split(" ").map(_.toInt).sortBy(identity).reverse
  for (i<- line ){
    array(i)+=1
  }

  var sum=array(4)
  if(array(3)>array(1)) {
    sum+=array(3)
    array(1)=0
  }
  else{
    sum+=array(3)
    array(1)-=array(3)
  }

  sum+=array(2)/2
  val remain=array(2)%2

  if(remain==1){
    if(array(1)>2){
      array(1)-=2
      sum+=1
    }
    else if(array(1)==1){
      array(1)=0
      sum+=1
    }
    else{
      sum+=1
    }
  }

  sum+=array(1)/4
  val remain1=array(1)%4
  if(remain1>0){
    sum+=1
  }

  print(sum)
}

import collection.immutable.IndexedSeq
import collection.mutable.ArrayBuffer
import java.util.Scanner

object B extends App {
	val in = new Scanner(System.in)
	val n = in.nextInt()
	val s = for (_ <- Array.range(1, n)) yield in.nextInt()
	val cars = (ArrayBuffer[Int]() /: s.sorted(Ordering[Int].reverse)) {
		def firstFit(currentCars: ArrayBuffer[Int], numberOfFriends: Int): ArrayBuffer[Int] = {
			val firstFitIndex = currentCars.indexWhere(4 - _ >= numberOfFriends)
			if (firstFitIndex == -1) {
				currentCars += numberOfFriends
			} else {
				currentCars(firstFitIndex) += numberOfFriends
			}
			currentCars
		}
		firstFit
	}
	println(cars.size)
}

import scala.math._

object Taxy extends App{

  import scala.collection.mutable.Map
  val n = readInt
  val arr = readLine.split(" ").map(_.toInt)
  val mp = Map[Int, Int]()

  (1 to 4).foreach(x => mp(x) = 0)
  arr.foreach(x => mp(x) += 1)

  val four = mp(4)
  val third = mp(3)
    mp(1) = max(mp(1) - mp(3), 0)
  val second = mp(2) / 2 + max(min(2 * (mp(2) % 2), mp(1)), mp(2) % 2)
    mp(1) = max(mp(1) - 2 * (mp(2) % 2), 0)
  val first = mp(1) / 4 + {if( (mp(1) % 4) != 0) 1 else 0}

  println(first + second + third + four)

}

import scala.util.Sorting

object _158B extends App
{
  val n = readLine().toInt
  val groups = (readLine().split(" ") map (_.toInt)).sortWith(_ > _)
  var b = n - 1
  var cur = 0
  var ans = 0

  for ( a <- 0 until n ; if a <= b ) {
    if (groups(a) + groups(b) > 4) {
      ans += 1
    } else {
      ans += 1
      b -= 1
    }
  }

  println(ans)
}

import scala.util.Sorting

object _158B extends App
{
  val n = readLine().toInt
  var fours = 0
  var threes = 0
  var twos = 0
  var ones = 0
  val groups = (readLine().split(" ") map (_.toInt)) foreach (x =>
  x match {
    case 4 => fours += 1
    case 3 => threes += 1
    case 2 => twos += 1
    case 1 => ones += 1
    case _ => println(x)
  })
  //println(fours + " " + threes + " " + twos + " " + ones)
  var ans = fours

  while (threes > 0) {
    if (threes >= ones) {
      ans += 1
      threes -= 1
      ones -= 1
    } else {
      ans += 1
      threes -= 1
    }
  }

  while (twos > 0) {
    if (twos >= 2) {
      twos -= 2
      ans += 1
    } else if (ones >= 2) {
      twos -= 1
      ones -= 2
      ans += 1
    } else {
      twos -= 1
      ans += 1
    }
  }

  while (ones >= 4) {
    ans += 1
    ones -= 4
  }
  if (ones > 0) {
    ans += 1
  }

  println(ans)
}

import java.util.Scanner
import java.io.PrintWriter
import scala.annotation.tailrec
import scala.collection.mutable
import scala.util.Random

object P158B extends App {
  val sc = new Scanner(System.in)
  val out = new PrintWriter(System.out)

  val N = sc.nextInt
  val s = List.fill(N)(sc.nextInt).groupBy(identity[Int]).map(x => (x._1 -> x._2.length))

  def solve: Int =
    if (s(1) == s(2)) s(4) + s(2) / 2 + s(2) % 2 + s(1)
    else s(4) + s(2) / 2 + (s(3) max s(1))

  out.println(solve)
  out.close
}

import java.util.Scanner
import java.io.PrintWriter
import scala.annotation.tailrec
import scala.collection.mutable
import scala.util.Random

object P158B extends App {
  val sc = new Scanner(System.in)
  val out = new PrintWriter(System.out)

  val N = sc.nextInt
  val s = List.fill(N)(sc.nextInt).groupBy(identity[Int]).map(x => (x._1 -> x._2.length))
  val t = for (i <- 1 to 4) yield s.getOrElse(i, 0)

  def solve: Int =
    if (t(0) > t(2)) t(3) + t(0) + t(1) / 2
    else t(3) + t(2) + t(1) / 2 + t(1) % 2

  out.println(solve)
  out.close
}

import java.util.Scanner
import java.io.PrintWriter
import scala.annotation.tailrec
import scala.collection.mutable
import scala.util.Random

object P158B extends App {
  val sc = new Scanner(System.in)
  val out = new PrintWriter(System.out)

  val N = sc.nextInt
  val s = List.fill(N)(sc.nextInt).groupBy(identity[Int]).map(x => (x._1 -> x._2.length))

  def solve: Int =
    if (s(1) == s(3)) s(4) + s(2) / 2 + s(2) % 2 + s(1)
    else s(4) + s(2) / 2 + (s(3) max s(1))

  out.println(solve)
  out.close
}

import java.util.Scanner

object R158_B extends App {
  val sc = new Scanner(System.in)

  val n = sc.nextInt()
  val groups = for(i <- 0 until n) yield sc.nextInt()

  println(process(groups))

  def process(groups:Seq[Int]):Int = {
    var a = new Array[Int](4)
    groups.foreach(g => {
      val k = g-1
      a(k)=a(k)+1
    })
    var c = 0
    c += a(3)
    c += a(2)
    if(a(2)<a(0)){
      a(0)=a(0)-a(2)
    }else{
      a(0)=0
    }
    c += a(1)/2
    if(a(1)%2==1){
      c += 1
      if(a(0)>2){
        a(0)=a(0)-2
      }else{
        a(0)=0
      }
    }
    c += a(0)/4
    c
  }
}

object Taxi {
	def main (args: Array[String]) {
		val scanner = new java.util.Scanner(System.in)
				val n = scanner.nextInt
				var remainder = 4
				var number = 1
				for (i <- 1 to n) {
					remainder = remainder - scanner.nextInt
					if (remainder <= 0) {
						number = number + 1
								remainder = remainder + 4
					}
				}
		println(number)
	}
}

object Taxi {
	var availableCars = collection.mutable.Map[Int,Int]((1,0), (2,0), (3,0))

			def addCar (index: Int) {
		availableCars += index -> (availableCars(index) + 1)
	}

	def removeCar (index: Int) {
		availableCars += index -> (availableCars(index) - 1)
	}

	def main (args: Array[String]) {
		val scanner = new java.util.Scanner(System.in)
				val n = scanner.nextInt
				var number = 0
				for (i <- 1 to n) {
					val current = scanner.nextInt
							current match {
							case 4 =>
							number = number + 1
							case 3 =>
							if (availableCars(1) > 0) {
								removeCar(1)
								number = number + 1
							}
							else {
								addCar(3)
							}
							case 2 =>
							if (availableCars(2) > 0) {
								removeCar(2)
								number = number + 1
							}
							else {
								addCar(2)
							}
							case 1 =>
							if (availableCars(3) > 0) {
								removeCar(3)
								number = number + 1
							}
							else {
								addCar(1)
							}
					}
				}

		while (availableCars(3) > 0 && availableCars(1) > 0) {
			number = number + 1
					removeCar(3)
					removeCar(1)
		}
		while (availableCars(2)>1) {
			val div2 = availableCars(2) / 2
					number = number + div2
					availableCars += 2 -> availableCars(2) % 2
		}
		if (availableCars(2) > 0 && availableCars(1) / 2 > 0) {
			if (availableCars(2) - (availableCars(1) / 2) > 0) {
			  val tmp = availableCars(2) - (availableCars(1) / 2)
				availableCars += 2 -> tmp
				number = number + (availableCars(1) / 2)
				availableCars += 1 -> availableCars(1) % 2
			}
			else {
			  availableCars += 1 -> (availableCars(1) - (2* availableCars(2)))
				number = number + availableCars(2)
			  availableCars += 2 -> 0
			}
		}
		number = number + availableCars(1) / 4
		availableCars += 1 -> availableCars(1) % 4
		println(number+availableCars(3)+availableCars(2)+availableCars(1))
	}
}

object Taxi {
	def main (args: Array[String]) {
		val scanner = new java.util.Scanner(System.in)
				val n = scanner.nextInt
				var availableCars = collection.mutable.Set[Int]()
				var number = 0
				for (i <- 1 to n) {
					val current = scanner.nextInt
					current match {
					case 4 =>
					number = number + 1
					case 3 =>
					if (availableCars contains 1) {
						availableCars -= 1
								number = number + 1
					}
					else {
						availableCars += 3
					}
					case 2 =>
					if (availableCars contains 2) {
						availableCars -= 2
								number = number + 1
					}
					else {
						if (availableCars contains 1) {
							availableCars -= 1
									availableCars += 3
						}
						else {
						  availableCars += 2
 						}
					}
					case 1 =>
					if (availableCars contains 3) {
						availableCars -= 3
								number = number + 1
					}
					else {
						if (availableCars contains 2) {
							availableCars -= 2
									availableCars += 3
						}
						else {
							if (availableCars contains 1) {
								availableCars -= 1
										availableCars += 2
							}
							else {
								availableCars += 1
							}
						}
					}
					}
				}
		println(availableCars.size+number)
	}
}

object Taxi {
	var availableCars = collection.mutable.Map[Int,Int]((1,0), (2,0), (3,0))

			def addCar (index: Int) {
		availableCars += index -> (availableCars(index) + 1)
	}

	def removeCar (index: Int) {
		availableCars += index -> (availableCars(index) - 1)
	}

	def main (args: Array[String]) {
		val scanner = new java.util.Scanner(System.in)
				val n = scanner.nextInt
				var number = 0
				for (i <- 1 to n) {
					val current = scanner.nextInt
							current match {
							case 4 =>
							number = number + 1
							case 3 =>
							if (availableCars(1) > 0) {
								removeCar(1)
								number = number + 1
							}
							else {
								addCar(3)
							}
							case 2 =>
							if (availableCars(2) > 0) {
								removeCar(2)
								number = number + 1
							}
							else {
								addCar(2)
							}
							case 1 =>
							if (availableCars(3) > 0) {
								removeCar(3)
								number = number + 1
							}
							else {
								addCar(1)
							}
					}
				}

		while (availableCars(3) > 0 && availableCars(1) > 0) {
			number = number + 1
					removeCar(3)
					removeCar(1)
		}
		while (availableCars(2) > 1) {
			val div2 = availableCars(2) / 2
					number = number + div2
					availableCars += 2 -> availableCars(2) % 2
		}
		if (availableCars(2) == 1) {
			removeCar(2)
			if (availableCars(1) >= 2) {
				removeCar(1)
				removeCar(1)
			}
			else {
				availableCars += 1 -> 0
			}
			number = number + 1
		}

		number = number + availableCars(1) / 4
				availableCars += 1 -> availableCars(1) % 4
/**
				println("------------")
				println("number: "+number)
				println("availableCars: "+availableCars)
				println("------------")
**/
				println(number+availableCars(3)+availableCars(2)+availableCars(1))
	}
}

object Taxi {
	var availableCars = collection.mutable.Map[Int,Int]((1,0), (2,0), (3,0))

			def addCar (index: Int) {
		availableCars += index -> (availableCars(index) + 1)
	}

	def removeCar (index: Int) {
		availableCars += index -> (availableCars(index) - 1)
	}

	def main (args: Array[String]) {
		val scanner = new java.util.Scanner(System.in)
				val n = scanner.nextInt
				var number = 0
				for (i <- 1 to n) {
					val current = scanner.nextInt
							current match {
							case 4 =>
							number = number + 1
							case 3 =>
							if (availableCars(1) > 0) {
								removeCar(1)
								number = number + 1
							}
							else {
								addCar(3)
							}
							case 2 =>
							if (availableCars(2) > 0) {
								removeCar(2)
										number = number + 1
							}
							else {
								if (availableCars(1) > 0) {
									removeCar(1)
									addCar(3)
								}
								else {
									addCar(2)
								}
							}
							case 1 =>
							if (availableCars(3) > 0) {
								removeCar(3)
								number = number + 1
							}
							else {
								if (availableCars(2) > 0) {
                      removeCar(2)
											addCar(3)
								}
								else {
									if (availableCars(1) > 0) {
                      removeCar(1)
											addCar(2)
									}
									else {
										addCar(1)
									}
								}
							}
					}
				}
		println(availableCars(1)+availableCars(2)+availableCars(3)+number)
	}
}

object Codeforces158B extends App{

  def TaxiNumber(ques:String):Int={
    var ans:Int=0
    val conv=ques.split(" ").map(_.toInt)
    var numset:Array[Int]=Array(0,0,0,0,0)
    for (i <- conv){
      numset(i)+=1
    }
    ans+=numset(4)
    if (numset(3)<=numset(1)){
      ans+=numset(3)
      var temp=numset(1)-numset(3)
      if (numset(2)%2==0){
        ans+=numset(2)/2
        ans+=temp/4
        if (temp%4!=0){
          ans+=1
        }
      }
      else{
        ans+=numset(2)/2+1
        temp-=2
        ans+=temp/4
        if (temp%4!=0){
          ans+=1
        }
      }
    }
    else{
      ans+=numset(3)
      ans+=numset(2)/2
      if (numset(2)%2==1){
        ans+=1
      }
    }
    return ans
  }

  val s:Int=scala.io.StdIn.readInt
  val k=scala.io.StdIn.readLine
  println(TaxiNumber(k))

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val cTwo = counts(2) / 2

  val mTwo = counts(2) * 2 % 4 / 2

  val cFour = counts(4)

  if(!counts.contains(2)) {

  }

//  println("twos -> " + counts(2))
//
//  println("mod from twos -> " + counts(2) * 2 % 4)
//
//  println("fours -> " + counts(4))
//
//  println("threes -> " + counts(3))
//
//  println("ones -> " + counts(1))

  val combinedCount = if (counts(3) == counts(1)) counts(3) else counts(3).min(counts(1))

  val bigger = if (counts(3) > counts(1)) "three" else if (counts(3) == counts(1)) "equal" else "one"

  if (bigger == "one") {
    val cOne = Math.abs(counts(3) - counts(1))
    if (mTwo == 0)  println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)
    else
      if (cOne > 2)
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4 + 1)
      else
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)

  } else if (bigger == "equal"){
    println(combinedCount)
    println(cTwo + cFour + mTwo  + combinedCount)
  }
  else {
    val cThree = Math.abs(counts(3) - counts(1))
//    println(cTwo)
//    println(cFour)
//    println(mTwo)
//    println(cThree)
//    println(combinedCount)
    println(cTwo + cFour + mTwo + cThree + combinedCount)
  }

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val fTwo = counts(2) / 2

  val twoLeft = counts(2) * 2 % 4

  //четверки собранны
  val fFour = counts(4)

  //число скомбенированные 3 и 1
  val (fThreeOne, left:(Int, Int)) = if (counts(3) == counts(1)) (counts(3), (0, 0)) else {
    val min = counts(3).min(counts(1))
    (min, (Map(3 -> counts(3), 1 -> counts(1)).maxBy(_._2)._1, Math.abs(counts(3) - counts(1))))
  }

  // комбинируем 2 с 1

  val (fTwoOne:Int, left1:(Int, Int)) = if (twoLeft != 0) left match  {
    case (0, 0) => (0, left)
    case (num:Int, count:Int) if num == 3 => (0, left)
    case (num:Int, count:Int) if num == 1 => if (count >= 2) (1, (num, count - 2))
  }

  val fLeft = if (left1._1 == 3)  left1._2 else {
    if (left1._2 < 4) {
      1
    } else {
      val modQ = if (left1._2 % 4 == 0) 0 else 1
      left1._2 / 4 + modQ
    }
  }

  println(fTwo + fFour + fLeft + fThreeOne + fTwoOne)

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val cTwo = counts(2) / 2

  val mTwo = counts(2) * 2 % 4 / 2

  val cFour = counts(4)

  if(!counts.contains(2)) {

  }

//  println("twos -> " + counts(2))
//
//  println("mod from twos -> " + counts(2) * 2 % 4)
//
//  println("fours -> " + counts(4))
//
//  println("threes -> " + counts(3))
//
//  println("ones -> " + counts(1))

  val combinedCount = if (counts(3) == counts(1)) counts(3) else counts(3).min(counts(1))

  val bigger = if (counts(3) > counts(1)) "three" else if (counts(3) == counts(1)) "equal" else "one"

  if (bigger == "one") {
    val cOne = Math.abs(counts(3) - counts(1))
    if (mTwo == 0)  {
      if (cOne/ 4 == 0 && cOne > 0 && cOne < 4) println(cTwo + cFour + combinedCount + 1)
      else println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)
    }
    else
      if (cOne > 2) {
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4 + 1) }
      else
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)

  } else if (bigger == "equal"){
    println(cTwo + cFour + mTwo  + combinedCount)
  }
  else {
    val cThree = Math.abs(counts(3) - counts(1))
//    println(cTwo)
//    println(cFour)
//    println(mTwo)
//    println(cThree)
//    println(combinedCount)
    println(cTwo + cFour + mTwo + cThree + combinedCount)
  }

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val fTwo = counts(2) / 2

  val twoLeft = counts(2) * 2 % 4

  //четверки собранны
  val fFour = counts(4)

  //число скомбенированные 3 и 1
  val (fThreeOne, left:(Int, Int)) = if (counts(3) == counts(1)) (counts(3), (0, 0)) else {
    val min = counts(3).min(counts(1))
    (min, (Map(3 -> counts(3), 1 -> counts(1)).maxBy(_._2)._1, Math.abs(counts(3) - counts(1))))
  }

  // комбинируем 2 с 1
  val (fTwoOne:Int, left1:(Int, Int)) = if (twoLeft != 0)  left match {

    case (0, 0) => (0, left)
    case (num: Int, count: Int) if num == 3 => (1, left)
    case (num: Int, count: Int) if num == 1 => if (count >= 2) (1, (num, count - 2)) else (1,(0, 0))

  } else (0, left)

  val fLeft = if (left1._1 == 3)  left1._2 else {
    if (left1._2 < 4 && left1._2 != 0) {
      1
    } else if (left1._2 == 0) {
      0
    } else {
      val modQ = if (left1._2 % 4 == 0) 0 else 1
      left1._2 / 4 + modQ
    }
  }
  println(fTwo + fFour + fLeft + fThreeOne + fTwoOne)

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val cTwo = counts(2) / 2

  val mTwo = counts(2) * 2 % 4

  val cFour = counts(4)

  if(!counts.contains(2)) {

  }

//  println("twos -> " + counts(2))
//
//  println("mod from twos -> " + counts(2) * 2 % 4)
//
//  println("fours -> " + counts(4))
//
//  println("threes -> " + counts(3))
//
//  println("ones -> " + counts(1))

  val combinedCount = if (counts(3) == counts(1)) counts(3) else counts(3).min(counts(1))

  val bigger = if (counts(3) > counts(1)) "three" else if (counts(3) == counts(1)) "equal" else "one"

  if (bigger == "one") {
    val cOne = Math.abs(counts(3) - counts(1))
    if (mTwo == 0)  println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)
    else
      if (cOne > 2)
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4 + 1)
      else
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)

  } else if (bigger == "equal"){
    println(cTwo + cFour + 1  + combinedCount)
  }
  else {
    val cThree = Math.abs(counts(3) - counts(1))
//    println(cTwo)
//    println(cFour)
//    println(mTwo)
//    println(cThree)
//    println(combinedCount)
    println(cTwo + cFour + 1 + cThree + combinedCount)
  }

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val fTwo = counts(2) / 2

  val twoLeft = counts(2) * 2 % 4

  //четверки собранны
  val fFour = counts(4)

  //число скомбенированные 3 и 1
  val (fThreeOne, left:(Int, Int)) = if (counts(3) == counts(1)) (counts(3), (0, 0)) else {
    val min = counts(3).min(counts(1))
    (min, (Map(3 -> counts(3), 1 -> counts(1)).maxBy(_._2)._1, Math.abs(counts(3) - counts(1))))
  }
//  println(left)

  // комбинируем 2 с 1
  val (fTwoOne:Int, left1:(Int, Int)) = if (twoLeft != 0)  left match {

    case (0, 0) => (0, left)
    case (num: Int, count: Int) if num == 3 => (1, left)
    case (num: Int, count: Int) if num == 1 => if (count >= 2) (1, (num, count - 2)) else (1,(0, 0))

  } else (0, left)

  val fLeft = if (left1._1 == 3)  left1._2 else {
    if (left1._2 < 4 && left1._2 != 0) {
      1
    } else if (left1._2 == 0) {
      0
    } else {
      val modQ = if (left1._2 % 4 == 0) 0 else 1
      left1._2 / 4 + modQ
    }
  }
  println(fTwo + fFour + fLeft + fThreeOne + fTwoOne)

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val cTwo = counts(2) / 2

  val mTwo = counts(2) * 2 % 4 / 2

  val cFour = counts(4)

  if(!counts.contains(2)) {

  }

//  println("twos -> " + counts(2))
//
//  println("mod from twos -> " + counts(2) * 2 % 4)
//
//  println("fours -> " + counts(4))
//
//  println("threes -> " + counts(3))
//
//  println("ones -> " + counts(1))

  val combinedCount = if (counts(3) == counts(1)) counts(3) else counts(3).min(counts(1))

  val bigger = if (counts(3) > counts(1)) "three" else if (counts(3) == counts(1)) "equal" else "one"

  if (bigger == "one") {
    val cOne = Math.abs(counts(3) - counts(1))
    if (mTwo == 0)  println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)
    else
      if (cOne > 2)
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4 + 1)
      else
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)

  } else if (bigger == "equal"){
    println(cTwo + cFour + mTwo  + combinedCount)
  }
  else {
    val cThree = Math.abs(counts(3) - counts(1))
//    println(cTwo)
//    println(cFour)
//    println(mTwo)
//    println(cThree)
//    println(combinedCount)
    println(cTwo + cFour + mTwo + cThree + combinedCount)
  }

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val fTwo = counts(2) / 2

  val twoLeft = counts(2) * 2 % 4

  //четверки собранны
  val fFour = counts(4)

  //число скомбенированные 3 и 1
  val (fThreeOne, left:(Int, Int)) = if (counts(3) == counts(1)) (counts(3), (0, 0)) else {
    val min = counts(3).min(counts(1))
    (min, (Map(3 -> counts(3), 1 -> counts(1)).maxBy(_._2)._1, Math.abs(counts(3) - counts(1))))
  }
  println(left)

  // комбинируем 2 с 1
  val (fTwoOne:Int, left1:(Int, Int)) = if (twoLeft != 0)  left match {

    case (0, 0) => (0, left)
    case (num: Int, count: Int) if num == 3 => (1, left)
    case (num: Int, count: Int) if num == 1 => if (count >= 2) (1, (num, count - 2)) else (1,(0, 0))

  } else (0, left)

  val fLeft = if (left1._1 == 3)  left1._2 else {
    if (left1._2 < 4 && left1._2 != 0) {
      1
    } else if (left1._2 == 0) {
      0
    } else {
      val modQ = if (left1._2 % 4 == 0) 0 else 1
      left1._2 / 4 + modQ
    }
  }
  println(fTwo + fFour + fLeft + fThreeOne + fTwoOne)

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val cTwo = counts(2) / 2

  val mTwo = counts(2) * 2 % 4

  val cFour = counts(4)

  if(!counts.contains(2)) {

  }

//  println("twos -> " + counts(2))
//
//  println("mod from twos -> " + counts(2) * 2 % 4)
//
//  println("fours -> " + counts(4))
//
//  println("threes -> " + counts(3))
//
//  println("ones -> " + counts(1))

  val combinedCount = counts(3).min(counts(1))

  val bigger = if (counts(3) > counts(1)) "three" else "one"

  if (bigger == "one") {
    val cOne = Math.abs(counts(3) - counts(1))
    if (mTwo == 0)  println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)
    else
      if (cOne > 2)
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4 + 1)
      else
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)

  } else {
    val cThree = Math.abs(counts(3) - counts(1))
//    println(cTwo)
//    println(cFour)
//    println(mTwo)
//    println(cThree)
//    println(combinedCount)
    println(cTwo + cFour + 1 + cThree + combinedCount)
  }

}

/**
 * Created by vol on 9/16/14.
 */
object B158 extends App{
  val n = readInt()
  val friends = readLine().split(" ").map(_.toInt)
  val counts = friends.foldLeft(Map(1 -> 0, 2 -> 0, 3 -> 0, 4 -> 0)) {
    (count, fr) => count + (fr -> (count.getOrElse(fr, 0) + 1))
  }

  val cTwo = counts(2) / 2

  val mTwo = counts(2) * 2 % 4 / 2

  val cFour = counts(4)

  if(!counts.contains(2)) {

  }

//  println("twos -> " + counts(2))
//
//  println("mod from twos -> " + counts(2) * 2 % 4)
//
//  println("fours -> " + counts(4))
//
//  println("threes -> " + counts(3))
//
//  println("ones -> " + counts(1))

  val combinedCount = if (counts(3) == counts(1)) counts(3) else counts(3).min(counts(1))

  val bigger = if (counts(3) > counts(1)) "three" else if (counts(3) == counts(1)) "equal" else "one"

  if (bigger == "one") {
    val cOne = Math.abs(counts(3) - counts(1))
    if (mTwo == 0)  {
      if (cOne/ 4 == 0 && cOne > 0 && cOne < 4) println(cTwo + cFour + combinedCount + 1)
      else println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)
    }
    else
      if (cOne > 2) {
        println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4 + 1) }
      else
        if (cOne + mTwo < 4)  println(cTwo + cFour + combinedCount + 1)
        else println(cTwo + cFour + combinedCount + cOne / 4 + cOne % 4)

  } else if (bigger == "equal"){
    println(cTwo + cFour + mTwo  + combinedCount)
  }
  else {
    val cThree = Math.abs(counts(3) - counts(1))
//    println(cTwo)
//    println(cFour)
//    println(mTwo)
//    println(cThree)
//    println(combinedCount)
    println(cTwo + cFour + mTwo + cThree + combinedCount)
  }

}

object Main {
  def main(args: Array[String]) {
    val n = readInt()
    val arr = readLine().split(" ").map(_.toInt)
    var g1, g2, g3, g4 = 0
    arr.foreach{
      case 1 => g1 += 1
      case 2 => g2 += 1
      case 3 => g3 += 1
      case 4 => g4 += 1
    }
    var ga = g4 + g3 + ((g2 + 1) / 2) + ((g4 - g3 - g2 % 2 + 3) / 4)
    println(ga)
  }
}

object Main {
  def main(args: Array[String]) {
    val n = readInt()
    val arr = readLine().split(" ").map(_.toInt)
    var g1, g2, g3, g4 = 0
    arr.foreach{
      case 1 => g1 += 1
      case 2 => g2 += 1
      case 3 => g3 += 1
      case 4 => g4 += 1
    }
    var ga = g4 + g3 + ((g2 + 1) / 2) + (((g1 - g3 - g2 % 2).max(0) + 3) / 4)
    println(ga)
  }
}

object P279D {

  def Read : Array[Int] = readLine().split(" ").map(_.toInt);

  def main ( args : Array[String] ) {
    Read
    println ((Read.sum - 1) / 4 + 1)
    /*println (Read.foldRight(0)(_ + _))*/
  }
}

object P279D {

  def main ( args : Array[String] ) {
    readLine().split(" ").map(_.toInt);
    val A : Array[Int] = readLine().split(" ").map(_.toInt);
    val C4 = A.count(_ == 4)
    val C3 = A.count(_ == 3)
    var C2 = A.count(_ == 2)
    var C1 = A.count(_ == 1)

    C1 -= (C2 % 2) * 2
    if(C1 < 0) C1 = 0

    C1 -= C3
    if(C1 < 0) C1 = 0
    if(C2 == 0) C2 = -1
    println (C4 + (C2 - 1) / 2 + 1 + C1 / 4 + C3)

  }
}

object P279D {

  def Read : Array[Int] = readLine().split(" ").map(_.toInt);

  def main ( args : Array[String] ) {
    Read
    println ((Read.sum - 1) / 4)
    /*println (Read.foldRight(0)(_ + _))*/
  }
}

object P279D {

  def main ( args : Array[String] ) {
    readLine().split(" ").map(_.toInt);
    val A : Array[Int] = readLine().split(" ").map(_.toInt);
    val C4 = A.count(_ == 4)
    val C3 = A.count(_ == 3)
    val C2 = A.count(_ == 2)
    var C1 = A.count(_ == 1)

    C1 -= (C2 % 2) * 2
    if(C1 < 0) C1 = 0

    C1 -= C3
    if(C1 < 0) C1 = 0

    println (C4 + (C2 - 1) / 2 + 1 + C1 / 4 + C3)

  }
}

object P279D {

  def main ( args : Array[String] ) {
    readLine().split(" ").map(_.toInt);
    val A : Array[Int] = readLine().split(" ").map(_.toInt);
    val C4 = A.count(_ == 4)
    val C3 = A.count(_ == 3)
    val C2 = A.count(_ == 2)
    var C1 = A.count(_ == 1)

    C1 -= (C2 % 2) * 2
    if(C1 < 0) C1 = 0

    C1 -= C3
    if(C1 < 0) C1 = 0

    println (C4 + C2 / 2 + C1 / 4 + C3)

  }
}

import scala.io.StdIn._

object A_158 extends App {

  def sgn(i: Int) = if (i > 0) 1 else 0

  val n = readInt()
  val S = readLine().split(" ").map(_.toInt).groupBy(identity).mapValues(_.length).withDefaultValue(0)

  val a = Math.max(0, S(1) - S(3))
  val answer = S(4) + S(3) + a / 4 + S(2) / 2 + sgn(S(2) % 2 + a % 4)

  println(answer)
}

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

    import scala.io.StdIn

    val nGroups: Int = StdIn.readInt()
    val stringGroups: String = StdIn.readLine()

    /*var ones: Int = repetitions(stringGroups, "1")
    stringGroups = stringGroups.replace("1", "")
    var twos: Int = repetitions(stringGroups, "2")
    stringGroups = stringGroups.replace("2", "")
    var threes: Int = repetitions(stringGroups, "3")
    stringGroups = stringGroups.replace("3", "")
    var fours: Int = repetitions(stringGroups, "4")*/

    var counts: Array[Int] = repetitions(stringGroups)

    var count: Int = 0

    var ones: Int = counts(0)
    var twos: Int = counts(1)
    var threes: Int = counts(2)
    var fours: Int = counts(3)

    /*if (threes >= ones){
      println((fours + threes + Math.ceil(twos.asInstanceOf[Float]/2))
        .asInstanceOf[Int])
    } else {
      println((fours + threes + Math.ceil(twos.asInstanceOf[Float]/2) + Math
        .ceil((ones-threes).asInstanceOf[Float]/4)).asInstanceOf[Int])
    }*/

    count = fours
    count = count + threes
    if (threes > ones){
      ones = 0
    } else {
      ones = ones - threes
    }
    count = count + twos/2
    if (twos%2 == 0){
    } else {
      ones = ones + twos%2
    }
    count = count + Math.ceil(ones.asInstanceOf[Double]/4).asInstanceOf[Int]
    println(count)
  }

  def repetitions(string: String): Array[Int] ={
    val myString: String = string
    var count: Array[Int] = new Array[Int](4)

    for (i <- 0 until myString.length){
      myString.charAt(i) match {
        case '1' => count(0) = count(0) + 1
        case '2' => count(1) = count(1) + 1
        case '3' => count(2) = count(2) + 1
        case '4' => count(3) = count(3) + 1
        case _ =>
      }
    }

    count
  }
}

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

    import scala.io.StdIn

    val nGroups: Int = StdIn.readInt()
    var stringGroups: String = StdIn.readLine()

    var ones: Int = repetitions(stringGroups, "1")
    var twos: Int = repetitions(stringGroups, "2")
    var threes: Int = repetitions(stringGroups, "3")
    var fours: Int = repetitions(stringGroups, "4")

    if (threes >= ones){
      println((fours + threes + Math.ceil(twos.asInstanceOf[Float]/2))
        .asInstanceOf[Int])
    } else {
      println((fours + threes + Math.ceil(twos.asInstanceOf[Float]/2) + Math
        .ceil((ones-threes).asInstanceOf[Float]/4)).asInstanceOf[Int])
    }

  }

  def repetitions(string: String, indexOf: String): Int ={
    var myString: String = string
    var str1: String = ""
    var str2: String = ""
    var index: Int = 0
    var count: Int = 0

    while (myString contains indexOf){
      index = myString.indexOf(indexOf)
      if (index > 0){
        str1 = myString.substring(0, index)
      } else {
        str1 = ""
      }
      if (index < myString.size-1) {
        str2 = myString.substring(index + 1)
      } else {
        str2 = ""
      }
      myString = str1 + str2
      count = count + 1
    }

    return count
  }
}

object main extends App {
    import java.io.{InputStream, PrintStream}
    import java.util.Scanner
    def solve(input: InputStream, output: PrintStream): Unit = {
    val sc = new Scanner(input)
    val n = sc.nextInt()
    val groups = (1 to n).map( _ => sc.nextInt())
    val counters =((1 to 4) map ( c => groups.count( _ == c))).toArray

    var c1 = counters(0)
    var c2 = counters(1)
    var c3 = counters(2)
    var c4 = counters(3)

    var result = c4
    if( c3 > c1){
      result += c1
      c3 -= c1
      c1 -= 0
    }else{
      result += c3
      c1 -= c3
      c3 = 0
    }

    result += c2 / 2
    c2 %= 2

    if( c2 > (c1 +1)/2){
      //hay más grupos de 2 que pares de 1
      result += c2
      c1 = 0
      c2 = 0
    }else{
      result += c2
      c1 -= c2*2
      c2 = 0
    }

    result += (c1+3)/4
    result += c2 + c3
    output.println(result)
  }
    solve(System.in,System.out)
}

object Main {

  def main(args: Array[String]): Unit = {
    val _ = readLine
    var res = 0;
    var count = new Array[Int](5)
    for(x <- readLine().split(" ").map(_.toInt))count(x) += 1
    count(1) = Math.max(0,count(1)-count(3))
    res = count(4)+count(3)+(count(2)*2+4*count(1)+3)/4
    print(res)
  }

}

import java.util.Scanner

object Taxi extends App {
  def parseInts(str: String, numIterations: Integer) = {
    val scanner = new Scanner(str)
    val res = (0 until numIterations) map (_ => scanner.nextInt())
    scanner.close()
    res
  }

  val Seq(numFamilies) = parseInts(Console.readLine(), 1)
  val families = parseInts(Console.readLine(), numFamilies)
  val groupings = Array.fill[Int](5)(0)

  families.foreach(fam => groupings(fam) = groupings(fam) + 1)

  var total = 0

  families.foreach(fam => {
    val remainder = 4 - fam
    var upperBound = math.max(remainder, fam)
    var lowerBound = math.min(remainder, fam)

    if (groupings(fam) > 0) {
      groupings(fam) -= 1
      total += 1
      var famAdded = fam
      while (famAdded < 4 && lowerBound <= upperBound) {
        if (groupings(upperBound) > 0) {
          groupings(upperBound) -= 1
          famAdded += upperBound
        } else {
          upperBound -= 1
        }
      }
    }
  })

  println(total)
}

import java.util.Scanner

object Taxi extends App {
  def parseInts(str: String, numIterations: Integer) = {
    val scanner = new Scanner(str)
    val res = (0 until numIterations) map (_ => scanner.nextInt())
    scanner.close()
    res
  }

  val Seq(numFamilies) = parseInts(Console.readLine(), 1)
  val families = parseInts(Console.readLine(), numFamilies)
  val groupings = Array.fill[Int](5)(0)

  families.foreach(fam => groupings(fam) = groupings(fam) + 1)

  var total = 0

  families.foreach(fam => {
    val remainder = 4 - fam
    var upperBound = remainder
    var lowerBound = 1

    if (groupings(fam) > 0) {
      groupings(fam) -= 1
      total += 1
      var famAdded = fam
      while (famAdded < 4 && lowerBound <= upperBound) {
        if (groupings(upperBound) > 0) {
          groupings(upperBound) -= 1
          famAdded += upperBound
        } else {
          upperBound -= 1
        }
      }
    }
  })

  println(total)
}

import java.util.Scanner

object Taxi extends App {
  def parseInts(str: String, numIterations: Integer) = {
    val scanner = new Scanner(str)
    val res = (0 until numIterations) map (_ => scanner.nextInt())
    scanner.close()
    res
  }

  val Seq(numFamilies) = parseInts(Console.readLine(), 1)
  val families = parseInts(Console.readLine(), numFamilies)
  val groupings = Array.fill[Int](5)(0)

  families.foreach(fam => groupings(fam) = groupings(fam) + 1)

  var total = 0

  families.foreach(fam => {
    val remainder = 4 - fam
    if (groupings(fam) > 0 && groupings(remainder) > 0) {
      groupings(fam) -= 1
      groupings(remainder) -= 1
      total += 1
    } else if (groupings(fam) > 0) {
      groupings(fam) -= 1
      total += 1
    }
  })

  println(total)
}

import java.util.Scanner

object Taxi extends App {
  def parseInts(str: String, numIterations: Integer) = {
    val scanner = new Scanner(str)
    val res = (0 until numIterations) map (_ => scanner.nextInt())
    scanner.close()
    res
  }

  val MAX_FAMILY_SIZE = 4
  val MIN_FAMILY_SIZE = 1

  val Seq(numFamilies) = parseInts(Console.readLine(), 1)
  val families = parseInts(Console.readLine(), numFamilies)
  val familiesBySize = Array.fill[Int](5)(0)

  families.foreach(fam => familiesBySize(fam) = familiesBySize(fam) + 1)

  var total = 0

  def placeInTaxi(famBySize: Array[Int], famSize: Int): Unit = {
    if (familiesBySize(famSize) > 0) {
      familiesBySize(famSize) -= 1
      total += 1
      var numInTaxi = famSize
      for {
        maybePlaceInTaxi <- (MAX_FAMILY_SIZE - famSize) to MIN_FAMILY_SIZE by -1
        if (numInTaxi < MAX_FAMILY_SIZE && familiesBySize(maybePlaceInTaxi) > 0)
      } yield {
        familiesBySize(maybePlaceInTaxi) -= 1
        numInTaxi += maybePlaceInTaxi
      }
    }
  }

  families.foreach(fam => placeInTaxi(familiesBySize, fam))

  println(total)
}

import scala.io.StdIn._
import scala.util.Sorting
import java.lang.Math._

object Taxi_158B extends App {
  val n = readInt
  val chs = readLine.split(" ").map(_.toInt)

  val gchs = Map(1->0, 2->0, 3->0, 4->0) ++ chs.groupBy((a: Int) => a).map(a => (a._1 -> a._2.length))

  val gchs1 = Map(
      4 -> gchs(4),
      3 -> gchs(3),
      2 -> gchs(2),
      1 -> (gchs(1) - min(gchs(1), gchs(3)))
          )

  val gchs2 = Map(
      4 -> gchs1(4),
      3 -> gchs1(3),
      2 -> (gchs1(2) + (if (gchs1(1) > 1 && gchs1(2) % 2 != 0) 1 else 0)),
      1 -> (if (gchs1(1) > 1 && gchs1(2) > 0) gchs1(1) - 2 else gchs1(1))
          )

  //println(gchs, gchs1, gchs2)
  val ans =
      gchs2(4) +
      gchs2(3) +
      gchs2(2) / 2 + (if (gchs2(2) % 2 != 0) 1 else 0) +
      gchs2(1) / 4 + (if (gchs2(1) % 4 != 0) 1 else 0)

  println(ans)
}

import scala.io.StdIn._
import scala.util.Sorting
import java.lang.Math._

object Taxi_158B extends App {
  val n = readInt
  val chs = readLine.split(" ").map(_.toInt)

  val gchs = Map(1->0, 2->0, 3->0, 4->0) ++ chs.groupBy((a: Int) => a).map(a => (a._1 -> a._2.length))

  val gchs1 = Map(
      4 -> gchs(4),
      3 -> gchs(3),
      2 -> gchs(2),
      1 -> (gchs(1) - min(gchs(1), gchs(3)))
          )

  val gchs2 = Map(
      4 -> gchs1(4),
      3 -> gchs1(3),
      2 -> (gchs1(2) + (if (gchs1(1) > 1 && gchs1(2) % 2 != 0) 1 else 0)),
      1 -> (if (gchs1(1) > 1 && gchs1(2) > 0) gchs1(1) - 2 else gchs1(1))
          )

  println(gchs, gchs1, gchs2)
  val ans =
      gchs2(4) +
      gchs2(3) +
      gchs2(2) / 2 + (if (gchs2(2) % 2 != 0) 1 else 0) +
      gchs2(1) / 4 + (if (gchs2(1) % 4 != 0) 1 else 0)

  println(ans)
}

import scala.io.StdIn._
import scala.util.Sorting
import java.lang.Math._

object Taxi_158B extends App {
  val n = readInt
  val chs = readLine.split(" ").map(_.toInt)

  val gchs = Map(1->0, 2->0, 3->0, 4->0) ++ chs.groupBy((a: Int) => a).map(a => (a._1 -> a._2.length))

  val gchs1 = Map(
      4 -> gchs(4),
      3 -> gchs(3),
      2 -> gchs(2),
      1 -> (gchs(1) - min(gchs(1), gchs(3)))
          )

  val gchs2 = Map(
      4 -> gchs1(4),
      3 -> gchs1(3),
      2 -> (gchs1(2) + (if (gchs1(1) > 1 && gchs1(2) % 2 != 0) 1 else 0)),
      1 -> (if (gchs1(1) > 0 && gchs1(2) > 0) gchs1(1) - min(gchs1(1), 2) else gchs1(1))
          )

  //println(gchs, gchs1, gchs2)
  val ans =
      gchs2(4) +
      gchs2(3) +
      gchs2(2) / 2 + (if (gchs2(2) % 2 != 0) 1 else 0) +
      gchs2(1) / 4 + (if (gchs2(1) % 4 != 0) 1 else 0)

  println(ans)
}

import scala.io.StdIn._
import scala.util.Sorting
import java.lang.Math._

object Taxi_158B extends App {
  val n = readInt
  val chs = readLine.split(" ").map(_.toInt)

  val gchs = Map(1->0, 2->0, 3->0, 4->0) ++ chs.groupBy((a: Int) => a).map(a => (a._1 -> a._2.length))

  val gchs1 = Map(
      4 -> gchs(4),
      3 -> gchs(3),
      2 -> gchs(2),
      1 -> (gchs(1) - min(gchs(1), gchs(3)))
          )

  val gchs2 = Map(
      4 -> gchs1(4),
      3 -> gchs1(3),
      2 -> (gchs1(2) + (if (gchs1(1) > 1 && gchs1(2) % 2 != 0) 1 else 0)),
      1 -> (if (gchs1(1) > 1) gchs1(1) - 2 else gchs1(1))
          )

  //println(gchs, gchs1, gchs2)
  val ans =
      gchs2(4) +
      gchs2(3) +
      gchs2(2) / 2 + (if (gchs2(2) % 2 != 0) 1 else 0)
      gchs2(1) + (if (gchs2(1) % 4 != 0) 1 else 0)

  println(ans)
}

object B00158 extends App {

  def oneIntLine = {
    val Seq(count) = parseInt(Console.readLine(), 1);
    count
  }

  def parseInt(str: String, count: Int): Seq[Int] = {
    val scanner = new java.util.Scanner(str)
    val res = (1 to count) map (_ => scanner.nextInt())
    scanner.close()
    res
  }
  def scanInts(count: Int): Seq[Int] = parseInt(Console.readLine, count)

  def frequency[T](seq: Seq[T]) = seq.groupBy(identity).mapValues(_.size).withDefaultValue(0)

  def partsNeededToCoverFull(fullLength: Int, partLength: Int) =
    Math.ceil(fullLength * 1.0 / partLength).toInt

  val count = oneIntLine
  val grouped = frequency(scanInts(count))
  val partialCount = grouped(4) + grouped(3) + partsNeededToCoverFull(grouped(2), 2)
  val vacantSeats = grouped(2) + (if (grouped(2) % 2 == 1) 2 else 0)
  val remainingSingles = if (grouped(1) > vacantSeats) grouped(1) - vacantSeats else 0
  val res = partialCount + partsNeededToCoverFull(remainingSingles, 4)
  println(res)
}

object B00158 extends App {

  def oneIntLine = {
    val Seq(count) = parseInt(Console.readLine(), 1);
    count
  }

  def parseInt(str: String, count: Int): Seq[Int] = {
    val scanner = new java.util.Scanner(str)
    val res = (1 to count) map (_ => scanner.nextInt())
    scanner.close()
    res
  }
  def scanInts(count: Int): Seq[Int] = parseInt(Console.readLine, count)

  def frequency[T](seq: Seq[T]) = seq.groupBy(identity).mapValues(_.size).withDefaultValue(0)

  val count = oneIntLine
  val grouped = frequency(scanInts(count))
  var oneCount = grouped(1)
  val partialCount = grouped(4) + grouped(3) + (Math.ceil(grouped(2) * 1.0 / 2)).toInt
  oneCount = oneCount - (if (oneCount > grouped(3)) oneCount - grouped(3) else 0)
  oneCount = oneCount - (if (grouped(2) % 2 == 1) 2 else 0)
  oneCount = if (oneCount < 0) 0 else oneCount
  val adjustment = (Math.ceil(oneCount / 4)).toInt
  println(partialCount + adjustment)
}