using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;
            bool oneLeft = false;
            bool twoLeft = false;
            bool threeLeft = false;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();
            int k1 = 0, k2 = 0, k3 = 0, k4 = 0;

            //////////////////////////////////////////////////////
            if (groupsList.Contains(4))
            {
                k4 = groupsList.Count - groupsList.IndexOf(4);
                answer += k4;
            }
            /////////////////////////////////////////////////////

            if (groupsList.Contains(2))
            {
                int startIndex = 0, endIndex = 0;
                startIndex = groupsList.IndexOf(2);

                if (groupsList.Contains(3))
                {
                    endIndex = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    endIndex = groupsList.IndexOf(4);
                }
                else
                {
                    endIndex = groupsList.Count;
                }

                if ((endIndex - startIndex) % 2 == 0)
                {
                    answer += (endIndex - startIndex) / 2;
                }
                else
                {
                    answer += (endIndex - startIndex) / 2;
                    twoLeft = true;
                }
            }

            ///////////////////////////////////////////////////////////////////
            if (groupsList.Contains(1) && groupsList.Contains(3))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else
                {
                    k1 = groupsList.IndexOf(3);
                }

                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                if (k1 == k3)
                {
                    answer += k1;
                }
                else
                {
                    if (k1 > k3)
                    {
                        answer += k3;
                        k1 -= k3;
                        oneLeft = true;
                    }
                    else
                    {
                        answer += k1;
                        k3 -= k1;
                        threeLeft = true;
                    }
                }
            }
            else if (groupsList.Contains(3))
            {
                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                answer += k3;
            }
            else if (groupsList.Contains(1))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else if (groupsList.Contains(3))
                {
                    k1 = groupsList.IndexOf(3);
                }
                else
                    k1 = groupsList.Count;

                answer += k1 / 4;
                if (k1 % 4 > 0)
                {
                    oneLeft = true;
                    k1 = k1 % 4;
                }
            }

            ///////////////////////////////////////////////////////////////

            if (threeLeft)
            {
                answer += k3;
            }

            if (oneLeft || twoLeft)
            {
                if (k1 > 2)
                {
                    answer++;
                    twoLeft = false;
                    k1 -= 2;

                    answer += k1 / 4;
                    if (k1 % 4 > 0)
                        answer++;
                }
                else
                {
                    twoLeft = false;
                    answer++;
                }
            }

            Console.WriteLine(answer);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            if (groupsList.Contains(4))
                answer += RemoveSingle(groupsList, 4); // all 4s

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                groupsList.Sort();
                double onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount && groupsList.Count % 2 == 0)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }
            else
            {
                while (groupsList.Contains(1) && groupsList.Contains(3))
                {
                    groupsList.RemoveAt(0);
                    groupsList.RemoveAt(groupsList.Count - 1);
                    answer++;
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
           // string groupsData = "1 1 1 1 1 1 1 1 1 1 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            if (groupsList.Contains(4))
                answer += RemoveSingle(groupsList, 4); // all 4s

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            groupsList.Sort();
            while (groupsList.Contains(1) && groupsList.Contains(3))
            {
                groupsList.RemoveAt(0);
                groupsList.RemoveAt(groupsList.Count-1);
                answer++;
            }

            //if (groupsList.Contains(3) && groupsList.Contains(1))
            //    answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            //if (groupsList.Contains(3) && groupsList.Contains(1))
            // answer += RemoveCouple(groupsList, 1, 3);

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's
            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "4 1";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer += RemoveSingle(groupsList, 4); // all 4s
            answer += RemoveCouple(groupsList, 2, 2); // all double 2s
            answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            answer += RemoveCouple(groupsList, 1, 3);
            answer += RemoveSingle(groupsList, 3); // all 3's
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            for (int i = 0; i < groupsList.Count; i++)
            {
                if (groupsList[i] == 1)
                {
                    pos.Add(i);
                    counter++;
                }

            }

            while (counter >= 4)
            {
                for (int i = 0; i < 4; i++)
                {
                    groupsList.RemoveAt(pos[pos.Count-1]);
                    pos.RemoveAt(pos.Count-1);
                }
                counter -= 4;
                answ++;
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            //string groupsData = Console.ReadLine();
            string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;
            bool oneLeft = false;
            bool twoLeft = false;
            bool threeLeft = false;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();
            int k1 = 0, k2 = 0, k3 = 0, k4 = 0;

            //////////////////////////////////////////////////////
            if (groupsList.Contains(4))
            {
                k4 = groupsList.Count - groupsList.IndexOf(4);
                answer += k4;
            }
            /////////////////////////////////////////////////////

            if (groupsList.Contains(2))
            {
                int startIndex = 0, endIndex = 0;
                startIndex = groupsList.IndexOf(2);

                if (groupsList.Contains(3))
                {
                    endIndex = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    endIndex = groupsList.IndexOf(4);
                }
                else
                {
                    endIndex = groupsList.Count;
                }

                if ((endIndex - startIndex) % 2 == 0)
                {
                    answer += (endIndex - startIndex) / 2;
                }
                else
                {
                    answer += (endIndex - startIndex) / 2;
                    twoLeft = true;
                }
            }

            ///////////////////////////////////////////////////////////////////
            if (groupsList.Contains(1) && groupsList.Contains(3))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else
                {
                    k1 = groupsList.IndexOf(3);
                }

                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                if (k1 == k3)
                {
                    answer += k1;
                }
                else
                {
                    if (k1 > k3)
                    {
                        answer += k3;
                        k1 -= k3;
                        oneLeft = true;
                    }
                    else
                    {
                        answer += k1;
                        k3 -= k1;
                        threeLeft = true;
                    }
                }
            }
            else if (groupsList.Contains(3))
            {
                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                answer += k3;
            }

            ///////////////////////////////////////////////////////////////

            if (threeLeft)
            {
                answer += k3;
            }

            if (oneLeft || twoLeft)
            {
                if (k1 > 2)
                {
                    answer++;
                    twoLeft = false;
                    k1 -= 2;

                    answer += k1 / 4;
                    if (k1 % 4 > 0)
                        answer++;
                }
                else
                {
                    twoLeft = false;
                    answer++;
                }
            }

            Console.WriteLine(answer);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
           // string groupsData = Console.ReadLine();
            string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();

            if (groupsList.Contains(4))
            {
                int startInxed = groupsList.IndexOf(4);
                answer += groupsList.Count - startInxed;
                groupsList.RemoveRange(startInxed, groupsList.Count - startInxed);
            }

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    int startIndex = groupsList.IndexOf(2);
                    int endIndex = groupsList.IndexOf(3);

                    if (endIndex < startIndex)
                    {
                        answer += RemoveCouple(groupsList, 2, 2);
                    }
                    else
                    {
                        answer += (endIndex - startIndex) / 2;
                        //if ((endIndex - startIndex) % 2 == 0)
                        //    answer++;

                        if (endIndex - startIndex > 1 && (endIndex - startIndex) % 2 == 0)
                        {
                            groupsList.RemoveRange(startIndex, endIndex - startIndex);
                        }
                        else if (endIndex - startIndex > 1)
                        {
                            groupsList.RemoveRange(startIndex, endIndex - startIndex - 1 );
                        }
                    }
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                double onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount && groupsList.Count % 2 == 0)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }
            else
            {
                while (groupsList.Contains(1) && groupsList.Contains(3))
                {
                    groupsList.RemoveAt(0);
                    groupsList.RemoveAt(groupsList.Count - 1);
                    answer++;
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;
            bool oneLeft = false;
            bool twoLeft = false;
            bool threeLeft = false;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();
            int k1 = 0, k2 = 0, k3 = 0, k4 = 0;

            //////////////////////////////////////////////////////
            if (groupsList.Contains(4))
            {
                k4 = groupsList.Count - groupsList.IndexOf(4);
                answer += k4;
            }
            /////////////////////////////////////////////////////

            if (groupsList.Contains(2))
            {
                int startIndex = 0, endIndex = 0;
                startIndex = groupsList.IndexOf(2);

                if (groupsList.Contains(3))
                {
                    endIndex = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    endIndex = groupsList.IndexOf(4);
                }
                else
                {
                    endIndex = groupsList.Count;
                }

                if ((endIndex - startIndex) % 2 == 0)
                {
                    answer += (endIndex - startIndex) / 2;
                }
                else
                {
                    answer += (endIndex - startIndex) / 2;
                    twoLeft = true;
                }
            }

            ///////////////////////////////////////////////////////////////////
            if (groupsList.Contains(1) && groupsList.Contains(3))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else
                {
                    k1 = groupsList.IndexOf(3);
                }

                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                if (k1 == k3)
                {
                    answer += k1;
                }
                else
                {
                    if (k1 > k3)
                    {
                        answer += k3;
                        k1 -= k3;
                        oneLeft = true;
                    }
                    else
                    {
                        answer += k1;
                        k3 -= k1;
                        threeLeft = true;
                    }
                }
            }
            else if (groupsList.Contains(3))
            {
                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                answer += k3;
            }
            else if (groupsList.Contains(1))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else if (groupsList.Contains(3))
                {
                    k1 = groupsList.IndexOf(3);
                }
                else
                    k1 = groupsList.Count;

                answer += k1 / 4;
                if (k1 % 4 > 0)
                    answer++;
            }

            ///////////////////////////////////////////////////////////////

            if (threeLeft)
            {
                answer += k3;
            }

            if (oneLeft || twoLeft)
            {
                if (k1 > 2)
                {
                    answer++;
                    twoLeft = false;
                    k1 -= 2;

                    answer += k1 / 4;
                    if (k1 % 4 > 0)
                        answer++;
                }
                else
                {
                    twoLeft = false;
                    answer++;
                }
            }

            Console.WriteLine(answer);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "3 2 3 2 2 4 3 3 3 3 3 3 3 3 3 2 4 3 3 3 2 2 3 2 3 2 3 3 3 2 3 2 3 3 3 1 1 1 1 1 1 1 2 2 2 2 2 2 3 3 3 3 3 3 4 4 4 4 4 2 1 2 3 1 2 3 1 2 3 4 4 2 1 2 2 1 2 2 3 2 1 2 3 2 1 2 2 2 2 2 2 3 3 2 1 2 3 2 3 2 1 2 2 3 3 3 3 2 2 1 2 2 1 4 4";
            string[] groups = groupsData.Split(' ');
            int answer = 0;
            bool oneLeft = false;
            bool twoLeft = false;
            bool threeLeft = false;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();
            int k1 = 0, k2 = 0, k3 = 0, k4 = 0;

            //////////////////////////////////////////////////////
            if (groupsList.Contains(4))
            {
                k4 = groupsList.Count - groupsList.IndexOf(4);
                answer += k4;
            }
            /////////////////////////////////////////////////////

            if (groupsList.Contains(2))
            {
                int startIndex = 0, endIndex = 0;
                startIndex = groupsList.IndexOf(2);

                if (groupsList.Contains(3))
                {
                    endIndex = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    endIndex = groupsList.IndexOf(4);
                }
                else
                {
                    endIndex = groupsList.Count;
                }

                if ((endIndex - startIndex) % 2 == 0)
                {
                    answer += (endIndex - startIndex) / 2;
                }
                else
                {
                    answer += (endIndex - startIndex) / 2;
                    twoLeft = true;
                }
            }

            ///////////////////////////////////////////////////////////////////
            if (groupsList.Contains(1) && groupsList.Contains(3))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else
                {
                    k1 = groupsList.IndexOf(3);
                }

                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                if (k1 == k3)
                {
                    answer += k1;
                }
                else
                {
                    if (k1 > k3)
                    {
                        answer += k3;
                        k1 -= k3;
                        oneLeft = true;
                    }
                    else
                    {
                        answer += k1;
                        k3 -= k1;
                        threeLeft = true;
                    }
                }
            }
            else if (groupsList.Contains(3))
            {
                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                answer += k3;
            }
            else if (groupsList.Contains(1))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else if (groupsList.Contains(3))
                {
                    k1 = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    k1 = groupsList.IndexOf(4);
                }
                else
                    k1 = groupsList.Count;

                answer += k1 / 4;
                if (k1 % 4 > 0)
                {
                    oneLeft = true;
                    k1 = k1 % 4;
                }
            }

            ///////////////////////////////////////////////////////////////

            if (threeLeft)
            {
                answer += k3;
            }

            if (oneLeft || twoLeft)
            {
                if (k1 > 2)
                {
                    if (twoLeft)
                    {
                        answer++;
                        twoLeft = false;
                        k1 -= 2;
                    }

                    answer += k1 / 4;
                    if (k1 % 4 > 0)
                        answer++;
                }
                else
                {
                    twoLeft = false;
                    answer++;
                }
            }

            Console.WriteLine(answer);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
           // string groupsData = "1 1 1 1 1 1 1 1 1 1 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            if (groupsList.Contains(4))
                answer += RemoveSingle(groupsList, 4); // all 4s

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2))
            {
                groupsList.Sort();
                int onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's
            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            if (groupsList.Contains(4))
                answer += RemoveSingle(groupsList, 4); // all 4s

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                groupsList.Sort();
                double onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount && groupsList.Count % 2 == 0)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }
            else
            {
                groupsList.Sort();
                while (groupsList.Contains(1) && groupsList.Contains(3))
                {
                    groupsList.RemoveAt(0);
                    groupsList.RemoveAt(groupsList.Count - 1);
                    answer++;
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();

            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer += RemoveSingle(groupsList, 4); // all 4s
            answer += RemoveCouple(groupsList, 2, 2); // all double 2s
            answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            answer += RemoveCouple(groupsList, 1, 3);
            answer += RemoveSingle(groupsList, 3); // all 3's
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            for (int i = 0; i < groupsList.Count; i++)
            {
                if (groupsList[i] == 1)
                {
                    pos.Add(i);
                    counter++;
                }

            }

            while (counter >= 4)
            {
                for (int i = 0; i < 4; i++)
                {
                    groupsList.RemoveAt(pos[pos.Count-1]);
                    pos.RemoveAt(pos.Count-1);
                }
                counter -= 4;
                answ++;
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > 0; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            //string groupsData = Console.ReadLine();

            string groupsData = "2 4 3 3 2 2 4 1 1 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer = RemoveSingle(answer, groupsList, 4); // all 4s
            answer = RemoveCouple(answer, groupsList, 2, 2); // all double 2s
            answer = RemoveCouple(answer, groupsList, 3, 1); // all 3+1 couples
            answer = RemoveCouple(answer, groupsList, 1, 3);
            answer = RemoveSingle(answer, groupsList, 3); // all 3's

            for (int i = 0; i < groupsList.Count; i++)
            {
                if (groupsList[i] == 2)
                {
                    if (groupsList.Count == 3 || groupsList.Count == 4)
                    {
                        answer++;
                        break;
                    }
                }
            }

            Console.WriteLine(answer);

        }

        private static int RemoveSingle(int answer, List<int> groupsList, int a)
        {
            for (int i = groupsList.Count - 1; i > 0; i--)
            {
                if (groupsList[i] == a)
                {
                    answer++;
                    groupsList.RemoveAt(i);
                }
            }
            return answer;
        }

        private static int RemoveCouple(int answer, List<int> groupsList, int a, int b)
        {
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                answer++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return answer;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
           // string groupsData = "1 1 1 1 1 1 1 1 1 1 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            if (groupsList.Contains(4))
                answer += RemoveSingle(groupsList, 4); // all 4s

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            groupsList.Sort();
            while (groupsList.Contains(1) && groupsList.Contains(3))
            {
                groupsList.RemoveAt(0);
                groupsList.RemoveAt(groupsList.Count);
                answer++;
            }

            //if (groupsList.Contains(3) && groupsList.Contains(1))
            //    answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            //if (groupsList.Contains(3) && groupsList.Contains(1))
            // answer += RemoveCouple(groupsList, 1, 3);

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's
            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
           // string groupsData = "1 1 1 1 1 1 1 1 1 1 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            if (groupsList.Contains(4))
                answer += RemoveSingle(groupsList, 4); // all 4s

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                groupsList.Sort();
                int onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2  2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();

            if (groupsList.Contains(4))
            {
                int startInxed = groupsList.IndexOf(4);
                answer += groupsList.Count - startInxed;
                groupsList.RemoveRange(startInxed, groupsList.Count - startInxed);
            }

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    int startIndex = groupsList.IndexOf(2);
                    int endIndex = groupsList.IndexOf(3);

                    if (endIndex < startIndex)
                    {
                        answer += RemoveCouple(groupsList, 2, 2);
                    }
                    else
                    {
                        answer += (endIndex - startIndex) / 2;
                        if ((endIndex - startIndex) % 2 > 0)
                            answer++;

                        groupsList.RemoveRange(startIndex, endIndex - startIndex);
                    }
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                double onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount && groupsList.Count % 2 == 0)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }
            else
            {
                while (groupsList.Contains(1) && groupsList.Contains(3))
                {
                    groupsList.RemoveAt(0);
                    groupsList.RemoveAt(groupsList.Count - 1);
                    answer++;
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 1 2 2 3 2 2 2 2 2 2 2 1 1 2 2 2 2 2 2 2 1 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;
            bool oneLeft = false;
            bool twoLeft = false;
            bool threeLeft = false;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();
            int k1 = 0, k2 = 0, k3 = 0, k4 = 0;

            //////////////////////////////////////////////////////
            if (groupsList.Contains(4))
            {
                k4 = groupsList.Count - groupsList.IndexOf(4);
                answer += k4;
            }
            /////////////////////////////////////////////////////

            if (groupsList.Contains(2))
            {
                int startIndex = 0, endIndex = 0;
                startIndex = groupsList.IndexOf(2);

                if (groupsList.Contains(3))
                {
                    endIndex = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    endIndex = groupsList.IndexOf(4);
                }
                else
                {
                    endIndex = groupsList.Count;
                }

                if ((endIndex - startIndex) % 2 == 0)
                {
                    answer += (endIndex - startIndex) / 2;
                }
                else
                {
                    answer += (endIndex - startIndex) / 2;
                    twoLeft = true;
                }
            }

            ///////////////////////////////////////////////////////////////////
            if (groupsList.Contains(1) && groupsList.Contains(3))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else
                {
                    k1 = groupsList.IndexOf(3);
                }

                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                if (k1 == k3)
                {
                    answer += k1;
                }
                else
                {
                    if (k1 > k3)
                    {
                        answer += k3;
                        k1 -= k3;
                        oneLeft = true;
                    }
                    else
                    {
                        answer += k1;
                        k3 -= k1;
                        threeLeft = true;
                    }
                }
            }
            else if (groupsList.Contains(3))
            {
                if (groupsList.Contains(4))
                {
                    k3 = groupsList.IndexOf(4) - groupsList.IndexOf(3);
                }
                else
                {
                    k3 = groupsList.Count - groupsList.IndexOf(3);
                }

                answer += k3;
            }
            else if (groupsList.Contains(1))
            {
                if (groupsList.Contains(2))
                {
                    k1 = groupsList.IndexOf(2);
                }
                else if (groupsList.Contains(3))
                {
                    k1 = groupsList.IndexOf(3);
                }
                else if (groupsList.Contains(4))
                {
                    k1 = groupsList.IndexOf(4);
                }
                else
                    k1 = groupsList.Count;

                answer += k1 / 4;
                if (k1 % 4 > 0)
                {
                    oneLeft = true;
                    k1 = k1 % 4;
                }
            }

            ///////////////////////////////////////////////////////////////

            if (threeLeft)
            {
                answer += k3;
            }

            if (oneLeft || twoLeft)
            {
                if (k1 > 2)
                {
                    answer++;
                    twoLeft = false;
                    k1 -= 2;

                    answer += k1 / 4;
                    if (k1 % 4 > 0)
                        answer++;
                }
                else
                {
                    twoLeft = false;
                    answer++;
                }
            }

            Console.WriteLine(answer);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            //string groupsData = Console.ReadLine();
            string groupsData = "2 3 4 4 2 1 3 1";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer += RemoveSingle(groupsList, 4); // all 4s
            answer += RemoveCouple(groupsList, 2, 2); // all double 2s
            answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            answer += RemoveCouple(groupsList, 1, 3);
            answer += RemoveSingle(groupsList, 3); // all 3's
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            for (int i = 0; i < groupsList.Count; i++)
            {
                if (groupsList[i] == 1)
                {
                    pos.Add(i);
                    counter++;
                }

            }

            while (counter >= 4)
            {
                for (int i = 0; i < 4; i++)
                {
                    groupsList.RemoveAt(pos[pos.Count-1]);
                    pos.RemoveAt(pos.Count-1);
                }
                counter -= 4;
                answ++;
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > 0; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
           // string groupsData = "1 1 1 1 1 1 1 1 1 1 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer += RemoveSingle(groupsList, 4); // all 4s
            answer += RemoveCouple(groupsList, 2, 2); // all double 2s
            answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            answer += RemoveCouple(groupsList, 1, 3);
            answer += RemoveSingle(groupsList, 3); // all 3's
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();

            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer += RemoveSingle(groupsList, 4); // all 4s
            answer += RemoveCouple(groupsList, 2, 2); // all double 2s
            answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            answer += RemoveCouple(groupsList, 1, 3);
            answer += RemoveSingle(groupsList, 3); // all 3's
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }
            else

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            for (int i = 0; i < groupsList.Count; i++)
            {
                if (groupsList[i] == 1)
                {
                    pos.Add(i);
                    counter++;
                }

            }

            while (counter >= 4)
            {
                for (int i = 0; i < 4; i++)
                {
                    groupsList.RemoveAt(pos[pos.Count-1]);
                    pos.RemoveAt(pos.Count-1);
                }
                counter -= 4;
                answ++;
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > 0; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();

//string groupsData = "1 2 4 3 3";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            answer += RemoveSingle(groupsList, 4); // all 4s
            answer += RemoveCouple(groupsList, 2, 2); // all double 2s
            answer += RemoveCouple(groupsList, 3, 1); // all 3+1 couples
            answer += RemoveCouple(groupsList, 1, 3);
            answer += RemoveSingle(groupsList, 3); // all 3's

            for (int i = 0; i < groupsList.Count; i++)
            {
                if (groupsList[i] == 2)
                {
                    if (groupsList.Count == 3 || groupsList.Count == 4)
                    {
                        answer++;
                        break;
                    }
                }
            }

            answer += groupsList.Count();

            Console.WriteLine(answer);

        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > 0; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;
            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2  2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();

            if (groupsList.Contains(4))
            {
                int startInxed = groupsList.IndexOf(4);
                answer += groupsList.Count - startInxed;
                groupsList.RemoveRange(startInxed, groupsList.Count - startInxed);
            }

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                double onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount && groupsList.Count % 2 == 0)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }
            else
            {
                while (groupsList.Contains(1) && groupsList.Contains(3))
                {
                    groupsList.RemoveAt(0);
                    groupsList.RemoveAt(groupsList.Count - 1);
                    answer++;
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace ProblemsFun
{
    class Program
    {
        static void Main(string[] args)
        {
            int n = Convert.ToInt32(Console.ReadLine());
            string groupsData = Console.ReadLine();
            //string groupsData = "2 2 2 2 3 3 2 2 2  2 2 2 2 2 2 2";
            string[] groups = groupsData.Split(' ');
            int answer = 0;

            List<int> groupsList = new List<int>();
            for (int i = 0; i < n; i++)
            {
                groupsList.Add(Convert.ToInt32(groups[i]));
            }

            groupsList.Sort();

            if (groupsList.Contains(4))
            {
                int startInxed = groupsList.IndexOf(4);
                groupsList.RemoveRange(startInxed, groupsList.Count - startInxed);
            }

            if (groupsList.Contains(2))
            {
                if (groupsList.Contains(1) || groupsList.Contains(3))
                {
                    answer += RemoveCouple(groupsList, 2, 2);
                }
                else
                {
                    answer += RemoveFast2(groupsList);
                }
            }

            if (!groupsList.Contains(2) && groupsList.Contains(1) && groupsList.Contains(3))
            {
                double onesCount = groupsList.IndexOf(3);

                if (groupsList.Count / 2 == onesCount && groupsList.Count % 2 == 0)
                {
                    answer += groupsList.Count / 2;
                    groupsList.Clear();
                }
                else
                {
                    while (groupsList.Contains(1) && groupsList.Contains(3))
                    {
                        groupsList.RemoveAt(0);
                        groupsList.RemoveAt(groupsList.Count - 1);
                        answer++;
                    }
                }
            }
            else
            {
                while (groupsList.Contains(1) && groupsList.Contains(3))
                {
                    groupsList.RemoveAt(0);
                    groupsList.RemoveAt(groupsList.Count - 1);
                    answer++;
                }
            }

            if (groupsList.Contains(3))
                answer += RemoveSingle(groupsList, 3); // all 3's

            if (groupsList.Contains(1))
            answer += RemoveAll4Ones(groupsList);

            if (groupsList.Count <= 3 && groupsList.Count > 0)
            {
                answer++;
            }
            else if (groupsList.Count == 4)
            {
                answer += 2;
            }

            Console.WriteLine(answer);
        }

        private static int RemoveAll4Ones(List<int> groupsList)
        {
            int answ = 0;
            int counter = 0;
            List<int> pos = new List<int>();

            if (groupsList.Contains(2))
            {
                for (int i = 0; i < groupsList.Count; i++)
                {
                    if (groupsList[i] == 1)
                    {
                        pos.Add(i);
                        counter++;
                    }
                }

                while (counter >= 4)
                {
                    for (int i = 0; i < 4; i++)
                    {
                        groupsList.RemoveAt(pos[pos.Count - 1]);
                        pos.RemoveAt(pos.Count - 1);
                    }
                    counter -= 4;
                    answ++;
                }
            }
            else
            {
                answ = groupsList.Count / 4;
                if (groupsList.Count % 4 > 0)
                    answ++;

                groupsList.Clear();
            }

            return answ;
        }

        private static int RemoveSingle(List<int> groupsList, int a)
        {
            int ans = 0;
            for (int i = groupsList.Count - 1; i > -1; i--)
            {
                if (groupsList[i] == a)
                {
                    ans++;
                    groupsList.RemoveAt(i);
                }
            }
            return ans;
        }

        private static int RemoveCouple(List<int> groupsList, int a, int b)
        {
            int ans = 0;

            for (int i = 0; i < groupsList.Count - 1; i++)
            {
                if (groupsList[i] == a)
                {
                    if (i + 1 < groupsList.Count)
                    {
                        for (int k = i + 1; k < groupsList.Count; k++)
                        {
                            if (groupsList[k] == b)
                            {
                                ans++;
                                groupsList.RemoveAt(k);
                                groupsList.RemoveAt(i);
                                i--;
                                break;
                            }
                        }
                    }
                }
            }
            return ans;
        }

        private static int RemoveFast2(List<int> groupsList)
        {
            int ans = 0;
            ans = groupsList.Count / 2;
            if (groupsList.Count % 2 > 0)
                ans++;

            groupsList.Clear();
            return ans;
        }
    }
}