After the lessons n groups of schoolchildren went outside and decided to visit Polycarpus to celebrate his birthday. We know that the i-th group consists of si friends (1 ≤ si ≤ 4), and they want to go to Polycarpus together. They decided to get there by taxi. Each car can carry at most four passengers. What minimum number of cars will the children need if all members of each group should ride in the same taxi (but one taxi can take more than one group)?

The first line contains integer n (1 ≤ n ≤ 105) — the number of groups of schoolchildren. The second line contains a sequence of integers s1, s2, ..., sn (1 ≤ si ≤ 4). The integers are separated by a space, si is the number of children in the i-th group.

Print the single number — the minimum number of taxis necessary to drive all children to Polycarpus.

NoteIn the first test we can sort the children into four cars like this:  the third group (consisting of four children),  the fourth group (consisting of three children),  the fifth group (consisting of three children),  the first and the second group (consisting of one and two children, correspondingly). There are other ways to sort the groups into four cars.

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

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

/*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;
}

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

}

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

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

/**
 * 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.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)
}

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

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

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

}

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

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

}

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

}

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

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