/*
codeforces,158B,B. Taxi
将n组学生送到目的地,每组学生包含1~4名学生
每辆车最多载4名学生,每个组的所有学生必须乘坐同一辆车,一辆车可以载多组的学生
最少需要多少辆车
输入
第一行: 一个数字,n
第二行: n个空格隔开的数字,表示第i组学生的人数
*/
/*
*/
#include <iostream>
#include <vector>
#define FULL_SEATS 4
int main(){
int n;std::cin>>n;
int ans = 0;
std::vector<int> counts(FULL_SEATS,0);//count of 1 2 3
//counts用于记录人数为1,2,3的组分别有几个,用counts[1],counts[2],counts[3]记录
for(int i = 0;i<n;++i){
int x;std::cin>>x;
if(x==FULL_SEATS){
//如果该组学生能坐满一辆空车,车数+1
ans++;
continue;
}else{
//如果该组学生不能坐满空车
if(counts[FULL_SEATS-x]>0){
//如果有互补的组,能凑满一辆车
--counts[FULL_SEATS-x];//互补的组数-1
ans++;//最终车数+1
continue;
}else{
//如果没有互补的组,该人数的组数+1
++counts[x];
}
}
}
int end = FULL_SEATS-1,head = 1;
//end记录当前剩余组中,人数最大的组的人数
//head记录当前剩余组中,人数最小的组的人数
while(end>=head){
while(counts[end]==0 && end>=head)--end;
while(counts[head]==0 && head<=end)++head;
if(end<head)break;
// while(counts[head]==0)++head;
int i = end;
int emptySeat = FULL_SEATS;
//一次装一辆车
while(emptySeat>=head){
//尽量装人数最多的组,直到人数最少的组都装不下为止
//保持i为当前能装下的组中最大的人数
while(counts[i]==0)--i;//counts[head]!=0,i>=head
int groups = std::min(emptySeat/i,counts[i]);
emptySeat-=groups*i;
counts[i]-=groups;
if(emptySeat<head){
//人数最小的组都装不下
break;
}else{
//人数正好为剩余的空位的组
i = emptySeat;
}
while(counts[head]==0)++head;
}
++ans;
}
std::cout<<ans;
}