import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=0;
            if(i!=0)
            lo=i+1;
            else
            lo=0;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      int[] ans_arr=new int[n+1];
	      if(one_count[n-1]!=two_count[n-1])
	      {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;};
	      for(int i=2;i<=n;i++)
	      {
	            ones=0;twos=0;
	            int c=0,in=0;
	            while(in>-1 && in<n-1)
	            {
	                  //System.out.println(in+" "+"in");
	                  k1=my_search(one_count,in,i,ones);
	                  k2=my_search(two_count,in,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>-1)
	                  {in=Math.min(k1,k2);c++;ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                 {in=-1;break;}
	                  else
	                  {in=Math.max(k1,k2);c++;ones=one_count[in];twos=two_count[in];}

	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {ans_arr[i-1]=c;ans++;//System.out.println(i+" "+"i");
	            }
	            else
	            ans_arr[i]=-1;
	      }
	    p.printLine(Integer.toString(ans));
	      for(int i=n-1;i>-1;i--)
	      {
	            if(ans_arr[i]>0)
	            {
	           p.print(Integer.toString(ans_arr[i])+" ");
	           p.print(Integer.toString(i+1));
	           p.printLine(" ");

	            }
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=0;
            if(i!=0)
            lo=i+1;
            else
            lo=0;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      int[] ans_arr=new int[n+1];
	      if(one_count[n-1]!=two_count[n-1])
	      {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;};int two_wins=0;int one_wins=0;
	      for(int i=2;i<=n;i++)
	      {
	            one_wins=0;two_wins=0;
	            ones=0;twos=0;
	            int c=0,in=0;
	            while(in>-1 && in<n-1)
	            {
	                  //System.out.println(in+" "+"in");
	                  k1=my_search(one_count,in,i,ones);
	                  k2=my_search(two_count,in,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>-1)
	                  {in=Math.min(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                 {in=-1;break;}
	                  else
	                  {in=Math.max(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}

	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {ans_arr[i-1]=Math.max(one_wins,two_wins);ans++;//System.out.println(i+" "+"i");
	            }
	            else
	            ans_arr[i]=-1;
	      }
	    p.printLine(Integer.toString(ans));
	      for(int i=n-1;i>-1;i--)
	      {
	            if(ans_arr[i]>0)
	            {
	           p.print(Integer.toString(ans_arr[i])+" ");
	           p.print(Integer.toString(i+1));
	           p.printLine(" ");

	            }
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=0;
            if(i!=0)
            lo=i+1;
            else
            lo=0;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      int[] ans_arr=new int[n+1];
	      //if(one_count[n-1]!=two_count[n-1])
	     // {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;}
	      int two_wins=0;int one_wins=0;
	      for(int i=1;i<=n;i++)
	      {
	            one_wins=0;two_wins=0;
	            ones=0;twos=0;
	            int c=0,in=0;
	            while(in>-1 && in<n-1)
	            {
	                  //System.out.println(in+" "+"in");
	                  k1=my_search(one_count,in,i,ones);
	                  k2=my_search(two_count,in,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>-1)
	                  {in=Math.min(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                 {in=-1;break;}
	                  else
	                  {in=Math.max(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}

	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {
	                  if(in==k1)
	                  {
	                        if(one_wins>two_wins)
	                        {ans_arr[i]=one_wins;ans++;}
	                        else
	                        {
	                              ans_arr[i]=0;
	                        }//System.out.println(i+" "+"i");
	            }
	            else
	            {
	                  if(two_wins>one_wins)
	                  {ans_arr[i]=two_wins;ans++;}
	                  else
	                  ans_arr[i]=0;}
	      }}
	    p.printLine(Integer.toString(ans));
	      for(int i=n;i>-1;i--)
	      {
	            if(ans_arr[i]>0)
	            {
	           p.print(Integer.toString(ans_arr[i])+" ");
	           p.print(Integer.toString(i));
	           p.printLine(" ");

	            }
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=0;
            if(i!=0)
            lo=i+1;
            else
            lo=0;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      if(n==1)
	     {  p.printLine("1");
	           p.printLine("1"+" "+"1");}
	      else{
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      LinkedList[] ans_arr=new LinkedList[n+1];
	      for(int i=1;i<=n;i++)
	      ans_arr[i]=new LinkedList();
	      //if(one_count[n-1]!=two_count[n-1])
	     // {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;}
	      int two_wins=0;int one_wins=0;
	      for(int i=1;i<=n;i++)
	      {
	            one_wins=0;two_wins=0;
	            ones=0;twos=0;
	            int c=0,in=0;
	            while(in>-1 && in<n-1)
	            {
	                  //System.out.println(in+" "+"in");
	                  k1=my_search(one_count,in,i,ones);
	                  k2=my_search(two_count,in,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>-1)
	                  {in=Math.min(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                 {in=-1;break;}
	                  else
	                  {in=Math.max(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}

	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {
	                  if(in==k1)
	                  {
	                        if(one_wins>two_wins)
	                        {ans_arr[one_wins].add(i);ans++;}

	            }
	            else
	            {
	                  if(two_wins>one_wins)
	                  {ans_arr[two_wins].add(i);ans++;}
	                  }
	      }}
	    p.printLine(Integer.toString(ans));
	      for(int i=1;i<=n;i++)
	      {
	            while(ans_arr[i].isEmpty()!=true)
	            {
	           p.print(Integer.toString(i)+" ");
	           p.print(Integer.toString((Integer)(ans_arr[i].removeFirst())));
	           p.printLine(" ");

	            }
	      }}
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=0;
            if(i!=0)
            lo=i+1;
            else
            lo=0;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      int[] ans_arr=new int[n+1];
	      //if(one_count[n-1]!=two_count[n-1])
	     // {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;}
	      int two_wins=0;int one_wins=0;
	      for(int i=1;i<=n;i++)
	      {
	            one_wins=0;two_wins=0;
	            ones=0;twos=0;
	            int c=0,in=0;
	            while(in>-1 && in<n-1)
	            {
	                  //System.out.println(in+" "+"in");
	                  k1=my_search(one_count,in,i,ones);
	                  k2=my_search(two_count,in,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>-1)
	                  {in=Math.min(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                 {in=-1;break;}
	                  else
	                  {in=Math.max(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}

	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {
	                  if(in==k1)
	                  {
	                        if(one_wins>two_wins)
	                        {ans_arr[i-1]=one_wins;ans++;}
	                        else
	                        {
	                              ans_arr[i-1]=0;
	                        }//System.out.println(i+" "+"i");
	            }
	            else
	            {
	                  if(two_wins>one_wins)
	                  {ans_arr[i]=two_wins;ans++;}
	                  else
	                  ans_arr[i-1]=0;}
	      }}
	    p.printLine(Integer.toString(ans));
	      for(int i=n-1;i>-1;i--)
	      {
	            if(ans_arr[i]>0)
	            {
	           p.print(Integer.toString(ans_arr[i])+" ");
	           p.print(Integer.toString(i+1));
	           p.printLine(" ");

	            }
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=i+1;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      int[] ans_arr=new int[n+1];
	      if(one_count[n-1]!=two_count[n-1])
	      ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);
	      for(int i=2;i<=n;i++)
	      {
	            ones=0;twos=0;
	            int c=0,in=0;int j=i;
	            while(in>-1 && in<n-1)
	            {
	                  k1=my_search(one_count,k1,i,ones);
	                  k2=my_search(two_count,k2,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>0)
	                  {in=Math.min(k1,k2);c++;ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                  break;
	                  else
	                  {in=Math.max(k1,k2);c++;ones=one_count[in];twos=two_count[in];}
	                  j+=i;
	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {ans_arr[i-1]=c;ans++;//System.out.println(i+" "+"i");
	            }
	            else
	            ans_arr[i]=-1;
	      }
	      p.printLine(Integer.toString(ans));
	      for(int i=n-1;i>-1;i--)
	      {
	            if(ans_arr[i]>0)
	            {
	            p.print(Integer.toString(ans_arr[i])+" ");
	            p.print(Integer.toString(i+1));
	            p.printLine(" ");}
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=0;
            if(i!=0)
            lo=i+1;
            else
            lo=0;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      LinkedList[] ans_arr=new LinkedList[n+1];
	      for(int i=1;i<=n;i++)
	      ans_arr[i]=new LinkedList();
	      //if(one_count[n-1]!=two_count[n-1])
	     // {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;}
	      int two_wins=0;int one_wins=0;
	      for(int i=1;i<=n;i++)
	      {
	            one_wins=0;two_wins=0;
	            ones=0;twos=0;
	            int c=0,in=0;
	            while(in>-1 && in<n-1)
	            {
	                  //System.out.println(in+" "+"in");
	                  k1=my_search(one_count,in,i,ones);
	                  k2=my_search(two_count,in,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>-1)
	                  {in=Math.min(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                 {in=-1;break;}
	                  else
	                  {in=Math.max(k1,k2);
	                  if(in==k1)
	                  one_wins++;
	                  else
	                  two_wins++;
	                  ones=one_count[in];twos=two_count[in];}

	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {
	                  if(in==k1)
	                  {
	                        if(one_wins>two_wins)
	                        {ans_arr[one_wins].add(i);ans++;}

	            }
	            else
	            {
	                  if(two_wins>one_wins)
	                  {ans_arr[two_wins].add(i);ans++;}
	                  }
	      }}
	    p.printLine(Integer.toString(ans));
	      for(int i=1;i<=n;i++)
	      {
	            while(ans_arr[i].isEmpty()!=true)
	            {
	           p.print(Integer.toString(i)+" ");
	           p.print(Integer.toString((Integer)(ans_arr[i].removeFirst())));
	           p.printLine(" ");

	            }
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.*;
import java.math.*;
import java.util.*;
public class Solution
{
      public static int my_search(int[]arr,int i,int k,int j)
      {
            int lo=i+1;
            int hi=arr.length;
            while(lo<hi)
            {
                  int mid=lo+((hi-lo)/2);
                  if(arr[mid]-j==k)
                  hi=mid;
                  else if(arr[mid]-j>k)
                  hi=mid;
                  else
                  lo=mid+1;
            }
            if(lo>=arr.length)
            return -1;
            else
            return lo;
      }
	public static void main (String[] args) throws java.lang.Exception
	{
	      Scan sn=new Scan();
	      Print p=new Print();
	      int n=sn.scanInt();
	      int[]arr=new int[n];
	      for(int i=0;i<n;i++)
	      arr[i]=sn.scanInt();
	      int[] one_count=new int[n];
	      int[] two_count=new int[n];
	      if(arr[0]==1)
	      one_count[0]=1;
	      else
	      two_count[0]=1;
	      for(int i=1;i<n;i++)
	      {
	            if(arr[i]==1)
	            {
	                  one_count[i]=one_count[i-1]+1;
	                  two_count[i]=two_count[i-1];
	            }
	            else
	            {
	                  one_count[i]=one_count[i-1];
	                  two_count[i]=two_count[i-1]+1;
	            }
	      }
	      int ans=0;int ones;int twos;int k1=-1;int k2=-1;
	      int[] ans_arr=new int[n+1];
	      if(one_count[n-1]!=two_count[n-1])
	      {ans_arr[0]=Math.max(one_count[n-1],two_count[n-1]);ans++;};
	      for(int i=2;i<=n;i++)
	      {
	            ones=0;twos=0;
	            int c=0,in=0;int j=i;
	            while(in>-1 && in<n-1)
	            {
	                  k1=my_search(one_count,k1,i,ones);
	                  k2=my_search(two_count,k2,i,twos);
	                  //System.out.println(k1+" "+k2);
	                  if(k1>-1 && k2>0)
	                  {in=Math.min(k1,k2);c++;ones=one_count[in];twos=two_count[in];}
	                  else if(k1<0 && k2<0)
	                  break;
	                  else
	                  {in=Math.max(k1,k2);c++;ones=one_count[in];twos=two_count[in];}
	                  j+=i;
	            }
	            //System.out.println(in+" "+i);
	            if(in==(n-1))
	            {ans_arr[i-1]=c;ans++;//System.out.println(i+" "+"i");
	            }
	            else
	            ans_arr[i]=-1;
	      }
	      p.printLine(Integer.toString(ans));
	      for(int i=n-1;i>-1;i--)
	      {
	            if(ans_arr[i]>0)
	            {
	            p.print(Integer.toString(ans_arr[i])+" ");
	            p.print(Integer.toString(i+1));
	            p.printLine(" ");}
	      }
	      p.close();
	}
}
class Scan
{
	private byte[] buf=new byte[1024];
	private int index;
	private InputStream in;
	private int total;
	public Scan()
	{
		in=System.in;
	}
	public int scan()throws IOException
	{
		if(total<0)
		throw new InputMismatchException();
		if(index>=total)
		{
			index=0;
			total=in.read(buf);
			if(total<=0)
			return -1;
		}
		return buf[index++];
	}
	public int scanInt()throws IOException
	{
		int integer=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n))
		{
			if(n>='0'&&n<='9')
			{
				integer*=10;
				integer+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		return neg*integer;
	}
	public double scanDouble()throws IOException
	{
		double doub=0;
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		int neg=1;
		if(n=='-')
		{
			neg=-1;
			n=scan();
		}
		while(!isWhiteSpace(n)&&n!='.')
		{
			if(n>='0'&&n<='9')
			{
				doub*=10;
				doub+=n-'0';
				n=scan();
			}
			else throw new InputMismatchException();
		}
		if(n=='.')
		{
			n=scan();
			double temp=1;
			while(!isWhiteSpace(n))
			{
				if(n>='0'&&n<='9')
				{
					temp/=10;
					doub+=(n-'0')*temp;
					n=scan();
				}
				else throw new InputMismatchException();
			}
		}
		return doub*neg;
	}
	public String scanString()throws IOException
	{
		StringBuilder sb=new StringBuilder();
		int n=scan();
		while(isWhiteSpace(n))
		n=scan();
		while(!isWhiteSpace(n))
		{
			sb.append((char)n);
			n=scan();
		}
		return sb.toString();
	}
	private boolean isWhiteSpace(int n)
	{
		if(n==' '||n=='\n'||n=='\r'||n=='\t'||n==-1)
		return true;
		return false;
	}
}

class Print
{
	private final BufferedWriter bw;
	public Print()
	{
		bw=new BufferedWriter(new OutputStreamWriter(System.out));
	}
	public void print(String str)throws IOException
	{
		bw.append(str);
	}
	public void printLine(String str)throws IOException
	{
		print(str);
		bw.append("\n");
	}
	public void close()throws IOException
	{
		bw.close();
	}}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class A {

	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt();
		ArrayList<Integer> one = new ArrayList<>();
		ArrayList<Integer> two = new ArrayList<>();
		int[] nextA = new int[n], nextB = new int[n];
		ArrayList<Pair> ans = new ArrayList<>();
		for(int i = 0; i < n; ++i)
		{
			nextA[i] = one.size();
			nextB[i] = two.size();
			if(sc.nextInt() == 1)
				one.add(i);
			else
				two.add(i);
		}

		ll: for(int i = 1; i <= n; ++i)
		{
			int j1 = 0, j2 = 0, pos = 0, lst = -1;
			while(pos != n)
			{
				int ptr1 = nextA[pos] + i - 1;
				int ptr2 = nextB[pos] + i - 1;
				int pos1 = ptr1 < one.size() ? one.get(ptr1) : n;
				int pos2 = ptr2 < two.size() ? two.get(ptr2) : n;
				if(pos1 == n && pos2 == n)
					continue ll;
				if(pos1 < pos2)
				{
					++j1;
					pos = pos1 + 1;
					lst = 1;
				}
				else
				{
					++j2;
					pos = pos2 + 1;
					lst = 2;
				}
			}
			if(lst == 1 && j1 > j2)
				ans.add(new Pair(j1, i));
			if(lst == 2 && j2 > j1)
				ans.add(new Pair(j2, i));
		}
		out.println(ans.size());
		Collections.sort(ans);
		for(Pair p: ans)
			out.printf("%d %d\n", p.s, p.t);
		out.flush();
		out.close();
	}

	static class Pair implements Comparable<Pair>
	{
		int s, t;

		Pair(int a, int b) { s = a; t = b; }

		public int compareTo(Pair p)
		{
			if(s != p.s)
				return s - p.s;
			return t - p.t;
		}
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public Scanner(FileReader r){	br = new BufferedReader(r);}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException { return Double.parseDouble(next()); }

		public boolean ready() throws IOException {return br.ready();}

	}
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.Collections;
import java.util.StringTokenizer;

public class A {

	public static void main(String[] args) throws IOException
	{
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);

		int n = sc.nextInt();
		ArrayList<Integer> one = new ArrayList<>();
		ArrayList<Integer> two = new ArrayList<>();
		ArrayList<Pair> ans = new ArrayList<>();
		for(int i = 0; i < n; ++i)
			if(sc.nextInt() == 1)
				one.add(i);
			else
				two.add(i);

		ll: for(int i = 1; i <= n; ++i)
		{
			int j1 = 0, j2 = 0, pos = 0, lst = -1;
//			System.out.println(i);
			while(pos != n)
			{
				int ptr1 = Collections.binarySearch(one, pos);
				if(ptr1 < 0)
					ptr1 = -ptr1 - 1;

				int ptr2 = Collections.binarySearch(two, pos);
				if(ptr2 < 0)
					ptr2 = -ptr2 - 1;
//				System.out.println(ptr1 + " " + ptr2);
				ptr1 += i - 1;
				ptr2 += i - 1;
				int pos1 = ptr1 < one.size() ? one.get(ptr1) : n;
				int pos2 = ptr2 < two.size() ? two.get(ptr2) : n;
				if(pos1 == n && pos2 == n)
					continue ll;
//				System.out.println(pos1 + " " + pos2);
				if(pos1 < pos2)
				{
					++j1;
					pos = pos1 + 1;
					lst = 1;
				}
				else
				{
					++j2;
					pos = pos2 + 1;
					lst = 2;
				}
			}
			if(lst == 1 && j1 > j2)
				ans.add(new Pair(j1, i));
			if(lst == 2 && j2 > j1)
				ans.add(new Pair(j2, i));
		}
		out.println(ans.size());
		Collections.sort(ans);
		for(Pair p: ans)
			out.printf("%d %d\n", p.s, p.t);
		out.flush();
		out.close();
	}

	static class Pair implements Comparable<Pair>
	{
		int s, t;

		Pair(int a, int b) { s = a; t = b; }

		public int compareTo(Pair p)
		{
			if(s != p.s)
				return s - p.s;
			return t - p.t;
		}
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public Scanner(FileReader r){	br = new BufferedReader(r);}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

		public int nextInt() throws IOException {return Integer.parseInt(next());}

		public long nextLong() throws IOException {return Long.parseLong(next());}

		public String nextLine() throws IOException {return br.readLine();}

		public double nextDouble() throws IOException { return Double.parseDouble(next()); }

		public boolean ready() throws IOException {return br.ready();}

	}
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

public class TestClass {
	private static InputStream stream;
	private static byte[] buf = new byte[1024];
	private static int curChar;
	private static int numChars;
	private static SpaceCharFilter filter;
	private static PrintWriter pw;

	public static class Queue{
		private class node{
			int val;
			node next;
			node(int a){
				val = a;
				next = null;
			}
		}
		node head,tail;
		Queue(){
			head = null;
			tail = null;
		}
		public void EnQueue(int a){
			if(head==null){
				node p = new node(a);
				head = p;
				tail = p;
			}
			else{
				node p = new node(a);
				tail.next = p;
				tail = p;
			}
		}
		public int DeQueue(){
			int a = head.val;
			head = head.next;
			return a;
		}
		public boolean isEmpty(){
			return head==null;
		}
	}
	public static long pow(long x,long y,long m){
		if(y==0)
    		return 1;
    	long k = pow(x,y/2,m);
    	if(y%2==0)
    		return (k*k)%m;
    	else
    		return (((k*k)%m)*x)%m;
    }
	static long Inversex = 0,Inversey = 0;
	public static void InverseModulo(long a,long m){
		if(m==0){
			Inversex = 1;
			Inversey = 0;
		}
		else{
    		InverseModulo(m,a%m);
    		long temp = Inversex;
    		Inversex = Inversey;
    		Inversey = temp+ - (a/m)*Inversey;
    	}
    }
    static long mod1 = 1000000007;
    static long mod2 = 1000000009;
	public static long gcd(long a,long b){
		if(a%b==0)
			return b;
		return gcd(b,a%b);
	}
	public static boolean isPrime(long a){
		if(a==1)
			return false;
		else if(a==2||a==3)
			return true;
		for(long i=2;i<=Math.sqrt(a);i++)
			if(a%i==0)
				return false;
		return true;
	}
	public static double distance(int a,int b,int x,int y){
		return Math.sqrt(((long)(a-x)*(long)(a-x))+((long)(b-y)*(long)(b-y)));
	}
	public static class Pair implements Comparable<Pair> {
		long u;
		long v;
		BigInteger bi;
		public Pair(long u, long v) {
			this.u = u;
			this.v = v;
		}
		public int hashCode() {
			int hu = (int) (u ^ (u >>> 32));
			int hv = (int) (v ^ (v >>> 32));
			return 31 * hu + hv;
		}
		public boolean equals(Object o) {
			Pair other = (Pair) o;
			return u == other.u && v == other.v;
		}
		public int compareTo(Pair other) {
			return Long.compare(u, other.u) != 0 ? Long.compare(u, other.u) : Long.compare(v, other.v);
		}
		public String toString() {
			return u+" "+v;
		}
	}
	public static int sieve(int a[],boolean b[]){
		int count = 0;
		b[0] = true;
		b[1] = true;
		for(int i=2;i<a.length;i++){
			if(!b[i]){
				for(int j=2*i;j<a.length;j=j+i){
					b[j] = true;
				}
				a[count++] = i;
			}
		}
		return count;
	}
	public static void MatrixMultiplication(int a[][],int b[][],int c[][]){
		for(int i=0;i<a.length;i++){
			for(int j=0;j<b[0].length;j++){
				c[i][j] = 0;
				for(int k=0;k<b.length;k++)
					c[i][j]=(int)((c[i][j]+((a[i][k]*(long)b[k][j])%mod1))%mod1);
			}
		}
	}
	public static void Equal(int arr[][],int temp[][]){
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr.length;j++)
				temp[i][j] = arr[i][j];
		}
	}
	public static class Trie {
		Node head;
		private class Node{
			Node a[] = new Node[2];
			boolean val;
			Node(){
				a[0] = null;
				a[1] = null;
				val = false;
			}
		}
		Trie(){
			head = new Node();
		}
		public void insert(Stack<Integer> s){
			Node temp = head;
			while(!s.isEmpty()){
				int q = s.pop();
				if(temp.a[q]==null)
					temp.a[q] = new Node();
				temp = temp.a[q];
			}
			temp.val = true;
		}
		public Node delete(Stack<Integer> s,Node temp){
			if(s.isEmpty())
				return null;
			int q = s.pop();
			temp.a[q] = delete(s,temp.a[q]);
			if(temp.a[q]==null&&temp.a[q^1]==null)
				return null;
			else
				return temp;
		}
		public void get(Stack<Integer> s,Stack<Integer> p){
			Node temp = head;
			while(!p.isEmpty()){
				int q = p.pop();
				if(temp.a[q]!=null){
					s.push(q);
					temp = temp.a[q];
				}
				else{
					s.push(q^1);
					temp = temp.a[q^1];
				}
			}
		}
	}
	/*public static void Merge(long a[][],int p,int r){
        if(p<r){
            int q = (p+r)/2;
            Merge(a,p,q);
            Merge(a,q+1,r);
            Merge_Array(a,p,q,r);
        }
    }
	public static void get(long a[][],long b[][],int i,int j){
		for(int k=0;k<a[i].length;k++)
			a[i][k] = b[j][k];
	}
    public static void Merge_Array(long a[][],int p,int q,int r){
        long b[][] = new long[q-p+1][a[0].length];
        long c[][] = new long[r-q][a[0].length];
        for(int i=0;i<b.length;i++){
            get(b,a,i,p+i);
        }
        for(int i=0;i<c.length;i++){
            get(c,a,i,q+i+1);
        }
        int i = 0,j = 0;
        for(int k=p;k<=r;k++){
            if(i==b.length){
                get(a,c,k,j);
                j++;
            }
            else if(j==c.length){
                get(a,b,k,i);
                i++;
            }
            else if(b[i][0]<c[j][0]){
                get(a,b,k,i);
                i++;
            }
            else{
                get(a,c,k,j);
                j++;
            }
        }
    }
    public static void powMatrix(long n){
    	if(n<=1)
    		return ;
    	powMatrix(n/2);
    	MatrixMultiplication(temp2,temp2,result);
		Equal(result,temp2);
    	if(n%2==1){
    		MatrixMultiplication(temp2,a,result);
    		Equal(result,temp2);
    	}
    }
    static int result[][] = new int[4][4];
	static int temp[][] = new int[4][4];
	static int temp2[][] = new int[4][4];
	static int a[][] = new int[4][4];
	static int[][] b = new int[4][1];
	static int [][] c = new int[4][1];
    public static int count(long n){
		a[0][0] = 1 ;
		a[0][1] = 1;
		a[1][0] = 1;
		a[2][1] = 1;
		a[3][0] = 1;
		a[3][1] = 1;
		a[3][3] = 1;
		b[0][0] = 1;
		b[1][0] = 1;
		b[2][0] = 0;
		b[3][0] = 2;
		Equal(a,temp2);
		result[0][0] = 1;
		result[1][1] = 1;
		result[2][2] = 1;
		result[3][3] = 1;
		Equal(result,temp);
		if(n<=0)
			return 0;
		else if(n==1)
			return 1;
		else if(n==2)
			return 2;
		n = n-2;
		powMatrix(n);
		MatrixMultiplication(temp2,b,c);
		return c[3][0];
	}*/
	public static class SegmentTree{
		long[] arr = new long[5000000];
		long[] lazy = new long[5000000];
		SegmentTree(long a[]){
			Build(a,0,a.length-1,0);
		}
		public void Build(long a[],int p,int q,int r){
			if(p==q){
				arr[r] = a[p];
				return ;
			}
			int mid = (p+q)/2;
			Build(a,p,mid,2*r+1);
			Build(a,mid+1,q,2*r+2);
			arr[r] = Math.min(arr[2*r+1],arr[2*r+2]);
		}
		public long getSum(int p,int q,int x,int y,int z){
			if(lazy[z]!=0){
				arr[z]+=lazy[z];
				lazy[2*z+1]+=lazy[z];
				lazy[2*z+2]+=lazy[z];
				lazy[z] = 0;
			}
			if(y<p||x>q)
				return Long.MAX_VALUE;
			if(p<=x&&q>=y)
				return arr[z];
			int mid = (x+y)/2;
			return Math.min(getSum(p,q,x,mid,2*z+1),getSum(p,q,mid+1,y,2*z+2));
		}
		public void Update(int p,int q,int x,int y,int z,int dif){
			if(lazy[z]!=0){
				arr[z]+=lazy[z];
				lazy[2*z+1] += lazy[z];
				lazy[2*z+2] += lazy[z];
				lazy[z] = 0;
			}
			if(p>y||q<x||p>q)
				return ;
			if(x<=p&&q<=y){
				arr[z]+=dif;
				lazy[2*z+1]+=dif;
				lazy[2*z+2]+=dif;
				return ;
			}
			int mid = (p+q)/2;
			Update(p,mid,x,y,2*z+1,dif);
			Update(mid+1,q,x,y,2*z+2,dif);
			arr[z] = Math.min(arr[2*z+1],arr[2*z+2]);
		}
	}
	public static int bs(int a[],int p,int q,int val){
		int mid = (p+q)/2;
		if(a[mid]>=val&&a[mid-1]<val)
			return mid;
		if(a[mid]<val)
			return bs(a,mid+1,q,val);
		else
			return bs(a,p,mid,val);
	}
	private static void soln(){
		int n = nI(),last = 0;
		int a[][] = new int[2][n+2];
		int b[] = new int[2];
		for(int i=1;i<=n;i++){
			int p = nI()%2;
			if(i==n)
				last = p;
			a[p][i] = a[p][i-1]+1;
			b[p]++;
			p = p^1;
			a[p][i] = a[p][i-1];
		}
		a[0][n+1] = 100000000;
		a[1][n+1] = 100000000;
		if(b[last]<=b[last^1]){
			pw.println("0");
			return ;
		}
		//pw.println("Utsav");
		TreeSet<Pair> t = new TreeSet<Pair>();
		for(int i=1;i<=n;i++){
			int index = 0,val1 = i,val2 = i,c1 = 0,c2 = 0,counter = 0;
			while(index<n){
				int p = bs(a[0],1,n+1,val1);
				int q = bs(a[1],1,n+1,val2);
				//pw.println(i+" "+p+" "+q);
				if(p>q){
					val1 = a[0][q]+i;
					val2+=i;
					c2++;
				}
				else{
					c1++;
					val1+=i;
					val2 = a[1][p] + i;
				}
				index = Math.min(p, q);
				counter++;
			}
			//pw.println("AN "+c1+" "+c2);
			if(index==n){
				if(c1>c2&&last==0)
					t.add(new Pair(c1,i));
				else if(c1<c2&&last==1)
					t.add(new Pair(c2,i));
			}
		}
		pw.println(t.size());
		while(!t.isEmpty())
			pw.println(t.pollFirst().toString());
	}
	public static void main(String[] args) {
		InputReader(System.in);
		pw = new PrintWriter(System.out);
		soln();
		pw.close();
	}
	// To Get Input
	// Some Buffer Methods
	public static void InputReader(InputStream stream1) {
		stream = stream1;
	}
	private static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	private static boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
	private static int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	private static int nI() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	private static long nL() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	private static String nextToken() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}
	private static String nLi() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}
	private static int[] nIA(int n) {
		int[] arr = new int[n];
		for (int i = 0; i < n; i++)
			arr[i] = nI();
		return arr;
	}
	private static long[] nLA(int n) {
		long[] arr = new long[n];
		for (int i = 0; i < n; i++)
			arr[i] = nL();
		return arr;
	}
	private static void pArray(int[] arr) {
		for (int i = 0; i < arr.length; i++)
			pw.print(arr[i] + " ");
		pw.println();
		return;
	}
	private static void pArray(long[] arr) {
		for (int i = 0; i < arr.length; i++)
			pw.print(arr[i] + " ");
		pw.println();
		return;
	}
	private static boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}
	private interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

public class TestClass {
	private static InputStream stream;
	private static byte[] buf = new byte[1024];
	private static int curChar;
	private static int numChars;
	private static SpaceCharFilter filter;
	private static PrintWriter pw;

	public static class Queue{
		private class node{
			int val;
			node next;
			node(int a){
				val = a;
				next = null;
			}
		}
		node head,tail;
		Queue(){
			head = null;
			tail = null;
		}
		public void EnQueue(int a){
			if(head==null){
				node p = new node(a);
				head = p;
				tail = p;
			}
			else{
				node p = new node(a);
				tail.next = p;
				tail = p;
			}
		}
		public int DeQueue(){
			int a = head.val;
			head = head.next;
			return a;
		}
		public boolean isEmpty(){
			return head==null;
		}
	}
	public static long pow(long x,long y,long m){
		if(y==0)
    		return 1;
    	long k = pow(x,y/2,m);
    	if(y%2==0)
    		return (k*k)%m;
    	else
    		return (((k*k)%m)*x)%m;
    }
	static long Inversex = 0,Inversey = 0;
	public static void InverseModulo(long a,long m){
		if(m==0){
			Inversex = 1;
			Inversey = 0;
		}
		else{
    		InverseModulo(m,a%m);
    		long temp = Inversex;
    		Inversex = Inversey;
    		Inversey = temp+ - (a/m)*Inversey;
    	}
    }
    static long mod1 = 1000000007;
    static long mod2 = 1000000009;
	public static long gcd(long a,long b){
		if(a%b==0)
			return b;
		return gcd(b,a%b);
	}
	public static boolean isPrime(long a){
		if(a==1)
			return false;
		else if(a==2||a==3)
			return true;
		for(long i=2;i<=Math.sqrt(a);i++)
			if(a%i==0)
				return false;
		return true;
	}
	public static double distance(int a,int b,int x,int y){
		return Math.sqrt(((long)(a-x)*(long)(a-x))+((long)(b-y)*(long)(b-y)));
	}
	public static class Pair implements Comparable<Pair> {
		long u;
		long v;
		BigInteger bi;
		public Pair(long u, long v) {
			this.u = u;
			this.v = v;
		}
		public int hashCode() {
			int hu = (int) (u ^ (u >>> 32));
			int hv = (int) (v ^ (v >>> 32));
			return 31 * hu + hv;
		}
		public boolean equals(Object o) {
			Pair other = (Pair) o;
			return u == other.u && v == other.v;
		}
		public int compareTo(Pair other) {
			return Long.compare(u, other.u) != 0 ? Long.compare(u, other.u) : Long.compare(v, other.v);
		}
		public String toString() {
			return u+" "+v;
		}
	}
	public static int sieve(int a[],boolean b[]){
		int count = 0;
		b[0] = true;
		b[1] = true;
		for(int i=2;i<a.length;i++){
			if(!b[i]){
				for(int j=2*i;j<a.length;j=j+i){
					b[j] = true;
				}
				a[count++] = i;
			}
		}
		return count;
	}
	public static void MatrixMultiplication(int a[][],int b[][],int c[][]){
		for(int i=0;i<a.length;i++){
			for(int j=0;j<b[0].length;j++){
				c[i][j] = 0;
				for(int k=0;k<b.length;k++)
					c[i][j]=(int)((c[i][j]+((a[i][k]*(long)b[k][j])%mod1))%mod1);
			}
		}
	}
	public static void Equal(int arr[][],int temp[][]){
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr.length;j++)
				temp[i][j] = arr[i][j];
		}
	}
	public static class Trie {
		Node head;
		private class Node{
			Node a[] = new Node[2];
			boolean val;
			Node(){
				a[0] = null;
				a[1] = null;
				val = false;
			}
		}
		Trie(){
			head = new Node();
		}
		public void insert(Stack<Integer> s){
			Node temp = head;
			while(!s.isEmpty()){
				int q = s.pop();
				if(temp.a[q]==null)
					temp.a[q] = new Node();
				temp = temp.a[q];
			}
			temp.val = true;
		}
		public Node delete(Stack<Integer> s,Node temp){
			if(s.isEmpty())
				return null;
			int q = s.pop();
			temp.a[q] = delete(s,temp.a[q]);
			if(temp.a[q]==null&&temp.a[q^1]==null)
				return null;
			else
				return temp;
		}
		public void get(Stack<Integer> s,Stack<Integer> p){
			Node temp = head;
			while(!p.isEmpty()){
				int q = p.pop();
				if(temp.a[q]!=null){
					s.push(q);
					temp = temp.a[q];
				}
				else{
					s.push(q^1);
					temp = temp.a[q^1];
				}
			}
		}
	}
	/*public static void Merge(long a[][],int p,int r){
        if(p<r){
            int q = (p+r)/2;
            Merge(a,p,q);
            Merge(a,q+1,r);
            Merge_Array(a,p,q,r);
        }
    }
	public static void get(long a[][],long b[][],int i,int j){
		for(int k=0;k<a[i].length;k++)
			a[i][k] = b[j][k];
	}
    public static void Merge_Array(long a[][],int p,int q,int r){
        long b[][] = new long[q-p+1][a[0].length];
        long c[][] = new long[r-q][a[0].length];
        for(int i=0;i<b.length;i++){
            get(b,a,i,p+i);
        }
        for(int i=0;i<c.length;i++){
            get(c,a,i,q+i+1);
        }
        int i = 0,j = 0;
        for(int k=p;k<=r;k++){
            if(i==b.length){
                get(a,c,k,j);
                j++;
            }
            else if(j==c.length){
                get(a,b,k,i);
                i++;
            }
            else if(b[i][0]<c[j][0]){
                get(a,b,k,i);
                i++;
            }
            else{
                get(a,c,k,j);
                j++;
            }
        }
    }
    public static void powMatrix(long n){
    	if(n<=1)
    		return ;
    	powMatrix(n/2);
    	MatrixMultiplication(temp2,temp2,result);
		Equal(result,temp2);
    	if(n%2==1){
    		MatrixMultiplication(temp2,a,result);
    		Equal(result,temp2);
    	}
    }
    static int result[][] = new int[4][4];
	static int temp[][] = new int[4][4];
	static int temp2[][] = new int[4][4];
	static int a[][] = new int[4][4];
	static int[][] b = new int[4][1];
	static int [][] c = new int[4][1];
    public static int count(long n){
		a[0][0] = 1 ;
		a[0][1] = 1;
		a[1][0] = 1;
		a[2][1] = 1;
		a[3][0] = 1;
		a[3][1] = 1;
		a[3][3] = 1;
		b[0][0] = 1;
		b[1][0] = 1;
		b[2][0] = 0;
		b[3][0] = 2;
		Equal(a,temp2);
		result[0][0] = 1;
		result[1][1] = 1;
		result[2][2] = 1;
		result[3][3] = 1;
		Equal(result,temp);
		if(n<=0)
			return 0;
		else if(n==1)
			return 1;
		else if(n==2)
			return 2;
		n = n-2;
		powMatrix(n);
		MatrixMultiplication(temp2,b,c);
		return c[3][0];
	}*/
	public static class SegmentTree{
		long[] arr = new long[5000000];
		long[] lazy = new long[5000000];
		SegmentTree(long a[]){
			Build(a,0,a.length-1,0);
		}
		public void Build(long a[],int p,int q,int r){
			if(p==q){
				arr[r] = a[p];
				return ;
			}
			int mid = (p+q)/2;
			Build(a,p,mid,2*r+1);
			Build(a,mid+1,q,2*r+2);
			arr[r] = Math.min(arr[2*r+1],arr[2*r+2]);
		}
		public long getSum(int p,int q,int x,int y,int z){
			if(lazy[z]!=0){
				arr[z]+=lazy[z];
				lazy[2*z+1]+=lazy[z];
				lazy[2*z+2]+=lazy[z];
				lazy[z] = 0;
			}
			if(y<p||x>q)
				return Long.MAX_VALUE;
			if(p<=x&&q>=y)
				return arr[z];
			int mid = (x+y)/2;
			return Math.min(getSum(p,q,x,mid,2*z+1),getSum(p,q,mid+1,y,2*z+2));
		}
		public void Update(int p,int q,int x,int y,int z,int dif){
			if(lazy[z]!=0){
				arr[z]+=lazy[z];
				lazy[2*z+1] += lazy[z];
				lazy[2*z+2] += lazy[z];
				lazy[z] = 0;
			}
			if(p>y||q<x||p>q)
				return ;
			if(x<=p&&q<=y){
				arr[z]+=dif;
				lazy[2*z+1]+=dif;
				lazy[2*z+2]+=dif;
				return ;
			}
			int mid = (p+q)/2;
			Update(p,mid,x,y,2*z+1,dif);
			Update(mid+1,q,x,y,2*z+2,dif);
			arr[z] = Math.min(arr[2*z+1],arr[2*z+2]);
		}
	}
	public static int bs(int a[],int p,int q,int val){
		int mid = (p+q)/2;
		if(a[mid]>=val&&a[mid-1]<val)
			return mid;
		if(a[mid]<val)
			return bs(a,mid+1,q,val);
		else
			return bs(a,p,mid,val);
	}
	private static void soln(){
		int n = nI(),last = 0;
		int a[][] = new int[2][n+2];
		int b[] = new int[2];
		for(int i=1;i<=n;i++){
			int p = nI()%2;
			if(i==n)
				last = p;
			a[p][i] = a[p][i-1]+1;
			b[p]++;
			p = p^1;
			a[p][i] = a[p][i-1];
		}
		a[0][n+1] = 100000000;
		a[1][n+1] = 100000000;
		//pw.println("Utsav");
		TreeSet<Pair> t = new TreeSet<Pair>();
		for(int i=1;i<=n;i++){
			int index = 0,val1 = i,val2 = i,c1 = 0,c2 = 0,counter = 0;
			while(index<n){
				int p = bs(a[0],1,n+1,val1);
				int q = bs(a[1],1,n+1,val2);
				//pw.println(i+" "+p+" "+q);
				if(p>q){
					val1 = a[0][q]+i;
					val2+=i;
					c2++;
				}
				else{
					c1++;
					val1+=i;
					val2 = a[1][p] + i;
				}
				index = Math.min(p, q);
				counter++;
			}
			//pw.println("AN "+c1+" "+c2);
			if(index==n){
				if(c1>c2&&last==0)
					t.add(new Pair(c1,i));
				else if(c1<c2&&last==1)
					t.add(new Pair(c2,i));
			}
		}
		pw.println(t.size());
		while(!t.isEmpty())
			pw.println(t.pollFirst().toString());
	}
	public static void main(String[] args) {
		InputReader(System.in);
		pw = new PrintWriter(System.out);
		soln();
		pw.close();
	}
	// To Get Input
	// Some Buffer Methods
	public static void InputReader(InputStream stream1) {
		stream = stream1;
	}
	private static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	private static boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
	private static int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	private static int nI() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	private static long nL() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	private static String nextToken() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}
	private static String nLi() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}
	private static int[] nIA(int n) {
		int[] arr = new int[n];
		for (int i = 0; i < n; i++)
			arr[i] = nI();
		return arr;
	}
	private static long[] nLA(int n) {
		long[] arr = new long[n];
		for (int i = 0; i < n; i++)
			arr[i] = nL();
		return arr;
	}
	private static void pArray(int[] arr) {
		for (int i = 0; i < arr.length; i++)
			pw.print(arr[i] + " ");
		pw.println();
		return;
	}
	private static void pArray(long[] arr) {
		for (int i = 0; i < arr.length; i++)
			pw.print(arr[i] + " ");
		pw.println();
		return;
	}
	private static boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}
	private interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}


import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.*;
import java.util.Map.Entry;

public class TestClass {
	private static InputStream stream;
	private static byte[] buf = new byte[1024];
	private static int curChar;
	private static int numChars;
	private static SpaceCharFilter filter;
	private static PrintWriter pw;

	public static class Queue{
		private class node{
			int val;
			node next;
			node(int a){
				val = a;
				next = null;
			}
		}
		node head,tail;
		Queue(){
			head = null;
			tail = null;
		}
		public void EnQueue(int a){
			if(head==null){
				node p = new node(a);
				head = p;
				tail = p;
			}
			else{
				node p = new node(a);
				tail.next = p;
				tail = p;
			}
		}
		public int DeQueue(){
			int a = head.val;
			head = head.next;
			return a;
		}
		public boolean isEmpty(){
			return head==null;
		}
	}
	public static long pow(long x,long y,long m){
		if(y==0)
    		return 1;
    	long k = pow(x,y/2,m);
    	if(y%2==0)
    		return (k*k)%m;
    	else
    		return (((k*k)%m)*x)%m;
    }
	static long Inversex = 0,Inversey = 0;
	public static void InverseModulo(long a,long m){
		if(m==0){
			Inversex = 1;
			Inversey = 0;
		}
		else{
    		InverseModulo(m,a%m);
    		long temp = Inversex;
    		Inversex = Inversey;
    		Inversey = temp+ - (a/m)*Inversey;
    	}
    }
    static long mod1 = 1000000007;
    static long mod2 = 1000000009;
	public static long gcd(long a,long b){
		if(a%b==0)
			return b;
		return gcd(b,a%b);
	}
	public static boolean isPrime(long a){
		if(a==1)
			return false;
		else if(a==2||a==3)
			return true;
		for(long i=2;i<=Math.sqrt(a);i++)
			if(a%i==0)
				return false;
		return true;
	}
	public static double distance(int a,int b,int x,int y){
		return Math.sqrt(((long)(a-x)*(long)(a-x))+((long)(b-y)*(long)(b-y)));
	}
	public static class Pair implements Comparable<Pair> {
		long u;
		long v;
		BigInteger bi;
		public Pair(long u, long v) {
			this.u = u;
			this.v = v;
		}
		public int hashCode() {
			int hu = (int) (u ^ (u >>> 32));
			int hv = (int) (v ^ (v >>> 32));
			return 31 * hu + hv;
		}
		public boolean equals(Object o) {
			Pair other = (Pair) o;
			return u == other.u && v == other.v;
		}
		public int compareTo(Pair other) {
			return Long.compare(u, other.u) != 0 ? Long.compare(u, other.u) : Long.compare(v, other.v);
		}
		public String toString() {
			return u+" "+v;
		}
	}
	public static int sieve(int a[],boolean b[]){
		int count = 0;
		b[0] = true;
		b[1] = true;
		for(int i=2;i<a.length;i++){
			if(!b[i]){
				for(int j=2*i;j<a.length;j=j+i){
					b[j] = true;
				}
				a[count++] = i;
			}
		}
		return count;
	}
	public static void MatrixMultiplication(int a[][],int b[][],int c[][]){
		for(int i=0;i<a.length;i++){
			for(int j=0;j<b[0].length;j++){
				c[i][j] = 0;
				for(int k=0;k<b.length;k++)
					c[i][j]=(int)((c[i][j]+((a[i][k]*(long)b[k][j])%mod1))%mod1);
			}
		}
	}
	public static void Equal(int arr[][],int temp[][]){
		for(int i=0;i<arr.length;i++){
			for(int j=0;j<arr.length;j++)
				temp[i][j] = arr[i][j];
		}
	}
	public static class Trie {
		Node head;
		private class Node{
			Node a[] = new Node[2];
			boolean val;
			Node(){
				a[0] = null;
				a[1] = null;
				val = false;
			}
		}
		Trie(){
			head = new Node();
		}
		public void insert(Stack<Integer> s){
			Node temp = head;
			while(!s.isEmpty()){
				int q = s.pop();
				if(temp.a[q]==null)
					temp.a[q] = new Node();
				temp = temp.a[q];
			}
			temp.val = true;
		}
		public Node delete(Stack<Integer> s,Node temp){
			if(s.isEmpty())
				return null;
			int q = s.pop();
			temp.a[q] = delete(s,temp.a[q]);
			if(temp.a[q]==null&&temp.a[q^1]==null)
				return null;
			else
				return temp;
		}
		public void get(Stack<Integer> s,Stack<Integer> p){
			Node temp = head;
			while(!p.isEmpty()){
				int q = p.pop();
				if(temp.a[q]!=null){
					s.push(q);
					temp = temp.a[q];
				}
				else{
					s.push(q^1);
					temp = temp.a[q^1];
				}
			}
		}
	}
	/*public static void Merge(long a[][],int p,int r){
        if(p<r){
            int q = (p+r)/2;
            Merge(a,p,q);
            Merge(a,q+1,r);
            Merge_Array(a,p,q,r);
        }
    }
	public static void get(long a[][],long b[][],int i,int j){
		for(int k=0;k<a[i].length;k++)
			a[i][k] = b[j][k];
	}
    public static void Merge_Array(long a[][],int p,int q,int r){
        long b[][] = new long[q-p+1][a[0].length];
        long c[][] = new long[r-q][a[0].length];
        for(int i=0;i<b.length;i++){
            get(b,a,i,p+i);
        }
        for(int i=0;i<c.length;i++){
            get(c,a,i,q+i+1);
        }
        int i = 0,j = 0;
        for(int k=p;k<=r;k++){
            if(i==b.length){
                get(a,c,k,j);
                j++;
            }
            else if(j==c.length){
                get(a,b,k,i);
                i++;
            }
            else if(b[i][0]<c[j][0]){
                get(a,b,k,i);
                i++;
            }
            else{
                get(a,c,k,j);
                j++;
            }
        }
    }
    public static void powMatrix(long n){
    	if(n<=1)
    		return ;
    	powMatrix(n/2);
    	MatrixMultiplication(temp2,temp2,result);
		Equal(result,temp2);
    	if(n%2==1){
    		MatrixMultiplication(temp2,a,result);
    		Equal(result,temp2);
    	}
    }
    static int result[][] = new int[4][4];
	static int temp[][] = new int[4][4];
	static int temp2[][] = new int[4][4];
	static int a[][] = new int[4][4];
	static int[][] b = new int[4][1];
	static int [][] c = new int[4][1];
    public static int count(long n){
		a[0][0] = 1 ;
		a[0][1] = 1;
		a[1][0] = 1;
		a[2][1] = 1;
		a[3][0] = 1;
		a[3][1] = 1;
		a[3][3] = 1;
		b[0][0] = 1;
		b[1][0] = 1;
		b[2][0] = 0;
		b[3][0] = 2;
		Equal(a,temp2);
		result[0][0] = 1;
		result[1][1] = 1;
		result[2][2] = 1;
		result[3][3] = 1;
		Equal(result,temp);
		if(n<=0)
			return 0;
		else if(n==1)
			return 1;
		else if(n==2)
			return 2;
		n = n-2;
		powMatrix(n);
		MatrixMultiplication(temp2,b,c);
		return c[3][0];
	}*/
	public static class SegmentTree{
		long[] arr = new long[5000000];
		long[] lazy = new long[5000000];
		SegmentTree(long a[]){
			Build(a,0,a.length-1,0);
		}
		public void Build(long a[],int p,int q,int r){
			if(p==q){
				arr[r] = a[p];
				return ;
			}
			int mid = (p+q)/2;
			Build(a,p,mid,2*r+1);
			Build(a,mid+1,q,2*r+2);
			arr[r] = Math.min(arr[2*r+1],arr[2*r+2]);
		}
		public long getSum(int p,int q,int x,int y,int z){
			if(lazy[z]!=0){
				arr[z]+=lazy[z];
				lazy[2*z+1]+=lazy[z];
				lazy[2*z+2]+=lazy[z];
				lazy[z] = 0;
			}
			if(y<p||x>q)
				return Long.MAX_VALUE;
			if(p<=x&&q>=y)
				return arr[z];
			int mid = (x+y)/2;
			return Math.min(getSum(p,q,x,mid,2*z+1),getSum(p,q,mid+1,y,2*z+2));
		}
		public void Update(int p,int q,int x,int y,int z,int dif){
			if(lazy[z]!=0){
				arr[z]+=lazy[z];
				lazy[2*z+1] += lazy[z];
				lazy[2*z+2] += lazy[z];
				lazy[z] = 0;
			}
			if(p>y||q<x||p>q)
				return ;
			if(x<=p&&q<=y){
				arr[z]+=dif;
				lazy[2*z+1]+=dif;
				lazy[2*z+2]+=dif;
				return ;
			}
			int mid = (p+q)/2;
			Update(p,mid,x,y,2*z+1,dif);
			Update(mid+1,q,x,y,2*z+2,dif);
			arr[z] = Math.min(arr[2*z+1],arr[2*z+2]);
		}
	}
	public static int bs(int a[],int p,int q,int val){
		int mid = (p+q)/2;
		if(a[mid]>=val&&a[mid-1]<val)
			return mid;
		if(a[mid]<val)
			return bs(a,mid+1,q,val);
		else
			return bs(a,p,mid,val);
	}
	private static void soln(){
		int n = nI(),last = 0;
		int a[][] = new int[2][n+2];
		int b[] = new int[2];
		for(int i=1;i<=n;i++){
			int p = nI()%2;
			if(i==n)
				last = p;
			a[p][i] = a[p][i-1]+1;
			b[p]++;
			p = p^1;
			a[p][i] = a[p][i-1];
		}
		a[0][n+1] = 100000000;
		a[1][n+1] = 100000000;
		if(b[last]<=b[last^1])
			pw.println("0");
		//pw.println("Utsav");
		TreeSet<Pair> t = new TreeSet<Pair>();
		for(int i=1;i<=n;i++){
			int index = 0,val1 = i,val2 = i,c1 = 0,c2 = 0,counter = 0;
			while(index<n){
				int p = bs(a[0],1,n+1,val1);
				int q = bs(a[1],1,n+1,val2);
				//pw.println(i+" "+p+" "+q);
				if(p>q){
					val1 = a[0][q]+i;
					val2+=i;
					c2++;
				}
				else{
					c1++;
					val1+=i;
					val2 = a[1][p] + i;
				}
				index = Math.min(p, q);
				counter++;
			}
			//pw.println("AN "+c1+" "+c2);
			if(index==n){
				if(c1>c2&&last==0)
					t.add(new Pair(c1,i));
				else if(c1<c2&&last==1)
					t.add(new Pair(c2,i));
			}
		}
		pw.println(t.size());
		while(!t.isEmpty())
			pw.println(t.pollFirst().toString());
	}
	public static void main(String[] args) {
		InputReader(System.in);
		pw = new PrintWriter(System.out);
		soln();
		pw.close();
	}
	// To Get Input
	// Some Buffer Methods
	public static void InputReader(InputStream stream1) {
		stream = stream1;
	}
	private static boolean isWhitespace(int c) {
		return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
	}
	private static boolean isEndOfLine(int c) {
		return c == '\n' || c == '\r' || c == -1;
	}
	private static int read() {
		if (numChars == -1)
			throw new InputMismatchException();
		if (curChar >= numChars) {
			curChar = 0;
			try {
				numChars = stream.read(buf);
			} catch (IOException e) {
				throw new InputMismatchException();
			}
			if (numChars <= 0)
				return -1;
		}
		return buf[curChar++];
	}
	private static int nI() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		int res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	private static long nL() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		int sgn = 1;
		if (c == '-') {
			sgn = -1;
			c = read();
		}
		long res = 0;
		do {
			if (c < '0' || c > '9')
				throw new InputMismatchException();
			res *= 10;
			res += c - '0';
			c = read();
		} while (!isSpaceChar(c));
		return res * sgn;
	}
	private static String nextToken() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isSpaceChar(c));
		return res.toString();
	}
	private static String nLi() {
		int c = read();
		while (isSpaceChar(c))
			c = read();
		StringBuilder res = new StringBuilder();
		do {
			res.appendCodePoint(c);
			c = read();
		} while (!isEndOfLine(c));
		return res.toString();
	}
	private static int[] nIA(int n) {
		int[] arr = new int[n];
		for (int i = 0; i < n; i++)
			arr[i] = nI();
		return arr;
	}
	private static long[] nLA(int n) {
		long[] arr = new long[n];
		for (int i = 0; i < n; i++)
			arr[i] = nL();
		return arr;
	}
	private static void pArray(int[] arr) {
		for (int i = 0; i < arr.length; i++)
			pw.print(arr[i] + " ");
		pw.println();
		return;
	}
	private static void pArray(long[] arr) {
		for (int i = 0; i < arr.length; i++)
			pw.print(arr[i] + " ");
		pw.println();
		return;
	}
	private static boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}
	private interface SpaceCharFilter {
		public boolean isSpaceChar(int ch);
	}
}


import java.io.*;
import java.util.*;
//I am fading.......
//read the question correctly (is y a vowel? what are the exact constraints?)
//look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
public class Main
{
	public static void main(String[] args) throws Exception
	{
		int n=ni();
		int[]a=nia(n);
		int ct1=0,ct2=0;
		for(int i=0; i<n; i++)
			if(a[i]==1)
				ct1++;
			else
				ct2++;
		int co1[]=new int[2*n];
		int co2[]=new int[2*n];
		for(int i=0,j=0,k=0; i<n; i++)
			if(a[i]==1) co1[j++]=i;
			else if(a[i]==2) co2[k++]=i;
		for(int i=ct1; i<2*n; i++)
			co1[i]=1000000;
		for(int i=ct2; i<2*n; i++)
			co2[i]=1000000;
		int con1[]=new int[n];
		int con2[]=new int[n];
		for(int i=0; i<n; i++)
		{
			if(i!=0)
			{
			con1[i]+=con1[i-1];
			con2[i]+=con2[i-1];
			}
			if(a[i]==1)
				con1[i]++;
			else
				con2[i]++;
		}
		int ans=0;
		for(int i=1; i<=ct1; i++)
		{
			int te1=0,te2=0;
			for(int k=0,l=0; ;)
			{
				if(co1[k+i-1]<co2[l+i-1])
				{
					k+=i;
					l=con2[co1[k-1]];
					te1++;
				}
				else if(co1[k+i-1]>co2[l+i-1])
				{
					l+=i;
					k=con1[co2[l-1]];
					te2++;
				}
				else
					break;
				if(k==ct1&&l==ct2)
				{
					if(te1!=te2)
					{
						pr(i+" "+Math.max(te1, te2));
						ans++;
					}
					break;
				}
			}
		}
		sop(ans);
		System.out.println(output);
	}

	///////////////////////////////////////////
	///////////////////////////////////////////
	///template from here
	static class pair
	{
		int a,b;
		pair(){}
		pair(int c,int d){a=c;b=d;}
		@Override
		public int hashCode(){return (a+" "+b).hashCode();}
		@Override public boolean equals(Object c){if(a==((pair)c).a&&b==((pair)c).b)return true;return false;}
	}
	static interface combiner
	{
		public int combine(int a, int b);
	}
	static final int mod=1000000007;
	static final double eps=1e-8;
	static final long inf=100000000000000000L;
	static Reader in=new Reader();
	static StringBuilder output=new StringBuilder();
	static Random rn=new Random();
	public static void sort(int[]a)
	{
		int te;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
				a[i]^=a[te];
				a[te]^=a[i];
				a[i]^=a[te];
			}
		}
		Arrays.sort(a);
	}
	public static void sort(long[]a)
	{
		int te;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
			a[i]^=a[te];
			a[te]^=a[i];
			a[i]^=a[te];
			}
		}
		Arrays.sort(a);
	}
	public static void sort(double[]a)
	{
		int te;
		double te1;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
			te1=a[te];
			a[te]=a[i];
			a[i]=te1;
			}
		}
		Arrays.sort(a);
	}
	public static void sort(int[][]a)
	{
		Arrays.sort(a, new Comparator<int[]>()
		{
			public int compare(int[]a,int[]b)
			{
				if(a[0]>b[0])
					return 1;
				if(b[0]>a[0])
					return -1;
				return 0;
			}
		});
	}
	static int lowerbound(int[]a, int key)
	{
		/*
		 * returns index of smallest element larger than equal to given element between indices l and r inclusive
		 */
		int low=0,high=a.length-1,mid=(low+high)/2;
		while(low<high)
		{
			if(a[mid] >= key)
				high=mid;
			else
				low=mid+1;
			mid=(low+high)/2;
		}
		return mid;
	}
	static int upperbound(int[]a, int key)
	{
		int low=0,high=a.length-1,mid=(low+high+1)/2;
		while(low<high)
		{
			if(a[mid] <= key)
				low=mid;
			else
				high=mid-1;
			mid=(low+high+1)/2;
		}
		return mid;
	}
	static int lowerbound(int[]a, int l, int r, int key)
	{
		int low=l,high=r,mid=(low+high)/2;
		while(low<high)
		{
			if(a[mid] >= key)
				high=mid;
			else
				low=mid+1;
			mid=(low+high)/2;
		}
		return mid;
	}
	static int upperbound(int[]a, int l, int r, int key)
	{
		/*
		 * returns index of largest element smaller than equal to given element
		 */
		int low=l,high=r,mid=(low+high+1)/2;
		while(low<high)
		{
			if(a[mid] <= key)
				low=mid;
			else
				high=mid-1;
			mid=(low+high+1)/2;
		}
		return mid;
	}

	void sort(pair[]a)
	{
		Arrays.sort(a,new Comparator<pair>()
				{
			@Override
			public int compare(pair a,pair b)
			{
				if(a.a>b.a)
					return 1;
				if(b.a>a.a)
				return -1;
				return 0;
			}
				});
	}
	static int log2n(long a)
	{
		int te=0;
		while(a>0)
		{
			a>>=1;
			++te;
		}
		return te;
	}
	static class vecti
	{
		int a[],size;
		vecti(){a=new int[10];size=0;}
		vecti(int n){a=new int[n];size=0;}
		public void add(int b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
	}
	static class vectl
	{
		long a[];
		int size;
		vectl(){a=new long[10];size=0;}
		vectl(int n){a=new long[n];size=0;}
		public void add(long b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
	}
	static class vectd
	{
		double a[];
		int size;
		vectd(){a=new double[10];size=0;}
		vectd(int n){a=new double[n];size=0;}
		public void add(double b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
	}
	//output functions////////////////
	static void pr(Object a){output.append(a+"\n");}
	static void pr(){output.append("\n");}
	static void p(Object a){output.append(a);}
	static void pra(int[]a){for(int i:a)output.append(i+" ");output.append("\n");}
	static void pra(long[]a){for(long i:a)output.append(i+" ");output.append("\n");}
	static void pra(String[]a){for(String i:a)output.append(i+" ");output.append("\n");}
	static void pra(double[]a){for(double i:a)output.append(i+" ");output.append("\n");}
	static void sop(Object a){System.out.println(a);}
	static void flush(){System.out.println(output);output=new StringBuilder();}
	//////////////////////////////////
	//input functions/////////////////
	static int ni(){return Integer.parseInt(in.next());}
	static long nl(){return Long.parseLong(in.next());}
	static String ns(){return in.next();}
	static double nd(){return Double.parseDouble(in.next());}
	static int[] nia(int n){int a[]=new int[n];for(int i=0; i<n; i++)a[i]=ni();return a;}
	static int[] pnia(int n){int a[]=new int[n+1];for(int i=1; i<=n; i++)a[i]=ni();return a;}
	static long[] nla(int n){long a[]=new long[n];for(int i=0; i<n; i++)a[i]=nl();return a;}
	static String[] nsa(int n){String a[]=new String[n];for(int i=0; i<n; i++)a[i]=ns();return a;}
	static double[] nda(int n){double a[]=new double[n];for(int i=0; i<n; i++)a[i]=nd();return a;}
	//////////////////////////////////
	//some utility functions
	static void exit(){System.exit(0);}
	static int min(int... a){int min=a[0];for(int i:a)min=Math.min(min, i);return min;}
	static int max(int... a){int max=a[0];for(int i:a)max=Math.max(max, i);return max;}
	static int gcd(int... a){int gcd=a[0];for(int i:a)gcd=gcd(gcd, i);return gcd;}
	static String pr(String a, long b){String c="";while(b>0){if(b%2==1)c=c.concat(a);a=a.concat(a);b>>=1;}return c;}
	static long powm(long a, long b, long m){long an=1;long c=a;while(b>0){if(b%2==1)an=(an*c)%m;c=(c*c)%m;b>>=1;}return an;}
	static int gcd(int a, int b){if(b==0)return a;return gcd(b, a%b);}
	static class Reader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public Reader() {
            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
            tokenizer = null;
        }
        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
    }
}


import java.io.*;
import java.util.*;
//I am fading.......
//read the question correctly (is y a vowel? what are the exact constraints?)
//look out for SPECIAL CASES (n=1?) and overflow (ll vs int?)
public class Main
{
	public static void main(String[] args) throws Exception
	{
		int n=ni();
		int[]a=nia(n);
		int ct1=0,ct2=0;
		for(int i=0; i<n; i++)
			if(a[i]==1)
				ct1++;
			else
				ct2++;
		int co1[]=new int[2*n];
		int co2[]=new int[2*n];
		for(int i=0,j=0,k=0; i<n; i++)
			if(a[i]==1) co1[j++]=i;
			else if(a[i]==2) co2[k++]=i;
		for(int i=ct1; i<2*n; i++)
			co1[i]=1000000;
		for(int i=ct2; i<2*n; i++)
			co2[i]=1000000;
		int con1[]=new int[n];
		int con2[]=new int[n];
		for(int i=0; i<n; i++)
		{
			if(i!=0)
			{
			con1[i]+=con1[i-1];
			con2[i]+=con2[i-1];
			}
			if(a[i]==1)
				con1[i]++;
			else
				con2[i]++;
		}
		int ans=0;
		for(int i=ct1; i>0; i--)
		{
			int te1=0,te2=0;
			for(int k=0,l=0; ;)
			{
				pair mac1=new pair(),mac2=new pair();
				if(co1[k+i-1]<co2[l+i-1])
				{
					k+=i;
					l=con2[co1[k-1]];
					te1++;
					mac1.a=te1;
					mac1.b=te2;

				}
				else if(co1[k+i-1]>co2[l+i-1])
				{
					l+=i;
					k=con1[co2[l-1]];
					te2++;
					mac2.a=te1;
					mac2.b=te2;

				}
				else
					break;
				if(k==ct1&&l==ct2)
				{
					if(te1>te2&&mac1.a==te1&&mac1.b==te2)
					{
						pr(Math.max(te1, te2)+" "+i);
						ans++;
					}
					if(te1<te2&&mac2.a==te1&&mac2.b==te2)
					{
						pr(Math.max(te1, te2)+" "+i);
						ans++;
					}

					break;
				}
			}
		}
		sop(ans);
		System.out.print(output);
	}

	///////////////////////////////////////////
	///////////////////////////////////////////
	///template from here
	static class pair
	{
		int a,b;
		pair(){}
		pair(int c,int d){a=c;b=d;}
		@Override
		public int hashCode(){return (a+" "+b).hashCode();}
		@Override public boolean equals(Object c){if(a==((pair)c).a&&b==((pair)c).b)return true;return false;}
	}
	static interface combiner
	{
		public int combine(int a, int b);
	}
	static final int mod=1000000007;
	static final double eps=1e-8;
	static final long inf=100000000000000000L;
	static Reader in=new Reader();
	static StringBuilder output=new StringBuilder();
	static Random rn=new Random();
	public static void sort(int[]a)
	{
		int te;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
				a[i]^=a[te];
				a[te]^=a[i];
				a[i]^=a[te];
			}
		}
		Arrays.sort(a);
	}
	public static void sort(long[]a)
	{
		int te;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
			a[i]^=a[te];
			a[te]^=a[i];
			a[i]^=a[te];
			}
		}
		Arrays.sort(a);
	}
	public static void sort(double[]a)
	{
		int te;
		double te1;
		for(int i=0; i<a.length; i+=2)
		{
			te=rn.nextInt(a.length);
			if(i!=te)
			{
			te1=a[te];
			a[te]=a[i];
			a[i]=te1;
			}
		}
		Arrays.sort(a);
	}
	public static void sort(int[][]a)
	{
		Arrays.sort(a, new Comparator<int[]>()
		{
			public int compare(int[]a,int[]b)
			{
				if(a[0]>b[0])
					return 1;
				if(b[0]>a[0])
					return -1;
				return 0;
			}
		});
	}
	static int lowerbound(int[]a, int key)
	{
		/*
		 * returns index of smallest element larger than equal to given element between indices l and r inclusive
		 */
		int low=0,high=a.length-1,mid=(low+high)/2;
		while(low<high)
		{
			if(a[mid] >= key)
				high=mid;
			else
				low=mid+1;
			mid=(low+high)/2;
		}
		return mid;
	}
	static int upperbound(int[]a, int key)
	{
		int low=0,high=a.length-1,mid=(low+high+1)/2;
		while(low<high)
		{
			if(a[mid] <= key)
				low=mid;
			else
				high=mid-1;
			mid=(low+high+1)/2;
		}
		return mid;
	}
	static int lowerbound(int[]a, int l, int r, int key)
	{
		int low=l,high=r,mid=(low+high)/2;
		while(low<high)
		{
			if(a[mid] >= key)
				high=mid;
			else
				low=mid+1;
			mid=(low+high)/2;
		}
		return mid;
	}
	static int upperbound(int[]a, int l, int r, int key)
	{
		/*
		 * returns index of largest element smaller than equal to given element
		 */
		int low=l,high=r,mid=(low+high+1)/2;
		while(low<high)
		{
			if(a[mid] <= key)
				low=mid;
			else
				high=mid-1;
			mid=(low+high+1)/2;
		}
		return mid;
	}

	void sort(pair[]a)
	{
		Arrays.sort(a,new Comparator<pair>()
				{
			@Override
			public int compare(pair a,pair b)
			{
				if(a.a>b.a)
					return 1;
				if(b.a>a.a)
				return -1;
				return 0;
			}
				});
	}
	static int log2n(long a)
	{
		int te=0;
		while(a>0)
		{
			a>>=1;
			++te;
		}
		return te;
	}
	static class vecti
	{
		int a[],size;
		vecti(){a=new int[10];size=0;}
		vecti(int n){a=new int[n];size=0;}
		public void add(int b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
	}
	static class vectl
	{
		long a[];
		int size;
		vectl(){a=new long[10];size=0;}
		vectl(int n){a=new long[n];size=0;}
		public void add(long b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
	}
	static class vectd
	{
		double a[];
		int size;
		vectd(){a=new double[10];size=0;}
		vectd(int n){a=new double[n];size=0;}
		public void add(double b){if(++size==a.length)a=Arrays.copyOf(a, 2*size);a[size-1]=b;}
		public void sort(){Arrays.sort(a, 0, size);}
		public void sort(int l, int r){Arrays.sort(a, l, r);}
	}
	//output functions////////////////
	static void pr(Object a){output.append(a+"\n");}
	static void pr(){output.append("\n");}
	static void p(Object a){output.append(a);}
	static void pra(int[]a){for(int i:a)output.append(i+" ");output.append("\n");}
	static void pra(long[]a){for(long i:a)output.append(i+" ");output.append("\n");}
	static void pra(String[]a){for(String i:a)output.append(i+" ");output.append("\n");}
	static void pra(double[]a){for(double i:a)output.append(i+" ");output.append("\n");}
	static void sop(Object a){System.out.println(a);}
	static void flush(){System.out.println(output);output=new StringBuilder();}
	//////////////////////////////////
	//input functions/////////////////
	static int ni(){return Integer.parseInt(in.next());}
	static long nl(){return Long.parseLong(in.next());}
	static String ns(){return in.next();}
	static double nd(){return Double.parseDouble(in.next());}
	static int[] nia(int n){int a[]=new int[n];for(int i=0; i<n; i++)a[i]=ni();return a;}
	static int[] pnia(int n){int a[]=new int[n+1];for(int i=1; i<=n; i++)a[i]=ni();return a;}
	static long[] nla(int n){long a[]=new long[n];for(int i=0; i<n; i++)a[i]=nl();return a;}
	static String[] nsa(int n){String a[]=new String[n];for(int i=0; i<n; i++)a[i]=ns();return a;}
	static double[] nda(int n){double a[]=new double[n];for(int i=0; i<n; i++)a[i]=nd();return a;}
	//////////////////////////////////
	//some utility functions
	static void exit(){System.exit(0);}
	static int min(int... a){int min=a[0];for(int i:a)min=Math.min(min, i);return min;}
	static int max(int... a){int max=a[0];for(int i:a)max=Math.max(max, i);return max;}
	static int gcd(int... a){int gcd=a[0];for(int i:a)gcd=gcd(gcd, i);return gcd;}
	static String pr(String a, long b){String c="";while(b>0){if(b%2==1)c=c.concat(a);a=a.concat(a);b>>=1;}return c;}
	static long powm(long a, long b, long m){long an=1;long c=a;while(b>0){if(b%2==1)an=(an*c)%m;c=(c*c)%m;b>>=1;}return an;}
	static int gcd(int a, int b){if(b==0)return a;return gcd(b, a%b);}
	static class Reader {
        public BufferedReader reader;
        public StringTokenizer tokenizer;
        public Reader() {
            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
            tokenizer = null;
        }
        public String next() {
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            return tokenizer.nextToken();
        }
    }
}