Vasya has n days of vacations! So he decided to improve his IT skills and do sport. Vasya knows the following information about each of this n days: whether that gym opened and whether a contest was carried out in the Internet on that day. For the i-th day there are four options:

  1. on this day the gym is closed and the contest is not carried out; 
  2. on this day the gym is closed and the contest is carried out; 
  3. on this day the gym is open and the contest is not carried out; 
  4. on this day the gym is open and the contest is carried out. 



On each of days Vasya can either have a rest or write the contest (if it is carried out on this day), or do sport (if the gym is open on this day).

Find the minimum number of days on which Vasya will have a rest (it means, he will not do sport and write the contest at the same time). The only limitation that Vasya has — he does not want to do the same activity on two consecutive days: it means, he will not do sport on two consecutive days, and write the contest on two consecutive days.

Input

The first line contains a positive integer n (1 ≤ n ≤ 100) — the number of days of Vasya's vacations.

The second line contains the sequence of integers a1, a2, ..., an (0 ≤ ai ≤ 3) separated by space, where: 

  * ai equals 0, if on the i-th day of vacations the gym is closed and the contest is not carried out; 
  * ai equals 1, if on the i-th day of vacations the gym is closed, but the contest is carried out; 
  * ai equals 2, if on the i-th day of vacations the gym is open and the contest is not carried out; 
  * ai equals 3, if on the i-th day of vacations the gym is open and the contest is carried out.

Output

Print the minimum possible number of days on which Vasya will have a rest. Remember that Vasya refuses:

  * to do sport on any two consecutive days, 
  * to write the contest on any two consecutive days. 

Examples

Input

4
1 3 2 0


Output

2


Input

7
1 3 3 2 1 2 3


Output

0


Input

2
2 2


Output

1

Note

In the first test Vasya can write the contest on the day number 1 and do sport on the day number 3. Thus, he will have a rest for only 2 days.

In the second test Vasya should write contests on days number 1, 3, 5 and 7, in other days do sport. Thus, he will not have a rest for a single day.

In the third test Vasya can do sport either on a day number 1 or number 2. He can not do sport in two days, because it will be contrary to the his limitation. Thus, he will have a rest for only one day.
import java.util.*;
import java.io.*;
import java.math.*;
import java.math.BigInteger;
import java.text.DecimalFormat;

public class Lib {
	public static long maxLong = Long.MAX_VALUE;
	public static int maxInt = Integer.MAX_VALUE;
	public static long minLong = Long.MIN_VALUE;
	public static int minInt = Integer.MIN_VALUE;
	public static final long MOD = (long) (1e9 + 7);
	
	
	
	public static void main(String args[])
	{
		InputReader in = new InputReader(System.in);
		OutputStream outputStream = System.out;
		PrintWriter out = new PrintWriter(outputStream);
		int n=in.nextInt();
		
		int [] arr = in.nextIntArray(n);
		
		
		int [][] dp = new int[n+1][3];
		
		for (int i=1;i<n+1;i++)
		{
			if(arr[i-1] == 0)
			{
				dp[i][1] = dp[i-1][1];
				dp[i][2] = dp[i-1][2];
			}
			else if(arr[i-1] == 1)
			{
				dp[i][1] = Math.max(dp[i-1][0],dp[i-1][2])+1;
				dp[i][2] = dp[i-1][2];
			}
			else if(arr[i-1] == 2)
			{
				dp[i][1] = dp[i-1][1];
				dp[i][2] = Math.max(dp[i-1][0],dp[i-1][1])+1;
			}
			else if(arr[i-1] == 3)
			{
				dp[i][1] = Math.max(dp[i-1][0],dp[i-1][2])+1;
				dp[i][2] = Math.max(dp[i-1][0],dp[i-1][1])+1;
			}
			
			dp[i][0]=Math.max(dp[i-1][0],Math.max(dp[i-1][1],dp[i-1][2]));
		}
		
		
		out.println(n- Math.max(dp[n][0],Math.max(dp[n][1],dp[n][2])));
				
		out.close();
	}

	
	static int binarySearch(int arr[], int x, int l, int r)
    {
        while (l <= r)
        {
            int m = l + (r-l)/2;
 
            if (arr[m] == x)
                return m;
 
            if (arr[m] < x)
			{
				l = m + 1; 
			} 
            else
			{
				r = m - 1;
			}
        }
        return -1;
    }
	
	static int floorSearch(int arr[], int low, int high, int x)
	{
		int ans=-1;
		while(low<=high)
		{
			int mid=(low)+(high-low)/2;
			
			if (arr[mid] == x)
				return mid;
			else if(arr[mid]>x)
			{
				high=mid-1;
			}
			else
			{
				ans=mid;
				low=mid+1;				
			}
		}
		return ans;
	}


	static int ceilSearch(int arr[], int low, int high, int x)
    {
    	int ans=-1;
		while(low<=high)
		{
			int mid=(low)+(high-low)/2;
			
			if(arr[mid] == x)
				return mid;
			else if(arr[mid]>x)
			{
				ans=mid;
				high=mid-1;
			}
			else
			{
				low=mid+1;
			}
		}
		return ans;
    }
	
	static int gcd(int a, int b)
    {
        if (a == 0)
            return b;
        return gcd(b % a, a);
    }
	
    static int gcdArray(int arr[], int n)
    {
        int result = arr[0];
        for (int i = 1; i < n; i++)
            result = gcd(arr[i], result);
 
        return result;
    }
	
	static int lcm(int a, int b)
    {
        return (a*b)/gcd(a, b);
    }
	
	public static long ncr(long n, long r) 
	{
		long result=1;
		result = factorial(n)/(factorial(r)*factorial(n-r));
		return result;
	}
	
	public static long factorial(long n) 
	{
	   long c;
	   long result = 1;
	 
	   for (c = 1; c <= n; c++)
		  result = result*c;
	 
	   return result;
	}
	 static long modFactorial(long x)
	 {
		long i=x,mul=1;
		while(i>0)
		{
			mul=(mul%MOD)*(i%MOD)%MOD;
			i--;
		}
		return mul;
	 }
	
	public static long modPower(long base, long exp) 
	{
		long res=1;
		while(exp>0) {
		   if(exp%2==1) 
			   res=(res*base)%MOD;
		   base=(base*base)%MOD;
		   exp/=2;
		}
		return res%MOD;
	}
	
	
	static void printArray(int [] arr)
	{
		System.out.println(Arrays.toString(arr));
	}
	static void printArray(float [] arr)
	{
		System.out.println(Arrays.toString(arr));
	}
	static void printArray(double [] arr)
	{
		System.out.println(Arrays.toString(arr));
	}
	static void printArray(long [] arr)
	{
		System.out.println(Arrays.toString(arr));
	}
	static void printArray(char [] arr)
	{
		System.out.println(Arrays.toString(arr));
	}
	
	
	static void print2DArray(int [][] arr)
	{
		for(int [] a : arr)
		{
			System.out.println(Arrays.toString(a));
		}
	}
	static void print2DArray(float [][] arr)
	{
		for(float [] a : arr)
		{
			System.out.println(Arrays.toString(a));
		}
	}
	static void print2DArray(double [][] arr)
	{
		for(double [] a : arr)
		{
			System.out.println(Arrays.toString(a));
		}
	}
	static void print2DArray(long [][] arr)
	{
		for(long [] a : arr)
		{
			System.out.println(Arrays.toString(a));
		}
	}
	static void print2DArray(char [][] arr)
	{
		for(char [] a : arr)
		{
			System.out.println(Arrays.toString(a));
		}
	}
	
	static void printArrayObject(Object [] arr)
	{
		System.out.println(Arrays.toString(arr));
	}
	
	static void print2DArrayObject(Object [][] arr)
	{
		for(Object [] a : arr)
		{
			System.out.println(Arrays.toString(a));
		}
	}
	
	
	static class InputReader {
		public BufferedReader reader;
		public StringTokenizer tokenizer;

		public InputReader(InputStream inputstream) {
			reader = new BufferedReader(new InputStreamReader(inputstream));
			tokenizer = null;
		}

		public String nextLine(){
			String fullLine=null;
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					fullLine=reader.readLine();
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
				return fullLine;
			}
			return fullLine;
		}
		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}
		public long nextLong() {
			return Long.parseLong(next());
		}
		public int nextInt() {
			return Integer.parseInt(next());
		}
		public double nextDouble() {
			return Double.parseDouble(next());
		}
		
		public int[] nextIntArray(int n)	
		{
			int[] a=new int[n];
			for(int i=0;i<n;i++)
				a[i]=nextInt();
			return a;
		}
		public long[] nextLongArray(int n)	
		{
			long[] a=new long[n];
			for(int i=0;i<n;i++)
				a[i]=nextLong();
			return a;
		}
		public double[] nextDoubleArray(int n)	
		{
			double[] a=new double[n];
			for(int i=0;i<n;i++)
				a[i]=nextDouble();
			return a;
		}
		public String[] nextStringArray(int n)	
		{
			String[] a=new String[n];
			for(int i=0;i<n;i++)
				a[i]=next();
			return a;
		}
		
	}
	
	static class Pair implements Comparable<Pair>
	{
		private long first;
		private long second;
		//private long second;;

		public Pair(long i, long j) 
		{ 
			this.first = i;
			this.second = j;
		}
		public Pair() {
			// TODO Auto-generated constructor stub
		}
		public long getFirst() { return first; }
		//public long getSecond() { return second; }
		public long getSecond() { return second ;}
		public void setFirst(long k) { this.first=k ; }
		public void setSecond(long k) { this.second=k ;}
		//public void setSecond(long k) { this.second=k ;}
		@Override
		public int compareTo(Pair o) 
		{
			return Long.compare(this.first, o.first);
		}
	}
	
	
	static class LengthComparator implements Comparator<String> {
	    public int compare(String arg0, String arg1) {
			return (arg0+arg1).compareTo(arg1+arg0);
	    }
	}
}





class Graph
{
    private int V;   
    private LinkedList<Integer> adj[];
 
    Graph(int v)
    {
        V = v;
        adj = new LinkedList[v];
        for (int i=0; i<v; ++i)
            adj[i] = new LinkedList();
    }
 
    void addEdge(int v,int w)
    {
        adj[v].add(w);
    }
	
	void addEdgeUndirected(int v, int w)
    {
        adj[v].add(w);  // Add w to v's list.
        adj[w].add(v);    //Add v to w's list
    }
 
 
    void BFS(int s)
    {
        boolean visited[] = new boolean[V];
 
        LinkedList<Integer> queue = new LinkedList<Integer>();
 
        visited[s]=true;
        queue.add(s);
 
        while (queue.size() != 0)
        {
            s = queue.poll();
            System.out.print(s+" ");

            Iterator<Integer> i = adj[s].listIterator();
            while (i.hasNext())
            {
                int n = i.next();
                if (!visited[n])
                {
                    visited[n] = true;
                    queue.add(n);
                }
            }
        }
    }
	
	
	void DFS(int s)
    {
        boolean visited[] = new boolean[V];
 
        Stack<Integer> stack = new Stack<Integer>();
 
        visited[s]=true;
        stack.push(s);
 
        while (stack.size() != 0)
        {
            s = stack.pop();
            System.out.print(s+" ");

            Iterator<Integer> i = adj[s].listIterator();
            while (i.hasNext())
            {
                int n = i.next();
                if (!visited[n])
                {
                    visited[n] = true;
                    stack.push(n);
                }
            }
        }
    }
	
	void topologicalSortUtil(int v, boolean visited[], Stack stack)
    {
        visited[v] = true;
        Integer i;
 
        Iterator<Integer> it = adj[v].iterator();
        while (it.hasNext())
        {
            i = it.next();
            if (!visited[i])
                topologicalSortUtil(i, visited, stack);
        }
        stack.push(new Integer(v));
    }
 
    void topologicalSort()
    {
        Stack stack = new Stack();
 
        boolean visited[] = new boolean[V];
        for (int i = 0; i < V; i++)
            visited[i] = false;
 
        for (int i = 0; i < V; i++)
            if (visited[i] == false)
                topologicalSortUtil(i, visited, stack);
 
        while (stack.empty()==false)
            System.out.print(stack.pop() + " ");
    }
	
	
	int time =0;
	
	void bridgeUtil(int u, boolean visited[], int disc[], int low[], int parent[])
    {
 
        int children = 0;
 
        visited[u] = true;
 
        disc[u] = low[u] = ++time;
 
        Iterator<Integer> i = adj[u].iterator();
        while (i.hasNext())
        {
            int v = i.next(); 
 
            if (!visited[v])
            {
                parent[v] = u;
                bridgeUtil(v, visited, disc, low, parent);
 
                low[u]  = Math.min(low[u], low[v]);
 
                if (low[v] > disc[u])
                    System.out.println(u+" "+v);
            }
            else if (v != parent[u])
                low[u]  = Math.min(low[u], disc[v]);
        }
    }
 
    void bridge()
    {
        boolean visited[] = new boolean[V];
        int disc[] = new int[V];
        int low[] = new int[V];
        int parent[] = new int[V];
 
 
        for (int i = 0; i < V; i++)
        {
            parent[i] = -1;
            visited[i] = false;
        }
 
        for (int i = 0; i < V; i++)
            if (visited[i] == false)
                bridgeUtil(i, visited, disc, low, parent);
    }
	
	
	void DFSUtil(int v,boolean visited[])
    {
        visited[v] = true;

        Iterator<Integer> i = adj[v].listIterator();
        while (i.hasNext())
        {
            int n = i.next();
            if (!visited[n])
                DFSUtil(n, visited);
        }
    }

    void motherVertex()
    {
        boolean visited[] = new boolean[V];
        for (int i = 0; i < V; i++)
        {
            visited[i] = false;
        }    
        
        // The vertex that finishes last should be the mother node
        int v = -1;
        for (int i = 0; i < V; i++)
        {
            if (visited[i] == false)
            {
                DFSUtil(i, visited);
                v = i;
            }
        }
        
        for (int i = 0; i < V; i++)
        {
            visited[i] = false;
        }
        
        System.out.println(" Mother Vertex Detected At:"  + v);
        
        DFSUtil(v, visited);
        for(int i = 0; i < V; i++)
        {
            if(visited[i] == false)
            {
                System.out.println("Not a mother vertex.Node that wasn't connected :" + i);        
                return;
            }
        }
        System.out.println(" Mother Vertex: "  + v);
    }
	
}