    import java.io.*;
    import java.util.*;
    import java.math.*;
    import java.text.*;
    public class Main3 {
        public static int n, k, nk, b;
        public static void fact(int value)
        {
            nk = 0;
            if ( value != 0)
            {
                while( value % k == 0 )
                {
                    nk++;
                    value /= k;
                }
            }
            b = value;

        }
        public static long maxL( long a, long b)
        {
            if ( a > b) return a;
            return b;
        }
    public static void main(String[] args) throws IOException {
        BufferedReader in;
        StringBuilder out = new StringBuilder();
        File file = new File("in");
        if (file.exists())
            in = new BufferedReader(new FileReader(file));
        else
            in = new BufferedReader(new InputStreamReader(System.in));
        String line, lines[];

        lines = in.readLine().split(" ");
        n = Integer.parseInt(lines[0]);
        k = Integer.parseInt(lines[1]);
        lines = in.readLine().split(" ");
        int arr[] = new int[n];
        ArrayList<Integer> ls[] = new ArrayList[n];
        int keys[] = new int[n];
        int count= 0;
        long countZ = 0;
        for (  int i = 0; i < n; i++ )
        {
            arr[i] = Integer.parseInt(lines[i]);
            if ( arr[i] == 0) countZ++;
        }
        countZ = countZ*(countZ-1)*(countZ-2);
        countZ /= 6l;
        if ( k != 1)
        {
            HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
            int value;
            for ( int i = 0; i < n; i++ )
            {
                fact(arr[i]);
                if ( map.containsKey(b))
                {
                    value = map.get(b);
                    ls[value].add(nk);
                }
                else
                {
                    ls[count] = new ArrayList<Integer>();
                    ls[count].add(nk);
                    map.put(b, count);
                    count++;
                }
            }
            long result = 0l;
            int l;
            long pow[];
            long pares[];
            for ( int i = 0; i < count; i++ )
            {
                pow = new long[30];
                pares = new long[30];
                for (int auxL : ls[i]) {
                    if ( auxL >= 2)
                    {
                        result += (long)(pares[auxL-1]);
                    }
                    if ( auxL >= 1)
                    {
                        pares[auxL] += pow[auxL-1];
                    }
                    pow[auxL]++;
                }
            }
            System.out.println(maxL(result, countZ));
        }
        else
        {
            HashMap<Integer,Long> mapV = new HashMap<Integer, Long>();
            long r = 0l;
            long ot = 0l;
            BigInteger resp = new BigInteger("0");
            for ( int i = 0; i < n; i++ )
            {
                if ( !mapV.containsKey(arr[i]))
                {
                    mapV.put(arr[i], 1l);
                }
                else
                {
                    long aux = mapV.get(arr[i]);
                    mapV.put(arr[i], aux+1l);
                    if ( aux>= 2)
                    {
                        ot = (long)(aux);
                        BigInteger auxB1 = new BigInteger(ot+"");
                        BigInteger auxB2 = new BigInteger((ot-1)+"");
                        auxB1 = auxB1.multiply(auxB2);
                        auxB1 = auxB1.divide(new BigInteger("2"));
                        resp = resp.add(auxB1);
                    }
                }
            }
            System.out.println(maxL(Long.parseLong(resp.toString()), countZ));
        }
    }
    }


    import java.io.*;
    import java.util.*;
    import java.math.*;
    import java.text.*;
    public class Main3 {
        public static int n, k, nk, b;
        public static void fact(int value)
        {
            nk = 0;
            if ( value != 0)
            {
                while( value % k == 0 )
                {
                    nk++;
                    value /= k;
                }
            }
            b = value;

        }
    public static void main(String[] args) throws IOException {
        BufferedReader in;
        StringBuilder out = new StringBuilder();
        File file = new File("in");
        if (file.exists())
            in = new BufferedReader(new FileReader(file));
        else
            in = new BufferedReader(new InputStreamReader(System.in));
        String line, lines[];

        lines = in.readLine().split(" ");
        n = Integer.parseInt(lines[0]);
        k = Integer.parseInt(lines[1]);
        lines = in.readLine().split(" ");
        int arr[] = new int[n];
        ArrayList<Integer> ls[] = new ArrayList[n];
        int keys[] = new int[n];
        int count= 0;
        for (  int i = 0; i < n; i++ )
        {
            arr[i] = Integer.parseInt(lines[i]);
        }
        if ( k != 1)
        {
            HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
            int value;
            for ( int i = 0; i < n; i++ )
            {
                fact(arr[i]);
                if ( map.containsKey(b))
                {
                    value = map.get(b);
                    ls[value].add(nk);
                }
                else
                {
                    ls[count] = new ArrayList<Integer>();
                    ls[count].add(nk);
                    map.put(b, count);
                    count++;
                }
            }
            long result = 0l;
            int l;
            long pow[];
            long pares[];
            for ( int i = 0; i < count; i++ )
            {
                pow = new long[30];
                pares = new long[30];
                for (int auxL : ls[i]) {
                    if ( auxL >= 2)
                    {
                        result += (long)(pares[auxL-1]);
                    }
                    if ( auxL >= 1)
                    {
                        pares[auxL] += pow[auxL-1];
                    }
                    pow[auxL]++;
                }
            }
            System.out.println(result);
        }
        else
        {
            HashMap<Integer,Long> mapV = new HashMap<Integer, Long>();
            long r = 0l;
            long ot = 0l;
            BigInteger resp = new BigInteger("0");
            for ( int i = 0; i < n; i++ )
            {
                if ( !mapV.containsKey(arr[i]))
                {
                    mapV.put(arr[i], 1l);
                }
                else
                {
                    long aux = mapV.get(arr[i]);
                    mapV.put(arr[i], aux+1l);
                    if ( aux>= 2)
                    {
                        ot = (long)(aux);
                        BigInteger auxB1 = new BigInteger(ot+"");
                        BigInteger auxB2 = new BigInteger((ot-1)+"");
                        auxB1 = auxB1.multiply(auxB2);
                        auxB1 = auxB1.divide(new BigInteger("2"));
                        resp = resp.add(auxB1);
                    }
                }
            }
            System.out.println(resp.toString());
        }
    }
    }


import java.io.*;
import java.util.*;
import java.math.*;
import java.text.*;
public class Main3 {
    public static int n, k, nk, b;
    public static void fact(int value)
    {
        nk = 0;
        while( value % k == 0)
        {
            nk++;
            value /= k;
        }
        b = value;

    }
public static void main(String[] args) throws IOException {
    BufferedReader in;
    StringBuilder out = new StringBuilder();
    File file = new File("in");
    if (file.exists())
        in = new BufferedReader(new FileReader(file));
    else
        in = new BufferedReader(new InputStreamReader(System.in));
    String line, lines[];

    lines = in.readLine().split(" ");
    n = Integer.parseInt(lines[0]);
    k = Integer.parseInt(lines[1]);
    lines = in.readLine().split(" ");
    int arr[] = new int[n];
    ArrayList<Integer> ls[] = new ArrayList[n];
    int keys[] = new int[n];
    int count= 0;
    for (  int i = 0; i < n; i++ )
    {
        arr[i] = Integer.parseInt(lines[i]);
    }
    if ( k != 1)
    {
        HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
        int value;
        for ( int i = 0; i < n; i++ )
        {
            fact(arr[i]);
            if ( map.containsKey(b))
            {
                value = map.get(b);
                ls[value].add(nk);
            }
            else
            {
                ls[count] = new ArrayList<Integer>();
                ls[count].add(nk);
                map.put(b, count);
                count++;
            }
        }
        long result = 0l;
        int l;
        int pow[];
        int pares[];
        for ( int i = 0; i < count; i++ )
        {
            pow = new int[30];
            pares = new int[30];
            for (int auxL : ls[i]) {
                if ( auxL >= 2)
                {
                    result += (long)(pares[auxL-1]);
                }
                if ( auxL >= 1)
                {
                    pares[auxL] += pow[auxL-1];
                }
                pow[auxL]++;
            }
        }
        System.out.println(result);
    }
    else
    {
        HashMap<Integer,Long> mapV = new HashMap<Integer, Long>();
        long r = 0l;
        long ot = 0l;
        BigInteger resp = new BigInteger("0");
        for ( int i = 0; i < n; i++ )
        {
            if ( !mapV.containsKey(arr[i]))
            {
                mapV.put(arr[i], 1l);
            }
            else
            {
                long aux = mapV.get(arr[i]);
                mapV.put(arr[i], aux+1l);
                if ( aux>= 2)
                {
                    ot = (long)(aux);
                    BigInteger auxB1 = new BigInteger(ot+"");
                    BigInteger auxB2 = new BigInteger((ot-1)+"");
                    auxB1 = auxB1.multiply(auxB2);
                    auxB1 = auxB1.divide(new BigInteger("2"));
                    resp = resp.add(auxB1);
                }
            }
        }
        System.out.println(resp.toString());
    }
}
}


import java.io.*;
import java.util.*;
import java.math.*;
import java.text.*;
public class Main3 {
    public static int n, k, nk, b;
    public static void fact(int value)
    {
        nk = 0;
        while( value % k == 0)
        {
            nk++;
            value /= k;
        }
        b = value;

    }
public static void main(String[] args) throws IOException {
    BufferedReader in;
    StringBuilder out = new StringBuilder();
    File file = new File("in");
    if (file.exists())
        in = new BufferedReader(new FileReader(file));
    else
        in = new BufferedReader(new InputStreamReader(System.in));
    String line, lines[];

    lines = in.readLine().split(" ");
    n = Integer.parseInt(lines[0]);
    k = Integer.parseInt(lines[1]);
    lines = in.readLine().split(" ");
    int arr[] = new int[n];
    ArrayList<Integer> ls[] = new ArrayList[n];
    int keys[] = new int[n];
    int count= 0;
    for (  int i = 0; i < n; i++ )
    {
        arr[i] = Integer.parseInt(lines[i]);
    }
    if ( k != 1)
    {
        HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
        int value;
        for ( int i = 0; i < n; i++ )
        {
            fact(arr[i]);
            if ( map.containsKey(b))
            {
                value = map.get(b);
                ls[value].add(nk);
            }
            else
            {
                ls[count] = new ArrayList<Integer>();
                ls[count].add(nk);
                map.put(b, count);
                count++;
            }
        }
        long result = 0l;
        int l;
        int pow[];
        int pares[];
        for ( int i = 0; i < count; i++ )
        {
            pow = new int[30];
            pares = new int[30];
            for (int auxL : ls[i]) {
                if ( auxL >= 2)
                {
                    result += (long)(pares[auxL-1]);
                }
                if ( auxL >= 1)
                {
                    pares[auxL] += pow[auxL-1];
                }
                pow[auxL]++;
            }
        }
        System.out.println(result);
    }
    else
    {
        HashMap<Integer,Long> mapV = new HashMap<Integer, Long>();
        long r = 0l;
        long ot = 0l;
        for ( int i = 0; i < n; i++ )
        {
            if ( !mapV.containsKey(arr[i]))
            {
                mapV.put(arr[i], 1l);
            }
            else
            {
                long aux = mapV.get(arr[i]);
                mapV.put(arr[i], aux+1l);
                if ( aux>= 2)
                {
                    ot = (long)(aux);
                    r += (ot*(ot-1l))/2l;
                }
            }
        }
        System.out.println(r);
    }
}
}


import java.io.*;
import java.util.*;
import java.math.*;
import java.text.*;
public class Main3 {
    public static int n, k, nk, b;
    public static void fact(int value)
    {
        nk = 0;
        while( value % k == 0)
        {
            nk++;
            value /= k;
        }
        b = value;

    }
public static void main(String[] args) throws IOException {
    BufferedReader in;
    StringBuilder out = new StringBuilder();
    File file = new File("in");
    if (file.exists())
        in = new BufferedReader(new FileReader(file));
    else
        in = new BufferedReader(new InputStreamReader(System.in));
    String line, lines[];

    lines = in.readLine().split(" ");
    n = Integer.parseInt(lines[0]);
    k = Integer.parseInt(lines[1]);
    lines = in.readLine().split(" ");
    int arr[] = new int[n];
    ArrayList<Integer> ls[] = new ArrayList[n];
    int keys[] = new int[n];
    int count= 0;
    for (  int i = 0; i < n; i++ )
    {
        arr[i] = Integer.parseInt(lines[i]);
    }
    if ( k != 1)
    {
        HashMap<Integer,Integer> map = new HashMap<Integer, Integer>();
        int value;
        for ( int i = 0; i < n; i++ )
        {
            fact(arr[i]);
            if ( map.containsKey(b))
            {
                value = map.get(b);
                ls[value].add(nk);
            }
            else
            {
                ls[count] = new ArrayList<Integer>();
                ls[count].add(nk);
                map.put(b, count);
                count++;
            }
        }
        long result = 0l;
        int l;
        int pow[];
        int pares[];
        for ( int i = 0; i < count; i++ )
        {
            pow = new int[30];
            pares = new int[30];
            for (int auxL : ls[i]) {
                if ( auxL >= 2)
                {
                    result += (long)(pares[auxL-1]);
                }
                if ( auxL >= 1)
                {
                    pares[auxL] += pow[auxL-1];
                }
                pow[auxL]++;
            }
        }
        System.out.println(result);
    }
    else
    {
        HashMap<Integer,Integer> mapV = new HashMap<Integer, Integer>();
        long r = 0;
        long ot = 0;
        for ( int i = 0; i < n; i++ )
        {
            if ( !mapV.containsKey(arr[i]))
            {
                mapV.put(arr[i], 1);
            }
            else
            {
                int aux = mapV.get(arr[i]);
                mapV.put(arr[i], aux+1);
                if ( aux>= 2)
                {
                    ot = aux;
                    r += (ot*(ot-1))/2l;
                }
            }
        }
        System.out.println(r);
    }
}
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;

public class CF {

	static InputReader in = new InputReader(System.in);

	public static void main(String[] args) {

		int n = in.nextInt();
		int k = in.nextInt();

		int[] arr = new int[n];

		HashMap<Integer, Long> r = new HashMap<>();
		HashMap<Integer, Long> l = new HashMap<>();

		for (int i = 0; i < n; i++) {
			arr[i] = in.nextInt();
			if (r.containsKey(arr[i])) {
				r.put(arr[i], r.get(arr[i]) + 1);
			} else {
				r.put(arr[i], (long) 1);
			}
		}

		long ans = 0;

		for (int i = 0; i < n; i++) {

			long k1 = 0, k2 = 0;

			if (arr[i] % k == 0 && l.containsKey(arr[i] / k)) {
				k1 = l.get(arr[i] / k);
			}

			r.put(arr[i], r.get(arr[i]) - 1);

			if (r.containsKey(arr[i] * k))
				k2 = r.get(arr[i] * k);

			ans += k1 * k2;

			if (l.containsKey(arr[i]))
				l.put(arr[i], l.get(arr[i]) + 1);
			else
				l.put(arr[i], (long) 1);

		}

		System.out.println(ans);
	}
}

class InputReader {
	private BufferedReader reader;
	private StringTokenizer tokenizer;

	public InputReader(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream), 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();
	}

	public String readLine() {
		try {
			return reader.readLine();
		} catch (IOException e) {
			throw new RuntimeException(e);
		}
	}

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

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

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

	public float nextFloat() {
		return Float.parseFloat(next());
	}

}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class CF {

    static InputReader in = new InputReader(System.in);

    public static void main(String[] args) {

        int n = in.nextInt();
        long k = in.nextLong();

        HashMap<Integer, TreeMap<Integer, Integer>> count = new HashMap<Integer, TreeMap<Integer, Integer>>();

        if (n < 3) {
            System.out.println(0);
        } else if (k == 1) {

            long result = 0;

            TreeMap<Integer, Integer> tm;

            for (int i = 0; i < n; i++) {

                int v = in.nextInt();

                tm = count.get(v);
                if (tm == null)
                    tm = new TreeMap<>();
                tm.put(i, tm.size());
                count.put(v, tm);
            }

            for (Entry<Integer, TreeMap<Integer, Integer>> entry : count
                    .entrySet()) {

                result += entry.getValue().size()
                        * (entry.getValue().size() - 1)
                        * (entry.getValue().size() - 2) / (3 * 2);
            }

            System.out.println(result);

        } else {

            int zeros = 0;

            int first = in.nextInt();
            int second = in.nextInt();

            if (first == 0)
                zeros++;
            if (second == 0)
                zeros++;

            TreeMap<Integer, Integer> tm = count.get(first);
            if (tm == null)
                tm = new TreeMap<>();
            tm.put(0, tm.size());
            count.put(first, tm);

            tm = count.get(second);
            if (tm == null)
                tm = new TreeMap<>();
            tm.put(1, tm.size());
            count.put(second, tm);

            long result = 0;

            for (int i = 2; i < n; i++) {

                int v = in.nextInt();

                if (v % k == 0 && v % (k * k) == 0
                        && count.containsKey((int) (v / k))
                        && count.containsKey((int) (v / (k * k)))
                        && count.get((int) (v / k)).size() != 0
                        && count.get((int) (v / (k * k))).size() != 0) {

                    if (v / (k * k) == 0) {
                        zeros++;
                        continue;
                    }

                    for (Map.Entry<Integer, Integer> entry : count.get(
                            (int) (v / (k * k))).entrySet()) {

                        {
                            result += (count.get((int) (v / k)).size() - count
                                    .get((int) (v / k))
                                    .ceilingEntry(entry.getKey()).getValue());
                        }

                    }
                }

                tm = count.get(v);
                if (tm == null)
                    tm = new TreeMap<>();
                tm.put(i, tm.size());
                count.put(v, tm);

            }

            System.out
                    .println(result += (zeros * (zeros - 1) * (zeros - 2) / 6));
        }
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 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();
    }

    public String readLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

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

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

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

    public float nextFloat() {
        return Float.parseFloat(next());
    }

}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    static int[] wins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        wins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        for (int i = 0; i < seq; i++) {
            wins[i] = st.nextToken().charAt(0) == '1' ? 1 : -1;
            if (wins[i] == 1) {
                p++;
            } else {
                g++;
            }
        }

        if (p == g || (p > g && wins[seq-1] == -1) || (g>p && wins[seq-1]==1)) {
            System.out.println(0);
        } else {
            TreeSet<String> set = new TreeSet<String>();

            int max = p > g ? p : g;

            set.add("1 " + max);
            set.add(max + " 1");

            for (int i = 2; i <= Math.sqrt(max); i++) {
                if (max % i == 0) {
                    int other = max / i;

                    if (other % 2 == 1 || valid(i, other)) {
                        set.add(i + " " + other);
                    }

                    if (i % 2 == 1 || valid(other, i)) {
                        set.add(other + " " + i);
                    }
                }
            }

            System.out.println(set.size());
            for (String s : set) {
                System.out.println(s);
            }

        }

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    static int[] wins;
    static int[] pwins;
    static int[] gwins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        pwins = new int[seq];
        gwins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        char ch = '0';
        for (int i = 0; i < seq; i++) {
            ch = st.nextToken().charAt(0);
            if (ch == '1') {
                p++;
            } else {
                g++;
            }
            pwins[i] = p;
            gwins[i] = g;
        }

        if (p == g || (p > g && ch == '2') || (g>p && ch == '1')) {
            System.out.println(0);
        } else {
            int max = p > g ? p : g;

            System.out.println("1 " + max);

            int setp = 0, setg = 0, minusp = 0, minusg = 0;
            for (int games = max-1; games >1; games--) {
                int index = games - 1;
                setp = setg = minusp = minusg = 0;
                boolean valid = true;
                while (true) {
                    if (index >= seq) {
                        valid = false;
                        break;
                    }
                    if (pwins[index]-minusp == games || gwins[index]-minusg== games) {
                        if (pwins[index]-minusp == games) {
                            setp++;
                        } else {
                            setg++;
                        }
                        minusp = pwins[index];
                        minusg = gwins[index];
                        if (index == seq - 1) {
                            valid = setp != setg;
                            break;
                        } else {
                            index += games;
                        }
                    } else {
                        index += games - Math.max(pwins[index]-minusp, gwins[index]-minusg);
                    }
                }

                if (valid) {
                    System.out.println(Math.max(setp, setg) + " " + games/* + " " + setp + " " + setg*/);
                }
            }
            System.out.println(max + " 1");

            /*
            TreeSet<String> set = new TreeSet<String>();

            set.add("1 " + max);
            set.add(max + " 1");

            for (int i = 2; i <= Math.sqrt(max); i++) {
                if (max % i == 0) {
                    int other = max / i;

                    if (other % 2 == 1 || valid(i, other)) {
                        set.add(i + " " + other);
                    }

                    if (i % 2 == 1 || valid(other, i)) {
                        set.add(other + " " + i);
                    }
                }
            }

            System.out.println(set.size());
            for (String s : set) {
                System.out.println(s);
            }*/

        }

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    static int[] wins;
    static int[] pwins;
    static int[] gwins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        pwins = new int[seq];
        gwins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        char ch = '0';
        for (int i = 0; i < seq; i++) {
            ch = st.nextToken().charAt(0);
            if (ch == '1') {
                p++;
            } else {
                g++;
            }
            pwins[i] = p;
            gwins[i] = g;
        }

        if (p == g || (p > g && ch == '2') || (g>p && ch == '1')) {
            System.out.println(0);
        } else {
            int max = p > g ? p : g;

            ArrayList<String> solutions = new ArrayList<String>();
            solutions.add("1 " + max);

            int setp = 0, setg = 0, minusp = 0, minusg = 0;
            for (int games = max-1; games >1; games--) {
                int index = games - 1;
                setp = setg = minusp = minusg = 0;
                boolean valid = true;
                while (true) {
                    if (index >= seq) {
                        valid = false;
                        break;
                    }
                    if (pwins[index]-minusp == games || gwins[index]-minusg== games) {
                        if (pwins[index]-minusp == games) {
                            setp++;
                        } else {
                            setg++;
                        }
                        minusp = pwins[index];
                        minusg = gwins[index];
                        if (index == seq - 1) {
                            valid = setp != setg;
                            break;
                        } else {
                            index += games;
                        }
                    } else {
                        index += games - Math.max(pwins[index]-minusp, gwins[index]-minusg);
                    }
                }

                if (valid) {
                    solutions.add(Math.max(setp, setg) + " " + games);
                }
            }
            solutions.add(max + " 1");

            int sols = solutions.size();
            System.out.println(sols);
            for (String s : solutions) {
                System.out.println(s);
            }

            /*
            TreeSet<String> set = new TreeSet<String>();

            set.add("1 " + max);
            set.add(max + " 1");

            for (int i = 2; i <= Math.sqrt(max); i++) {
                if (max % i == 0) {
                    int other = max / i;

                    if (other % 2 == 1 || valid(i, other)) {
                        set.add(i + " " + other);
                    }

                    if (i % 2 == 1 || valid(other, i)) {
                        set.add(other + " " + i);
                    }
                }
            }

            System.out.println(set.size());
            for (String s : set) {
                System.out.println(s);
            }*/

        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

public class Main {

    static int[] wins;
    static int[] pwins;
    static int[] gwins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        pwins = new int[seq];
        gwins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        char ch = '0';
        for (int i = 0; i < seq; i++) {
            ch = st.nextToken().charAt(0);
            if (ch == '1') {
                p++;
            } else {
                g++;
            }
            pwins[i] = p;
            gwins[i] = g;
        }

        int max = p > g ? p : g;

        TreeMap<Integer, TreeSet<Integer>> solutions = new TreeMap<>();

        int setp = 0, setg = 0, minusp = 0, minusg = 0;
        int totalsolutions = 0;

        for (int games = max; games >= 1; games--) {
            int index = games - 1;
            setp = setg = minusp = minusg = 0;
            boolean valid = true;
            while (true) {
                if (index >= seq) {
                    valid = false;
                    break;
                }
                if (pwins[index] - minusp == games || gwins[index] - minusg == games) {
                    if (pwins[index] - minusp == games) {
                        setp++;
                    } else {
                        setg++;
                    }
                    minusp = pwins[index];
                    minusg = gwins[index];
                    if (index == seq - 1) {
                        valid = (setp > setg && ch == '1') || (setg > setp && ch == '2');
                        break;
                    } else {
                        index += games;
                    }
                } else {
                    index += games - Math.max(pwins[index] - minusp, gwins[index] - minusg);
                }
            }

            if (valid) {
                totalsolutions++;
                int sets = Math.max(setp, setg);
                TreeSet<Integer> sol;
                if (solutions.containsKey(sets)) {
                    sol = solutions.get(sets);
                } else {
                    sol = new TreeSet<>();
                }
                sol.add(games);
                solutions.put(sets, sol);
            }
        }

        System.out.println(totalsolutions);
        for (int setno : solutions.keySet()) {
            TreeSet<Integer> sol = solutions.get(setno);
            for (int gameno : sol) {
                System.out.println(setno + " " + gameno);
            }
        }

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    static int[] wins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        wins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        for (int i = 0; i < seq; i++) {
            wins[i] = st.nextToken().charAt(0) == '1' ? 1 : -1;
            if (wins[i] == 1) {
                p++;
            } else {
                g++;
            }
        }

        if (p == g) {
            System.out.println(0);
        } else {
            TreeSet<String> set = new TreeSet<String>();

            int max = p > g ? p : g;
            set.add("1 " + max);
            set.add(max + " 1");

            for (int i = 2; i <= Math.sqrt(max); i++) {
                if (max % i == 0) {
                    int other = max / i;

                    if (other % 2 == 1 || valid(i, other)) {
                        set.add(i + " " + other);
                    }

                    if (i % 2 == 1 || valid(other, i)) {
                        set.add(other + " " + i);
                    }
                }
            }

            System.out.println(set.size());
            for (String s : set) {
                System.out.println(s);
            }

        }

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    static int[] wins;
    static int[] pwins;
    static int[] gwins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        pwins = new int[seq];
        gwins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        char ch = '0';
        for (int i = 0; i < seq; i++) {
            ch = st.nextToken().charAt(0);
            if (ch == '1') {
                p++;
            } else {
                g++;
            }
            pwins[i] = p;
            gwins[i] = g;
        }

        //if (p == g || (p > g && ch == '2') || (g>p && ch == '1')) {
//            System.out.println(0);
  //      } else {
            int max = p > g ? p : g;

            ArrayList<String> solutions = new ArrayList<String>();
            //solutions.add("1 " + max);

            int setp = 0, setg = 0, minusp = 0, minusg = 0;
            for (int games = max; games >=1; games--) {
                int index = games - 1;
                setp = setg = minusp = minusg = 0;
                boolean valid = true;
                while (true) {
                    if (index >= seq) {
                        valid = false;
                        break;
                    }
                    if (pwins[index]-minusp == games || gwins[index]-minusg== games) {
                        if (pwins[index]-minusp == games) {
                            setp++;
                        } else {
                            setg++;
                        }
                        minusp = pwins[index];
                        minusg = gwins[index];
                        if (index == seq - 1) {
                            valid = (setp > setg && ch == '1') || (setg > setp && ch == '2');
                            break;
                        } else {
                            index += games;
                        }
                    } else {
                        index += games - Math.max(pwins[index]-minusp, gwins[index]-minusg);
                    }
                }

                if (valid) {
                    solutions.add(Math.max(setp, setg) + " " + games);
                }
            }
            //solutions.add(max + " 1");

            int sols = solutions.size();
            System.out.println(sols);
            for (String s : solutions) {
                System.out.println(s);
            }

            /*
            TreeSet<String> set = new TreeSet<String>();

            set.add("1 " + max);
            set.add(max + " 1");

            for (int i = 2; i <= Math.sqrt(max); i++) {
                if (max % i == 0) {
                    int other = max / i;

                    if (other % 2 == 1 || valid(i, other)) {
                        set.add(i + " " + other);
                    }

                    if (i % 2 == 1 || valid(other, i)) {
                        set.add(other + " " + i);
                    }
                }
            }

            System.out.println(set.size());
            for (String s : set) {
                System.out.println(s);
            }*/

        //}

    }
}


import java.io.BufferedReader;
import java.io.FileReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class Main {

    static int[] wins;
    static int[] pwins;
    static int[] gwins;

    static boolean valid(int sets, int games) {
        for (int set = 0; set < sets; set++) {
            int sum = 0;
            int offset = set * games;

            for (int game = 0; game < games; game++) {
                sum += wins[offset + game];
            }

            if (sum == 0) {
                return false;
            }
        }
        return true;
    }

    public static void main(String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        //BufferedReader br = new BufferedReader(new FileReader("data"));

        int seq = Integer.parseInt(br.readLine());
        pwins = new int[seq];
        gwins = new int[seq];

        StringTokenizer st = new StringTokenizer(br.readLine());

        int p = 0, g = 0;
        char ch = '0';
        for (int i = 0; i < seq; i++) {
            ch = st.nextToken().charAt(0);
            if (ch == '1') {
                p++;
            } else {
                g++;
            }
            pwins[i] = p;
            gwins[i] = g;
        }

        //if (p == g || (p > g && ch == '2') || (g>p && ch == '1')) {
//            System.out.println(0);
  //      } else {
            int max = p > g ? p : g;

            ArrayList<String> solutions = new ArrayList<String>();
            //solutions.add("1 " + max);

            int setp = 0, setg = 0, minusp = 0, minusg = 0;
            for (int games = max; games >=1; games--) {
                int index = games - 1;
                setp = setg = minusp = minusg = 0;
                boolean valid = true;
                while (true) {
                    if (index >= seq) {
                        valid = false;
                        break;
                    }
                    if (pwins[index]-minusp == games || gwins[index]-minusg== games) {
                        if (pwins[index]-minusp == games) {
                            setp++;
                        } else {
                            setg++;
                        }
                        minusp = pwins[index];
                        minusg = gwins[index];
                        if (index == seq - 1) {
                            valid = setp != setg;
                            break;
                        } else {
                            index += games;
                        }
                    } else {
                        index += games - Math.max(pwins[index]-minusp, gwins[index]-minusg);
                    }
                }

                if (valid) {
                    solutions.add(Math.max(setp, setg) + " " + games);
                }
            }
            //solutions.add(max + " 1");

            int sols = solutions.size();
            System.out.println(sols);
            for (String s : solutions) {
                System.out.println(s);
            }

            /*
            TreeSet<String> set = new TreeSet<String>();

            set.add("1 " + max);
            set.add(max + " 1");

            for (int i = 2; i <= Math.sqrt(max); i++) {
                if (max % i == 0) {
                    int other = max / i;

                    if (other % 2 == 1 || valid(i, other)) {
                        set.add(i + " " + other);
                    }

                    if (i % 2 == 1 || valid(other, i)) {
                        set.add(other + " " + i);
                    }
                }
            }

            System.out.println(set.size());
            for (String s : set) {
                System.out.println(s);
            }*/

        //}

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author aryssoncf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            try {
                int n = in.readInt();
                int[] a = in.readIntArray(n);
                MiscUtils.decreaseByOne(a);
                int[][] counter = new int[2][n];
                for (int i = 0; i < 2; i++) {
                    for (int j = 0; j < n; j++) {
                        counter[i][j] = a[j] == i ? 1 : 0;
                        if (j > 0) {
                            counter[i][j] += counter[i][j - 1];
                        }
                    }
                }
                List<IntIntPair> res = new ArrayList<>();
                for (int t = n; t > 0; t--) {
                    int s = f(counter, t);
                    if (s != -1) {
                        res.add(IntIntPair.makePair(s, t));
                    }
                }
                Collections.sort(res);
                out.printLine(res.size());
                out.printPairList(res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        int f(int[][] counter, int t) {
            int[] score = new int[2];
            int n = counter[0].length, pos = 0, chosen = -1;
            while (pos < n) {
                int end = n;
                chosen = -1;
                for (int type = 0; type < 2; type++) {
                    int finalType = type;
                    int finalPos = pos;
                    LongFilter filter = i -> {
                        int prev = finalPos == 0 ? 0 : counter[finalType][finalPos - 1];
                        return i == n || counter[finalType][(int) i] >= prev + t;
                    };
                    int aux = (int) MiscUtils.binarySearch(0, n, filter);
                    if (aux < end) {
                        end = aux;
                        chosen = type;
                    }
                }
                if (chosen == -1) {
                    return -1;
                }
                pos = end + 1;
                score[chosen]++;
            }
            if (score[0] == score[1]) {
                return -1;
            }
            int best = score[0] > score[1] ? 0 : 1;
            return chosen == best ? score[best] : -1;
        }

    }

    static class MiscUtils {
        public static long binarySearch(long from, long to, LongFilter function) {
            while (from < to) {
                long argument = from + ((to - from) >> 1);
                if (function.accept(argument)) {
                    to = argument;
                } else {
                    from = argument + 1;
                }
            }
            return from;
        }

        public static void decreaseByOne(int[]... arrays) {
            for (int[] array : arrays) {
                for (int i = 0; i < array.length; i++) {
                    array[i]--;
                }
            }
        }

    }

    static class IntIntPair implements Comparable<IntIntPair> {
        public final int first;
        public final int second;

        public static IntIntPair makePair(int first, int second) {
            return new IntIntPair(first, second);
        }

        public IntIntPair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            IntIntPair pair = (IntIntPair) o;

            return first == pair.first && second == pair.second;
        }

        public int hashCode() {
            int result = first;
            result = 31 * result + second;
            return result;
        }

        public String toString() {
            return "(" + first + "," + second + ")";
        }

        public int compareTo(IntIntPair o) {
            int value = Integer.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }

    }

    static interface LongFilter {
        public boolean accept(long value);

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

        public void printPairList(List<IntIntPair> answer) {
            for (IntIntPair pair : answer) {
                printLine(pair.first, pair.second);
            }
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public 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++];
        }

        public int readInt() {
            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;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.util.Collections;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author aryssoncf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            try {
                int n = in.readInt();
                int[] a = in.readIntArray(n);
                MiscUtils.decreaseByOne(a);
                int[][] counter = new int[2][n];
                for (int i = 0; i < 2; i++) {
                    for (int j = 0; j < n; j++) {
                        counter[i][j] = a[j] == i ? 1 : 0;
                        if (j > 0) {
                            counter[i][j] += counter[i][j - 1];
                        }
                    }
                }
                List<IntIntPair> res = new ArrayList<>();
                for (int t = n; t > 0; t--) {
                    int s = f(counter, t);
                    if (s != -1) {
                        res.add(IntIntPair.makePair(s, t));
                    }
                }
                Collections.sort(res);
                out.printLine(res.size());
                out.printPairList(res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        int f(int[][] counter, int t) {
            int[] score = new int[2];
            int n = counter[0].length, pos = 0;
            while (pos < n) {
                int end = n, chosen = -1;
                for (int type = 0; type < 2; type++) {
                    int finalType = type;
                    int finalPos = pos;
                    LongFilter filter = i -> {
                        int prev = finalPos == 0 ? 0 : counter[finalType][finalPos - 1];
                        return i == n || counter[finalType][(int) i] >= prev + t;
                    };
                    int aux = (int) MiscUtils.binarySearch(0, n, filter);
                    if (aux < end) {
                        end = aux;
                        chosen = type;
                    }
                }
                if (chosen == -1) {
                    return -1;
                }
                pos = end + 1;
                score[chosen]++;
            }
            if (score[0] < score[1]) {
                int tmp = score[0];
                score[0] = score[1];
                score[1] = tmp;
            }
            return score[0] == score[1] ? -1 : score[0];
        }

    }

    static class MiscUtils {
        public static long binarySearch(long from, long to, LongFilter function) {
            while (from < to) {
                long argument = from + ((to - from) >> 1);
                if (function.accept(argument)) {
                    to = argument;
                } else {
                    from = argument + 1;
                }
            }
            return from;
        }

        public static void decreaseByOne(int[]... arrays) {
            for (int[] array : arrays) {
                for (int i = 0; i < array.length; i++) {
                    array[i]--;
                }
            }
        }

    }

    static interface LongFilter {
        public boolean accept(long value);

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

        public void printPairList(List<IntIntPair> answer) {
            for (IntIntPair pair : answer) {
                printLine(pair.first, pair.second);
            }
        }

    }

    static class IntIntPair implements Comparable<IntIntPair> {
        public final int first;
        public final int second;

        public static IntIntPair makePair(int first, int second) {
            return new IntIntPair(first, second);
        }

        public IntIntPair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            IntIntPair pair = (IntIntPair) o;

            return first == pair.first && second == pair.second;
        }

        public int hashCode() {
            int result = first;
            result = 31 * result + second;
            return result;
        }

        public String toString() {
            return "(" + first + "," + second + ")";
        }

        public int compareTo(IntIntPair o) {
            int value = Integer.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public 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++];
        }

        public int readInt() {
            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;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author aryssoncf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            try {
                int n = in.readInt();
                int[] a = in.readIntArray(n);
                MiscUtils.decreaseByOne(a);
                int[][] counter = new int[2][n];
                for (int i = 0; i < 2; i++) {
                    for (int j = 0; j < n; j++) {
                        counter[i][j] = a[j] == i ? 1 : 0;
                        if (j > 0) {
                            counter[i][j] += counter[i][j - 1];
                        }
                    }
                }
                List<IntIntPair> res = new ArrayList<>();
                for (int t = n; t > 0; t--) {
                    int s = f(counter, t);
                    if (s != -1) {
                        res.add(IntIntPair.makePair(s, t));
                    }
                }
                out.printLine(res.size());
                out.printPairList(res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        int f(int[][] counter, int t) {
            int[] score = new int[2];
            int n = counter[0].length, pos = 0;
            while (pos < n) {
                int end = n, chosen = -1;
                for (int type = 0; type < 2; type++) {
                    int finalType = type;
                    int finalPos = pos;
                    LongFilter filter = i -> {
                        int prev = finalPos == 0 ? 0 : counter[finalType][finalPos - 1];
                        return i == n || counter[finalType][(int) i] >= prev + t;
                    };
                    int aux = (int) MiscUtils.binarySearch(0, n, filter);
                    if (aux < end) {
                        end = aux;
                        chosen = type;
                    }
                }
                if (chosen == -1) {
                    return -1;
                }
                pos = end + 1;
                score[chosen]++;
            }
            if (score[0] < score[1]) {
                int tmp = score[0];
                score[0] = score[1];
                score[1] = tmp;
            }
            return score[0] == score[1] ? -1 : score[0];
        }

    }

    static class MiscUtils {
        public static long binarySearch(long from, long to, LongFilter function) {
            while (from < to) {
                long argument = from + ((to - from) >> 1);
                if (function.accept(argument)) {
                    to = argument;
                } else {
                    from = argument + 1;
                }
            }
            return from;
        }

        public static void decreaseByOne(int[]... arrays) {
            for (int[] array : arrays) {
                for (int i = 0; i < array.length; i++) {
                    array[i]--;
                }
            }
        }

    }

    static interface LongFilter {
        public boolean accept(long value);

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

        public void printPairList(List<IntIntPair> answer) {
            for (IntIntPair pair : answer) {
                printLine(pair.first, pair.second);
            }
        }

    }

    static class IntIntPair implements Comparable<IntIntPair> {
        public final int first;
        public final int second;

        public static IntIntPair makePair(int first, int second) {
            return new IntIntPair(first, second);
        }

        public IntIntPair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            IntIntPair pair = (IntIntPair) o;

            return first == pair.first && second == pair.second;
        }

        public int hashCode() {
            int result = first;
            result = 31 * result + second;
            return result;
        }

        public String toString() {
            return "(" + first + "," + second + ")";
        }

        public int compareTo(IntIntPair o) {
            int value = Integer.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public 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++];
        }

        public int readInt() {
            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;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author aryssoncf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            try {
                int n = in.readInt();
                int[] a = in.readIntArray(n);
                MiscUtils.decreaseByOne(a);
                int[][] counter = new int[2][n];
                for (int i = 0; i < 2; i++) {
                    for (int j = 0; j < n; j++) {
                        counter[i][j] = a[j] == i ? 1 : 0;
                        if (j > 0) {
                            counter[i][j] += counter[i][j - 1];
                        }
                    }
                }
                List<IntIntPair> res = new ArrayList<>();
                for (int t = n; t > 0; t--) {
                    int s = f(counter, t);
                    if (s != -1) {
                        res.add(IntIntPair.makePair(s, t));
                    }
                }
                out.printLine(res.size());
                out.printPairList(res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        int f(int[][] counter, int t) {
            int[] score = new int[2];
            int n = counter[0].length, pos = 0, chosen = -1;
            while (pos < n) {
                int end = n;
                chosen = -1;
                for (int type = 0; type < 2; type++) {
                    int finalType = type;
                    int finalPos = pos;
                    LongFilter filter = i -> {
                        int prev = finalPos == 0 ? 0 : counter[finalType][finalPos - 1];
                        return i == n || counter[finalType][(int) i] >= prev + t;
                    };
                    int aux = (int) MiscUtils.binarySearch(0, n, filter);
                    if (aux < end) {
                        end = aux;
                        chosen = type;
                    }
                }
                if (chosen == -1) {
                    return -1;
                }
                pos = end + 1;
                score[chosen]++;
            }
            if (score[0] == score[1]) {
                return -1;
            }
            int best = score[0] > score[1] ? 0 : 1;
            return chosen == best ? score[best] : -1;
        }

    }

    static class MiscUtils {
        public static long binarySearch(long from, long to, LongFilter function) {
            while (from < to) {
                long argument = from + ((to - from) >> 1);
                if (function.accept(argument)) {
                    to = argument;
                } else {
                    from = argument + 1;
                }
            }
            return from;
        }

        public static void decreaseByOne(int[]... arrays) {
            for (int[] array : arrays) {
                for (int i = 0; i < array.length; i++) {
                    array[i]--;
                }
            }
        }

    }

    static class IntIntPair implements Comparable<IntIntPair> {
        public final int first;
        public final int second;

        public static IntIntPair makePair(int first, int second) {
            return new IntIntPair(first, second);
        }

        public IntIntPair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            IntIntPair pair = (IntIntPair) o;

            return first == pair.first && second == pair.second;
        }

        public int hashCode() {
            int result = first;
            result = 31 * result + second;
            return result;
        }

        public String toString() {
            return "(" + first + "," + second + ")";
        }

        public int compareTo(IntIntPair o) {
            int value = Integer.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }

    }

    static interface LongFilter {
        public boolean accept(long value);

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

        public void printPairList(List<IntIntPair> answer) {
            for (IntIntPair pair : answer) {
                printLine(pair.first, pair.second);
            }
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public 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++];
        }

        public int readInt() {
            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;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 *
 * @author aryssoncf
 */
public class Main {
    public static void main(String[] args) {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        OutputWriter out = new OutputWriter(outputStream);
        TaskD solver = new TaskD();
        solver.solve(1, in, out);
        out.close();
    }

    static class TaskD {
        public void solve(int testNumber, InputReader in, OutputWriter out) {
            try {
                int n = in.readInt();
                int[] a = in.readIntArray(n);
                MiscUtils.decreaseByOne(a);
                int[][] counter = new int[2][n];
                for (int i = 0; i < 2; i++) {
                    for (int j = 0; j < n; j++) {
                        counter[i][j] = a[j] == i ? 1 : 0;
                        if (j > 0) {
                            counter[i][j] += counter[i][j - 1];
                        }
                    }
                }
                List<IntIntPair> res = new ArrayList<>();
                for (int t = n; t > 0; t--) {
                    int s = f(counter, t);
                    if (s != -1) {
                        res.add(IntIntPair.makePair(s, t));
                    }
                }
                out.printLine(res.size());
                out.printPairList(res);
            } catch (Exception e) {
                e.printStackTrace();
            }
        }

        int f(int[][] counter, int t) {
            int[] score = new int[2];
            int n = counter[0].length, pos = 0;
            while (pos < n) {
                int end = n, chosen = -1;
                for (int type = 0; type < 2; type++) {
                    int finalType = type;
                    int finalPos = pos;
                    LongFilter filter = i -> {
                        int prev = finalPos == 0 ? 0 : counter[finalType][finalPos - 1];
                        return i == n || counter[finalType][(int) i] >= prev + t;
                    };
                    int aux = (int) MiscUtils.binarySearch(0, n, filter);
                    if (aux < end) {
                        end = aux;
                        chosen = type;
                    }
                }
                if (chosen == -1) {
                    return -1;
                }
                pos = end + 1;
                score[chosen]++;
            }
            return score[0] == score[1] ? -1 : Math.max(score[0], score[1]);
        }

    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private InputReader.SpaceCharFilter filter;

        public InputReader(InputStream stream) {
            this.stream = stream;
        }

        public int[] readIntArray(int size) {
            int[] array = new int[size];
            for (int i = 0; i < size; i++) {
                array[i] = readInt();
            }
            return array;
        }

        public 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++];
        }

        public int readInt() {
            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;
        }

        public boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

        public static boolean isWhitespace(int c) {
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        public interface SpaceCharFilter {
            boolean isSpaceChar(int ch);

        }

    }

    static class IntIntPair implements Comparable<IntIntPair> {
        public final int first;
        public final int second;

        public static IntIntPair makePair(int first, int second) {
            return new IntIntPair(first, second);
        }

        public IntIntPair(int first, int second) {
            this.first = first;
            this.second = second;
        }

        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            IntIntPair pair = (IntIntPair) o;

            return first == pair.first && second == pair.second;
        }

        public int hashCode() {
            int result = first;
            result = 31 * result + second;
            return result;
        }

        public String toString() {
            return "(" + first + "," + second + ")";
        }

        public int compareTo(IntIntPair o) {
            int value = Integer.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }

    }

    static interface LongFilter {
        public boolean accept(long value);

    }

    static class MiscUtils {
        public static long binarySearch(long from, long to, LongFilter function) {
            while (from < to) {
                long argument = from + ((to - from) >> 1);
                if (function.accept(argument)) {
                    to = argument;
                } else {
                    from = argument + 1;
                }
            }
            return from;
        }

        public static void decreaseByOne(int[]... arrays) {
            for (int[] array : arrays) {
                for (int i = 0; i < array.length; i++) {
                    array[i]--;
                }
            }
        }

    }

    static class OutputWriter {
        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
        }

        public OutputWriter(Writer writer) {
            this.writer = new PrintWriter(writer);
        }

        public void print(Object... objects) {
            for (int i = 0; i < objects.length; i++) {
                if (i != 0) {
                    writer.print(' ');
                }
                writer.print(objects[i]);
            }
        }

        public void printLine(Object... objects) {
            print(objects);
            writer.println();
        }

        public void close() {
            writer.close();
        }

        public void printLine(int i) {
            writer.println(i);
        }

        public void printPairList(List<IntIntPair> answer) {
            for (IntIntPair pair : answer) {
                printLine(pair.first, pair.second);
            }
        }

    }
}


import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Iterator;

public class Main {

//removing columns
//  public static char[][] readEntrance() throws IOException {
//      BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
//      String line = br.readLine();
//      String[] numbers = line.split(" ");
//      int n = Integer.parseInt(numbers[0]);
//      int m = Integer.parseInt(numbers[1]);
//
//      char[][] A = new char[n][m];
//
//      for (int i = 0; i < n; i++) {
//          line = br.readLine();
//          for (int j = 0; j < m; j++) {
//              A[i][j] = line.charAt(j);
//          }
//      }
//      return A;
//  }
//
//  public static void main (String[] args) throws IOException {
//      char[][] A = readEntrance();
//      int toRemove = 0;
//      if (A.length < 2) {
//          System.out.println(0);
//          return;
//      }
//      if (A[0].length == 0) {
//          System.out.println(0);
//          return;
//      }
//      boolean[] wasSame = new boolean[A.length];
//
//      for (int i = 0; i < wasSame.length; i++) {
//          wasSame[i] = true;
//      }
//
//      for (int j = 0; j < A[0].length; j++) {
//          int i = 1; boolean good = true;
//          boolean[] isSame = new boolean[A.length];
//          while (i < A.length && good) {
//              if (wasSame[i]) {
//                  if (A[i][j] < A[i-1][j]) {
//                      toRemove++;
//                      good = false;
//                  } else if (A[i][j] == A[i-1][j]) {
//                      isSame[i] = true;
//                  }
//              }
//              i++;
//          }
//          for (int k = 0; k < A.length; k++) {
//              if (good) {
//                  wasSame[k] = isSame[k];
//              }
//          }
//      }
//      System.out.println(toRemove);
//  }

    public static void main (String[] args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
        String line = br.readLine();
        int n = Integer.parseInt(line);

        int[] A = new int[n];
        line = br.readLine();
        String[] serves = line.split(" ");
        ArrayList<ArrayList<Integer>> advSc = new ArrayList<ArrayList<Integer>>(2);
        advSc.add(new ArrayList<Integer>());
        advSc.get(0).add(0);
        advSc.add(new ArrayList<Integer>());
        advSc.get(1).add(0);
        int[] scores = new int[2];

        for (int j = 0; j < n; j++) {
            int tmp = Integer.parseInt(serves[j]);
            A[j] = tmp;
            scores[tmp-1]++;
            advSc.get(tmp-1).add(scores[2-tmp]);
        }

        ArrayList<Integer> sSet = new ArrayList<Integer>();
        ArrayList<Integer> tSet = new ArrayList<Integer>();
        int counter = 0;

        for (int t = Math.max(scores[0], scores[1]); t > 0; t--) {
            int[] tmpSets = new int[2];
            int better = 0;
            int[] index = new int[2];
            int act = (scores[0] > scores[1]) ? 0 : 1;
            while (advSc.get(act).size() > index[act]+t) {
//              System.out.println("index " + index[act] + " value " + advSc.get(act).get(index[act]));
                better = (advSc.get(act).get(index[act]+t) - index[1-act] >= t) ? 1-act : act;
                index[better] += t;
                index[1-better] = advSc.get(better).get(index[better]);
                tmpSets[better]++;
                act = (index[act]+t < advSc.get(act).size()) ? act : 1-act;
//              System.out.println("sets: " + tmpSets[0] + ", " + tmpSets[1]);
            }
//          System.out.println("after while");
//          System.out.println("t: " + t + " index[0]: " + index[0] + " index[1]: " + index[1] + " sets: " + tmpSets[longer]);
            if (index[better] == advSc.get(better).size()-1 && index[1-better] == advSc.get(1-better).size()-1
                    && tmpSets[better] > tmpSets[1-better]) {
//              System.out.println("here");
                counter++;
                tSet.add(t);
                sSet.add(Math.max(tmpSets[0], tmpSets[1]));
            }
        }

        System.out.println(counter);
        Iterator<Integer> it1 = sSet.iterator();
        Iterator<Integer> it2 = tSet.iterator();

        int lastS = 0;
        ArrayList<Integer> sLast = new ArrayList<Integer>();
        ArrayList<Integer> tLast = new ArrayList<Integer>();

        if (it1.hasNext()) {
            lastS = it1.next();
            sLast.add(lastS);
            tLast.add(it2.next());
        }

        while (it1.hasNext()) {
            int a = it1.next();
            if (a != lastS) {
                for (int i = sLast.size()-1; i >= 0; i--) {
                    System.out.println(sLast.get(i) + " " + tLast.get(i));
                }
                sLast.clear();
                tLast.clear();
            }
            sLast.add(a);
            tLast.add(it2.next());
            lastS = a;
        }

        for (int i = sLast.size()-1; i >= 0; i--) {
            System.out.println(sLast.get(i) + " " + tLast.get(i));
            sLast.remove(i);
            tLast.remove(i);
        }
    }
}


import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class CF283D1 {

    private static class Result implements Comparable<Result> {
        Integer s;
        Integer t;

        public Result(final Integer s, final Integer t) {
            this.s = s;
            this.t = t;
        }

        @Override
        public int compareTo(final Result o) {

            if (s.compareTo(o.s) == 0) {
                return t.compareTo(o.t);
            }

            return s.compareTo(o.s);
        }
    }

    public static void main(final String[] args) {
        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        List<Integer> posOnesList = new LinkedList<Integer>();
        List<Integer> posTwosList = new LinkedList<Integer>();
        int[] meetOnes = new int[n];
        int[] meetTwos = new int[n];
        for (int i = 0; i < n; i++) {
            int curr = sc.nextInt();
            meetOnes[i] = i > 0 ? meetOnes[i - 1] : 0;
            meetTwos[i] = i > 0 ? meetTwos[i - 1] : 0;
            if (curr == 1) {
                posOnesList.add(i);
                meetOnes[i]++;
            } else {
                posTwosList.add(i);
                meetTwos[i]++;
            }
        }

        Integer[] posOnes = posOnesList.toArray(new Integer[0]);
        Integer[] posTwos = posTwosList.toArray(new Integer[0]);

        List<Result> results = new LinkedList<Result>();

        for (int t = 1; t <= n; t++) {

            int currPos = -1;
            int onesWins = 0;
            int twosWins = 0;
            while (currPos < n) {
                int metOnes = currPos >= 0 ? meetOnes[currPos] : 0;
                int metTwos = currPos >= 0 ? meetTwos[currPos] : 0;

                int i1 = 3 * n;
                if (metOnes + t - 1 < posOnes.length) {
                    i1 = posOnes[metOnes + t - 1];
                }

                int i2 = 3 * n;
                if (metTwos + t - 1 < posTwos.length) {
                    i2 = posTwos[metTwos + t - 1];
                }

                if (i1 < i2) {
                    currPos = i1;
                    onesWins++;
                } else if (i2 < i1) {
                    currPos = i2;
                    twosWins++;
                } else {
                    break;
                }

            }

            if (currPos == n - 1 && onesWins != twosWins) {
                results.add(new Result(Math.max(onesWins, twosWins), t));
            }

        }

        Result[] res = results.toArray(new Result[0]);
        Arrays.sort(res);

        StringBuilder sb = new StringBuilder();
        for (Result r : res) {
            if (sb.length() > 0) {
                sb.append("\n");
            }

            sb.append(r.s + " " + r.t);
        }

        System.out.println(res.length);
        if (res.length > 0) {
            System.out.println(sb.toString());
        }

    }
}


import java.util.Arrays;
import java.util.LinkedList;
import java.util.List;
import java.util.Scanner;

public class CF283D {

    private static class Node {
        public static final Node ZERO = new Node(0, 0);

        int ones = 0;
        int twos = 0;

        public Node(final int ones, final int twos) {
            this.ones = ones;
            this.twos = twos;
        }

        public Node sum(final Node n) {
            return new Node(ones + n.ones, twos + n.twos);
        }

    }

    private static class Result implements Comparable<Result> {
        Integer s;
        Integer t;

        public Result(final Integer s, final Integer t) {
            this.s = s;
            this.t = t;
        }

        @Override
        public int compareTo(final Result o) {

            if (s.compareTo(o.s) == 0) {
                return t.compareTo(o.t);
            }

            return s.compareTo(o.s);
        }
    }

    public static void main(final String[] args) {

        Scanner sc = new Scanner(System.in);

        int n = sc.nextInt();
        int[] s = new int[n];
        int ones = 0;
        int twos = 0;
        for (int i = 0; i < s.length; i++) {
            s[i] = sc.nextInt();
            if (s[i] == 1) {
                ones++;
            } else {
                twos++;
            }
        }

        List<Result> result = new LinkedList<Result>();

        if (ones != twos) {
            result.add(new Result(Math.max(ones, twos), 1));
        }

        Node[] segTree = new Node[4 * n];

        build(segTree, s, 1, 0, n - 1);

        for (int t = 2; t <= n; t++) {
            int curr = 0;
            ones = 0;
            twos = 0;

            while (curr < n) {
                int start = curr + t - 1;
                int end = start + t - 1;

                boolean found = false;
                int mid = (start + end) / 2;
                while (start <= end) {
                    mid = (start + end) / 2;
                    if (mid < n) {
                        Node status = sum(segTree, 1, 0, n - 1, curr, mid);

                        if (status.ones == t && status.twos < t) {
                            found = true;
                            ones++;
                            break;
                        } else if (status.twos == t && status.ones < t) {
                            found = true;
                            twos++;
                            break;
                        } else if (status.ones > t || status.twos > t) {
                            end = mid - 1;
                        } else {
                            start = mid + 1;
                        }
                    } else {
                        end = mid - 1;
                    }
                }

                if (!found) {
                    break;
                }

                curr = mid + 1;

            }

            if (curr == n && ones != twos) {
                result.add(new Result(Math.max(ones, twos), t));
            }
        }

        Result[] res = result.toArray(new Result[0]);
        Arrays.sort(res);

        StringBuilder sb = new StringBuilder();
        for (Result r : res) {
            if (sb.length() > 0) {
                sb.append("\n");
            }

            sb.append(r.s + " " + r.t);
        }

        System.out.println(res.length);
        if (res.length > 0) {
            System.out.println(sb.toString());
        }

    }

    static void build(final Node[] tree, final int[] a, final int v, final int tl, final int tr) {
        if (tl == tr) {
            tree[v] = (a[tl] == 1 ? new Node(1, 0) : new Node(0, 1));
        } else {
            int tm = (tl + tr) / 2;
            build(tree, a, v * 2, tl, tm);
            build(tree, a, v * 2 + 1, tm + 1, tr);
            tree[v] = tree[v * 2].sum(tree[v * 2 + 1]);
        }
    }

    static Node sum(final Node[] tree, final int v, final int tl, final int tr, final int l, final int r) {
        if (l > r) {
            return Node.ZERO;
        }

        if (l == tl && r == tr) {
            return tree[v];
        }

        int tm = (tl + tr) / 2;
        return sum(tree, v * 2, tl, tm, l, Math.min(r, tm)).sum(sum(tree, v * 2 + 1, tm + 1, tr, Math.max(l, tm + 1),
                    r));

    }
}