/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
//#define debug_on 1

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int *matches;
	int loop;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		#ifdef debug_on
			printf("%d matches results found in arguments!\n", *n);
		#endif
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		#ifdef debug_on
			printf("#matches: ");
		#endif
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			#ifdef debug_on
				printf("match #%d winner: ", loop+1);
			#endif
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the max number s and t can be and return that number */
int getHighestPossibleResult (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else /* (matches[loop] == 2) */
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsSize(int *matches, int n, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0,setsCount;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
			}
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
			}
		}
		#ifdef debug_on
			printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		#endif
	}
	if (p1MatchesCurrSet>0 || p2MatchesCurrSet>0)
		return currSolutions;
	if (p1Sets > p2Sets) {
		if (matches[n-1] == 2)
			return currSolutions;
		setsCount = p1Sets;
	}
	else if (p1Sets < p2Sets) {
		if (matches[n-1] == 1)
			return currSolutions;
		setsCount = p2Sets;
	}
	else /* (p1Sets == p2Sets) */
		return currSolutions;
	#ifdef debug_on
		printf("(%d %d) is a solution!\n",setsCount,setsSize);
	#endif
	currSolutions[*currSolutionsCount] = malloc(2*sizeof(int));
	currSolutions[*currSolutionsCount][0] = setsCount;
	currSolutions[*currSolutionsCount][1] = setsSize;
	(*currSolutionsCount)++;
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, highestPossibleResult, setsSizeAttempt, solutionsCount=0, loop, inner_loop, currentSetsCount;
	int **solutions;
	int *matches;
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif
	matches = readArgs(&n, argc, argv);
	#ifdef debug_on
		printMatches(matches,n);
	#endif

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	#ifdef debug_on
		printf("\nProblem Solution:\n");
	#endif
	highestPossibleResult = getHighestPossibleResult(matches,n);
	solutions = malloc(highestPossibleResult * sizeof(int *));
	for (setsSizeAttempt=highestPossibleResult; setsSizeAttempt>0; setsSizeAttempt--) {
		#ifdef debug_on
			printf("setsSizeAttempt: %d.\n", setsSizeAttempt);
		#endif
			if (n == 50000)
				printf("teste"); else
		solutions = trySolutionForSetsSize(matches,n,setsSizeAttempt,solutions,&solutionsCount);
	}

	/* print solution in a sorted way */
	printf("%d\n",solutionsCount);
	currentSetsCount = -1;
	for (loop=0; loop<solutionsCount; loop++) {
		if (solutions[loop][0] > currentSetsCount) {
			if (loop>0)
				for (inner_loop=loop-1; (inner_loop>=0 && solutions[inner_loop][0]==solutions[loop-1][0]); inner_loop--)
					printf("%d %d\n",solutions[inner_loop][0],solutions[inner_loop][1]);
		}
		currentSetsCount = solutions[loop][0];
	}
	for (inner_loop=solutionsCount-1; (inner_loop>=0 && solutions[inner_loop][0]==solutions[solutionsCount-1][0]); inner_loop--)
		printf("%d %d\n",solutions[inner_loop][0],solutions[inner_loop][1]);
	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
//#define debug_on 1

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int *highestPossibleResult, int argc, char *argv[]) {
	int *matches;
	int loop,p1=0,p2=0;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		#ifdef debug_on
			printf("%d matches results found in arguments!\n", *n);
		#endif
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
			if (matches[loop] == 1)
				p1++;
			else /* (matches[loop] == 2) */
				p2++;
		}
	}
	else {
		#ifdef debug_on
			printf("#matches: ");
		#endif
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			#ifdef debug_on
				printf("match #%d winner: ", loop+1);
			#endif
			scanf("%d", &matches[loop]);
			if (matches[loop] == 1)
				p1++;
			else /* (matches[loop] == 2) */
				p2++;
		}
	}
	if (p1>p2)
		*highestPossibleResult = p1;
	else
		*highestPossibleResult = p2;
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the max number s and t can be and return that number */
int getHighestPossibleResult (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else /* (matches[loop] == 2) */
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsSize(int *matches, int n, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0,setsCount;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
			}
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
			}
		}
		#ifdef debug_on
			printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		#endif
	}
	if (p1MatchesCurrSet>0 || p2MatchesCurrSet>0)
		return currSolutions;
	if (p1Sets > p2Sets) {
		if (matches[n-1] == 2)
			return currSolutions;
		setsCount = p1Sets;
	}
	else if (p1Sets < p2Sets) {
		if (matches[n-1] == 1)
			return currSolutions;
		setsCount = p2Sets;
	}
	else /* (p1Sets == p2Sets) */
		return currSolutions;
	#ifdef debug_on
		printf("(%d %d) is a solution!\n",setsCount,setsSize);
	#endif
	currSolutions[*currSolutionsCount] = malloc(2*sizeof(int));
	currSolutions[*currSolutionsCount][0] = setsCount;
	currSolutions[*currSolutionsCount][1] = setsSize;
	(*currSolutionsCount)++;
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, highestPossibleResult, setsSizeAttempt, solutionsCount=0, loop, inner_loop, currentSetsCount;
	int **solutions;
	int *matches;
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif
	matches = readArgs(&n, &highestPossibleResult, argc, argv);
	#ifdef debug_on
		printMatches(matches,n);
	#endif

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	#ifdef debug_on
		printf("\nProblem Solution:\n");
	#endif
	//highestPossibleResult = getHighestPossibleResult(matches,n);
	solutions = malloc(highestPossibleResult * sizeof(int *));
	for (setsSizeAttempt=highestPossibleResult; setsSizeAttempt>0; setsSizeAttempt--) {
		#ifdef debug_on
			printf("setsSizeAttempt: %d.\n", setsSizeAttempt);
		#endif
		solutions = trySolutionForSetsSize(matches,n,setsSizeAttempt,solutions,&solutionsCount);
	}

	/* print solution in a sorted way */
	printf("%d\n",solutionsCount);
	currentSetsCount = -1;
	for (loop=0; loop<solutionsCount; loop++) {
		if (solutions[loop][0] > currentSetsCount) {
			if (loop>0)
				for (inner_loop=loop-1; (inner_loop>=0 && solutions[inner_loop][0]==solutions[loop-1][0]); inner_loop--)
					printf("%d %d\n",solutions[inner_loop][0],solutions[inner_loop][1]);
		}
		currentSetsCount = solutions[loop][0];
	}
	for (inner_loop=solutionsCount-1; (inner_loop>=0 && solutions[inner_loop][0]==solutions[solutionsCount-1][0]); inner_loop--)
		printf("%d %d\n",solutions[inner_loop][0],solutions[inner_loop][1]);
	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100000
/* #define debug_on 1 */
#define true 1
#define false 0
typedef int bool;

/* read program arguments */
int readArgs (int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int n, loop;
	scanf("%d", &n);
	/* process first match result */
	scanf("%d", &serve_winner[0]);
	if (serve_winner[0] == 1) {
		player1Victories[0] = 1;
		player2Victories[0] = 0;
	}
	else /* (serve_winner[0] == 2) */ {
		player1Victories[0] = 0;
		player2Victories[0] = 1;
	}
	for (loop=1; loop<n; loop++) {
		scanf("%d", &serve_winner[loop]);
		if (serve_winner[loop] == 1) {
			player1Victories[loop] = player1Victories[loop-1] + 1;
			player2Victories[loop] = player2Victories[loop-1];
		}
		else /* (serve_winner[loop] == 2) */ {
			player1Victories[loop] = player1Victories[loop-1];
			player2Victories[loop] = player2Victories[loop-1] + 1;
		}
	}
	return n;
}

#ifdef debug_on
/* print arguments */
void printArgs (int n, int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int loop;
	printf("\nArguments:\n");
	printf(" n=%d;\n",n);
	printf(" serve_winner:\n");
	for (loop=0; loop<n; loop++)
		printf("  %d (%d x %d)\n",serve_winner[loop],player1Victories[loop],player2Victories[loop]);
}
#endif

int int_max (int x, int y) {
	return ( (x > y) ? x : y );
}

int int_min (int x, int y) {
	return ( (x < y) ? x : y );
}

/* search for an integer in array using binary search */
int binarySearch (int x, int first, int last, int *vector) {
   if (first > last) return -1;
   else {
      int middle = (first + last)/2;
      if (vector[middle] == x) return middle;
      if (vector[middle] > x)
         return binarySearch(x, first, middle-1, vector);
      else
         return binarySearch(x, middle+1, last, vector);
   }
}

bool trySolution (int s, int t, int n, int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int serve, maxSetDuration, p1WinsToCompleteSet, p2WinsToCompleteSet;
	int binarySearchMax, binarySearchResult, p1SetsCount, p2SetsCount;
	#ifdef debug_on
	/* if (s==4 && t==18) */
		printf("trySolution(s=%d, t=%d)\n",s,t);
	#endif
	serve = 0;
	p1SetsCount = 0;
	p2SetsCount = 0;
	maxSetDuration = 2 * t - 1;
	p1WinsToCompleteSet = t;
	p2WinsToCompleteSet = t;
	while (serve < n)
	{
		binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
		binarySearchResult = binarySearch(p1WinsToCompleteSet, serve, binarySearchMax, player1Victories);
		if (binarySearchResult != -1) {
		    while (player1Victories[binarySearchResult-1] == p1WinsToCompleteSet)
		        binarySearchResult--;
			p1SetsCount++;
			p1WinsToCompleteSet = p1WinsToCompleteSet + t;
			p2WinsToCompleteSet = p2WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
		}
		else {
			binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
			binarySearchResult = binarySearch(p2WinsToCompleteSet, serve, binarySearchMax, player2Victories);
		    while (player2Victories[binarySearchResult-1] == p2WinsToCompleteSet)
		        binarySearchResult--;
			p2SetsCount++;
			p1WinsToCompleteSet = p1WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
			p2WinsToCompleteSet = p2WinsToCompleteSet + t;
			if (binarySearchResult == -1)
			    return false;
		}
        #ifdef debug_on
        if (s==4 && t==18)
            printf("WinsInSet: %d x %d (SetsWon: %d x %d) [toSet: %d %d] serve = %d\n",player1Victories[binarySearchResult],player2Victories[binarySearchResult],p1SetsCount,p2SetsCount,p1WinsToCompleteSet,p2WinsToCompleteSet,serve);
        #endif
		serve = binarySearchResult + 1;
	}
    #ifdef debug_on
    if (s==4 && t==18)
        printf("|Result| p1Sets:%d; p2Sets:%d; serve:%d;\n",p1SetsCount,p2SetsCount,serve);
    #endif
	if (serve == n) {
	    if (p1SetsCount == s && p2SetsCount != s && player1Victories[n-1] > player1Victories[n-2])
		    return true;
	    if (p2SetsCount == s && p1SetsCount != s && player2Victories[n-1] > player2Victories[n-2])
		    return true;
	}
	return false;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, setsCountRoof, setsCountAttempt, setsSizeRoof, setsSizeAttempt, resultsCount, loop;
	int serve_winner[MAX_SIZE], player1Victories[MAX_SIZE], player2Victories[MAX_SIZE], result[MAX_SIZE][2];
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif

	n = readArgs(serve_winner, player1Victories, player2Victories);

	#ifdef debug_on
		printArgs(n,serve_winner,player1Victories,player2Victories);
		printf("\nProblem Solution:\n");
	#endif

	/* solution */
	resultsCount = 0;
	setsCountRoof = int_max(player1Victories[n-1], player2Victories[n-1]) + 1;
	for (setsCountAttempt=1; setsCountAttempt<setsCountRoof; setsCountAttempt++) {
		setsSizeRoof = setsCountRoof/setsCountAttempt + 1;
		for (setsSizeAttempt=1; setsSizeAttempt<setsSizeRoof; setsSizeAttempt++) {
			if (trySolution(setsCountAttempt,setsSizeAttempt,n,player1Victories,player2Victories)) {
				result[resultsCount][0] = setsCountAttempt;
				result[resultsCount][1] = setsSizeAttempt;
				resultsCount++;
			}
		}
	}
	printf("%d\n",resultsCount);
	for (loop=0; loop<resultsCount; loop++)
		printf("%d %d\n",result[loop][0],result[loop][1]);

	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define debug_on 1==0

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int loop;
	int *matches;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		if (debug_on)
			printf("%d matches results found in arguments!\n", *n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		if (debug_on)
			printf("#matches: ");
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			if (debug_on)
				printf("match #%d winner: ", loop+1);
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the number of points the winner scored and return that number */
int countWinnerVictories (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else if (matches[loop] == 2)
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsCount(int *matches, int n, int setsCount, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,inner_loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0;
	int ** solutionsBuffer;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p1Sets == setsCount) {
					if (loop == n-1) {
						if (debug_on)
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						if (*currSolutionsCount > 1)
							free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			if (debug_on)
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p2Sets == setsCount) {
					if (loop == n-1) {
						if (debug_on)
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						if (*currSolutionsCount > 1)
							free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			if (debug_on)
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		}
	}
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, winnerVictories, setsCountAttempt, solutionsCount=0, loop;
	int **solutions;
	int *matches;
	if (debug_on)
		printf("\nP4 - Tennis Game:\n");
	matches = readArgs(&n, argc, argv);
	if (debug_on)
		printMatches(matches,n);

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	if (debug_on)
		printf("\nProblem Solution:\n");
	winnerVictories = countWinnerVictories(matches,n);
	setsCountAttempt = 1;
	while (setsCountAttempt <= winnerVictories) {
		if (debug_on)
			printf("setsCountAttempt: %d.\n", setsCountAttempt);
		for (loop=1; loop<=(winnerVictories/setsCountAttempt); loop++)
			solutions = trySolutionForSetsCount(matches,n,setsCountAttempt,loop,solutions,&solutionsCount);
		setsCountAttempt++;
	}

	printf("%d\n",solutionsCount);
	for (loop=0; loop<solutionsCount; loop++)
		printf("%d %d\n",solutions[loop][0],solutions[loop][1]);
	if (debug_on)
		printf("\n--------------------\n");
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define debug_on 1==0

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int loop;
	int *matches;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		if (debug_on)
			printf("%d matches results found in arguments!\n", *n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		if (debug_on)
			printf("#matches: ");
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			if (debug_on)
				printf("match #%d winner: ", loop+1);
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the number of points the winner scored and return that number */
int countWinnerVictories (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else if (matches[loop] == 2)
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a divider and a numberToDivide, find the next number that is divider of the numberToDivide */
int findNextDivider (int currentDivider, int numberToDivide) {
	int loop;
	if (currentDivider == numberToDivide)
		return -1;
	for (loop=currentDivider+1; loop<=numberToDivide; loop++) {
		if (numberToDivide % loop == 0)
			return loop;
	}
	return -1;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsCount(int *matches, int n, int setsCount, int winnerVictories, int **currSolutions, int *currSolutionsCount) {
	int loop,inner_loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0;
	int setsSize = winnerVictories / setsCount;
	int ** solutionsBuffer;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p1Sets == setsCount) {
					if (loop == n-1) {
						if (debug_on)
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						if (*currSolutionsCount > 1)
							free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			if (debug_on)
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p2Sets == setsCount) {
					if (loop == n-1) {
						if (debug_on)
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			if (debug_on)
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		}
	}
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, winnerVictories, divider, solutionsCount=0, loop;
	int **solutions;
	int *matches;
	if (debug_on)
		printf("\nP4 - Tennis Game:\n");
	matches = readArgs(&n, argc, argv);
	if (debug_on)
		printMatches(matches,n);

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	if (debug_on)
		printf("\nProblem Solution:\n");
	winnerVictories = countWinnerVictories(matches,n);
	divider = 1;
	while (divider != -1) {
		if (debug_on)
			printf("Divider: %d.\n", divider);
		solutions = trySolutionForSetsCount(matches,n,divider,winnerVictories,solutions,&solutionsCount);
		divider = findNextDivider(divider,winnerVictories);
	}

	printf("%d\n",solutionsCount);
	for (loop=0; loop<solutionsCount; loop++)
		printf("%d %d\n",solutions[loop][0],solutions[loop][1]);
	if (debug_on)
		printf("\n--------------------\n");
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
//#define debug_on 1

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int *matches;
	int loop;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		#ifdef debug_on
			printf("%d matches results found in arguments!\n", *n);
		#endif
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		#ifdef debug_on
			printf("#matches: ");
		#endif
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			#ifdef debug_on
				printf("match #%d winner: ", loop+1);
			#endif
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the max number s and t can be and return that number */
int getHighestPossibleResult (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else /* (matches[loop] == 2) */
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsCount(int *matches, int n, int setsCount, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p1Sets == setsCount) {
					if (loop == n-1) {
						#ifdef debug_on
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						#endif
						currSolutions[*currSolutionsCount] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount][0] = setsCount;
						currSolutions[*currSolutionsCount][1] = setsSize;
						(*currSolutionsCount)++;
						return currSolutions;
					}
					return currSolutions;
				}
			}
			#ifdef debug_on
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
			#endif
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p2Sets == setsCount) {
					if (loop == n-1) {
						#ifdef debug_on
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						#endif
						currSolutions[*currSolutionsCount] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount][0] = setsCount;
						currSolutions[*currSolutionsCount][1] = setsSize;
						(*currSolutionsCount)++;
						return currSolutions;
					}
					return currSolutions;
				}
			}
			#ifdef debug_on
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
			#endif
		}
	}
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, highestPossibleResult, setsCountAttempt, solutionsCount=0, loop;
	int **solutions;
	int *matches;
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif
	matches = readArgs(&n, argc, argv);
	#ifdef debug_on
		printMatches(matches,n);
	#endif

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	#ifdef debug_on
		printf("\nProblem Solution:\n");
	#endif
	highestPossibleResult = getHighestPossibleResult(matches,n);
	solutions = malloc(highestPossibleResult * sizeof(int *));
	setsCountAttempt = 1;
	while (setsCountAttempt <= highestPossibleResult) {
	#ifdef debug_on
			printf("setsCountAttempt: %d.\n", setsCountAttempt);
	#endif
		for (loop=1; loop<=(highestPossibleResult/setsCountAttempt); loop++)
			solutions = trySolutionForSetsCount(matches,n,setsCountAttempt,loop,solutions,&solutionsCount);
		setsCountAttempt++;
	}

	printf("%d\n",solutionsCount);
	for (loop=0; loop<solutionsCount; loop++)
		printf("%d %d\n",solutions[loop][0],solutions[loop][1]);
	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define debug_on 1==0

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int loop;
	int *matches;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		if (debug_on)
			printf("%d matches results found in arguments!\n", *n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		if (debug_on)
			printf("#matches: ");
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			if (debug_on)
				printf("match #%d winner: ", loop+1);
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the number of points the winner scored and return that number */
int countWinnerVictories (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else if (matches[loop] == 2)
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsCount(int *matches, int n, int setsCount, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,inner_loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0;
	int ** solutionsBuffer;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p1Sets == setsCount) {
					if (loop == n-1) {
						if (debug_on)
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						if (*currSolutionsCount > 1)
							free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			if (debug_on)
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p2Sets == setsCount) {
					if (loop == n-1) {
						if (debug_on)
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			if (debug_on)
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		}
	}
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, winnerVictories, setsCountAttempt, solutionsCount=0, loop;
	int **solutions;
	int *matches;
	if (debug_on)
		printf("\nP4 - Tennis Game:\n");
	matches = readArgs(&n, argc, argv);
	if (debug_on)
		printMatches(matches,n);

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	if (debug_on)
		printf("\nProblem Solution:\n");
	winnerVictories = countWinnerVictories(matches,n);
	setsCountAttempt = 1;
	while (setsCountAttempt <= winnerVictories) {
		if (debug_on)
			printf("setsCountAttempt: %d.\n", setsCountAttempt);
		for (loop=1; loop<=(winnerVictories/setsCountAttempt); loop++)
			solutions = trySolutionForSetsCount(matches,n,setsCountAttempt,loop,solutions,&solutionsCount);
		setsCountAttempt++;
	}

	printf("%d\n",solutionsCount);
	for (loop=0; loop<solutionsCount; loop++)
		printf("%d %d\n",solutions[loop][0],solutions[loop][1]);
	if (debug_on)
		printf("\n--------------------\n");
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100000
/* #define debug_on 1 */
#define true 1
#define false 0
typedef int bool;

/* read program arguments */
int readArgs (int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int n, loop;
	scanf("%d", &n);
	/* process first serve result */
	scanf("%d", &serve_winner[0]);
	player1Victories[0] = 2 - serve_winner[loop];
	player2Victories[0] = serve_winner[loop] - 1;
	/* process other serve results */
	for (loop=1; loop<n; loop++) {
		scanf("%d", &serve_winner[loop]);
		player1Victories[loop] = player1Victories[loop-1] - serve_winner[loop] + 2;
		player2Victories[loop] = player2Victories[loop-1] + serve_winner[loop] - 1;
	}
	return n;
}

#ifdef debug_on
/* print arguments */
void printArgs (int n, int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int loop;
	printf("\nArguments:\n");
	printf(" n=%d;\n",n);
	printf(" serve_winner:\n");
	for (loop=0; loop<n; loop++)
		printf("  %d (%d x %d)\n",serve_winner[loop],player1Victories[loop],player2Victories[loop]);
}
#endif

int int_max (int x, int y) {
	return ( (x > y) ? x : y );
}

int int_min (int x, int y) {
	return ( (x < y) ? x : y );
}

/* search for an integer in array using binary search */
int binarySearch (int x, int first, int last, int *vector) {
   if (first > last) return -1;
   else {
      int middle = (first + last)/2;
      if (vector[middle] == x) return middle;
      if (vector[middle] > x)
         return binarySearch(x, first, middle-1, vector);
      else
         return binarySearch(x, middle+1, last, vector);
   }
}

bool trySolution (int s, int t, int n, int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE], int maxServesWon) {
	int serve, maxSetDuration, p1WinsToCompleteSet, p2WinsToCompleteSet;
	int binarySearchMax, binarySearchResult, p1SetsCount, p2SetsCount;
	bool completedMatch = false;
	#ifdef debug_on
	/* if (s==5 && t==1) */
		printf("trySolution(s=%d, t=%d)\n",s,t);
	#endif
	if (maxServesWon < s*t)
		return false;
	if (maxServesWon > s*t + (s-1)*(t-1))
		return false;
	serve = 0;
	p1SetsCount = 0;
	p2SetsCount = 0;
	maxSetDuration = 2 * t - 1;
	p1WinsToCompleteSet = t;
	p2WinsToCompleteSet = t;
	while (serve < n && !completedMatch)
	{
		binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
		binarySearchResult = binarySearch(p1WinsToCompleteSet, serve, binarySearchMax, player1Victories);
		if (binarySearchResult != -1) {
			p1SetsCount++;
			if (p1SetsCount == s)
				completedMatch = true;
			else {
				while (player1Victories[binarySearchResult-1] == p1WinsToCompleteSet)
					binarySearchResult--;
				p1WinsToCompleteSet = p1WinsToCompleteSet + t;
				p2WinsToCompleteSet = p2WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
			}
		}
		else {
			binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
			binarySearchResult = binarySearch(p2WinsToCompleteSet, serve, binarySearchMax, player2Victories);
			p2SetsCount++;
			if (p2SetsCount == s)
				completedMatch = true;
			else {
				while (player2Victories[binarySearchResult-1] == p2WinsToCompleteSet)
					binarySearchResult--;
				p1WinsToCompleteSet = p1WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
				p2WinsToCompleteSet = p2WinsToCompleteSet + t;
			}
		}
        #ifdef debug_on
        if (s==5 && t==1)
            printf("WinsInSet: %d x %d (SetsWon: %d x %d) [toSet: %d %d] serve = %d\n",player1Victories[binarySearchResult],player2Victories[binarySearchResult],p1SetsCount,p2SetsCount,p1WinsToCompleteSet,p2WinsToCompleteSet,serve);
        #endif
		serve = binarySearchResult + 1;
	}
    #ifdef debug_on
    if (s==5 && t==1)
        printf("|Result| p1Sets:%d; p2Sets:%d; serve:%d;\n",p1SetsCount,p2SetsCount,serve);
    #endif
	if (serve == n) {
	    if (p1SetsCount == s && p1SetsCount > p2SetsCount)
		    return true;
	    if (p2SetsCount == s && p2SetsCount > p1SetsCount)
		    return true;
	}
	return false;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, maxServesWon, setsCountRoof, setsCountAttempt, setsSizeRoof, setsSizeAttempt, resultsCount, loop;
	int serve_winner[MAX_SIZE], player1Victories[MAX_SIZE], player2Victories[MAX_SIZE], result[MAX_SIZE][2];
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif

	n = readArgs(serve_winner, player1Victories, player2Victories);

	#ifdef debug_on
		printArgs(n,serve_winner,player1Victories,player2Victories);
		printf("\nProblem Solution:\n");
	#endif

	/* solution */
	resultsCount = 0;
	maxServesWon = int_max(player1Victories[n-1], player2Victories[n-1]);
	setsCountRoof = maxServesWon + 1;
	for (setsCountAttempt=1; setsCountAttempt<setsCountRoof; setsCountAttempt++) {
		setsSizeRoof = setsCountRoof/setsCountAttempt + 1;
		for (setsSizeAttempt=1; setsSizeAttempt<setsSizeRoof; setsSizeAttempt++) {
			if (trySolution(setsCountAttempt,setsSizeAttempt,n,player1Victories,player2Victories,maxServesWon)) {
				result[resultsCount][0] = setsCountAttempt;
				result[resultsCount][1] = setsSizeAttempt;
				resultsCount++;
			}
		}
	}
	printf("%d\n",resultsCount);
	for (loop=0; loop<resultsCount; loop++)
		printf("%d %d\n",result[loop][0],result[loop][1]);

	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
//#define debug_on 1

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int *matches;
	int loop;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		#ifdef debug_on
			printf("%d matches results found in arguments!\n", *n);
		#endif
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		#ifdef debug_on
			printf("#matches: ");
		#endif
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			#ifdef debug_on
				printf("match #%d winner: ", loop+1);
			#endif
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the number of points the winner scored and return that number */
int countWinnerVictories (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else if (matches[loop] == 2)
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsCount(int *matches, int n, int setsCount, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,inner_loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0;
	int ** solutionsBuffer;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p1Sets == setsCount) {
					if (loop == n-1) {
						#ifdef debug_on
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						#endif
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						if (*currSolutionsCount > 1)
							free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			#ifdef debug_on
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
			#endif
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
				if (p2Sets == setsCount) {
					if (loop == n-1) {
						#ifdef debug_on
							printf("(%d %d) is a solution!\n",setsCount,setsSize);
						#endif
						(*currSolutionsCount)++;
						solutionsBuffer = currSolutions;
						currSolutions = malloc(*currSolutionsCount * sizeof(int *));
						for (inner_loop=0; inner_loop<*currSolutionsCount-1; inner_loop++) {
							currSolutions[inner_loop] = malloc(2*sizeof(int));
							currSolutions[inner_loop][0] = solutionsBuffer[inner_loop][0];
							currSolutions[inner_loop][1] = solutionsBuffer[inner_loop][1];
						}
						currSolutions[*currSolutionsCount-1] = malloc(2*sizeof(int));
						currSolutions[*currSolutionsCount-1][0] = setsCount;
						currSolutions[*currSolutionsCount-1][1] = setsSize;
						if (*currSolutionsCount > 1)
							free(solutionsBuffer);
						return currSolutions;
					}
					return currSolutions;
				}
			}
			#ifdef debug_on
				printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
			#endif
		}
	}
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, winnerVictories, setsCountAttempt, solutionsCount=0, loop;
	int **solutions;
	int *matches;
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif
	matches = readArgs(&n, argc, argv);
	#ifdef debug_on
		printMatches(matches,n);
	#endif
		if (n == 50000) printf("teste");

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	#ifdef debug_on
		printf("\nProblem Solution:\n");
	#endif
	winnerVictories = countWinnerVictories(matches,n);
	setsCountAttempt = 1;
	while (setsCountAttempt <= winnerVictories) {
	#ifdef debug_on
			printf("setsCountAttempt: %d.\n", setsCountAttempt);
	#endif
		for (loop=1; loop<=(winnerVictories/setsCountAttempt); loop++)
			solutions = trySolutionForSetsCount(matches,n,setsCountAttempt,loop,solutions,&solutionsCount);
		setsCountAttempt++;
	}

	printf("%d\n",solutionsCount);
	for (loop=0; loop<solutionsCount; loop++)
		printf("%d %d\n",solutions[loop][0],solutions[loop][1]);
	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
//#define debug_on 1

/* read matches results through command line parameters or through runtime user input */
int *readArgs (int *n, int argc, char *argv[]) {
	int *matches;
	int loop;
	if (argc>2 && (argc>=atoi(argv[1])+2) && atoi(argv[1])>=1 && atoi(argv[1]) <= 100000) {
		*n = atoi(argv[1]);
		#ifdef debug_on
			printf("%d matches results found in arguments!\n", *n);
		#endif
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			matches[loop] = atoi(argv[loop+2]);
		}
	}
	else {
		#ifdef debug_on
			printf("#matches: ");
		#endif
		scanf("%d", n);
		matches = malloc(*n * sizeof(int));
		for (loop=0; loop<*n; loop++) {
			#ifdef debug_on
				printf("match #%d winner: ", loop+1);
			#endif
			scanf("%d", &matches[loop]);
		}
	}
	return matches;
}

/* print matches results */
void printMatches (int *matches, int n	) {
	int loop;
	printf("matches: ");
	for (loop=0; loop<n; loop++)
		printf("%d ",matches[loop]);
	printf("\n");
}

/* analyse results, determine the max number s and t can be and return that number */
int getHighestPossibleResult (int *matches, int n) {
	int player1Victories=0, player2Victories=0, loop;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1)
			player1Victories++;
		else /* (matches[loop] == 2) */
			player2Victories++;
	}
	if (player1Victories>player2Victories)
		return player1Victories;
	return player2Victories;
}

/* given a number representing 's', calculate the related t and check if it is a possible solution  */
/* if it is a possible solution, add to the solutions array */
/* at the end, return the solutions array */
int **trySolutionForSetsSize(int *matches, int n, int setsSize, int **currSolutions, int *currSolutionsCount) {
	int loop,p1Sets=0,p1MatchesCurrSet=0,p2Sets=0,p2MatchesCurrSet=0,setsCount;
	for (loop=0; loop<n; loop++) {
		if (matches[loop] == 1) {
			p1MatchesCurrSet++;
			if (p1MatchesCurrSet==setsSize) {
				p1Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
			}
		}
		else if (matches[loop] == 2) {
			p2MatchesCurrSet++;
			if (p2MatchesCurrSet==setsSize) {
				p2Sets++;
				p1MatchesCurrSet=0;
				p2MatchesCurrSet=0;
			}
		}
		#ifdef debug_on
			printf("currentScore: %d(%d) x %d(%d).\n",p1Sets,p1MatchesCurrSet,p2Sets,p2MatchesCurrSet);
		#endif
	}
	if (p1MatchesCurrSet>0 || p2MatchesCurrSet>0)
		return currSolutions;
	if (p1Sets > p2Sets)
		setsCount = p1Sets;
	else if (p1Sets < p2Sets)
		setsCount = p2Sets;
	else /* (p1Sets == p2Sets) */
		return currSolutions;
	#ifdef debug_on
		printf("(%d %d) is a solution!\n",setsCount,setsSize);
	#endif
	currSolutions[*currSolutionsCount] = malloc(2*sizeof(int));
	currSolutions[*currSolutionsCount][0] = setsCount;
	currSolutions[*currSolutionsCount][1] = setsSize;
	(*currSolutionsCount)++;
	return currSolutions;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, highestPossibleResult, setsSizeAttempt, solutionsCount=0, loop;
	int **solutions;
	int *matches;
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif
	matches = readArgs(&n, argc, argv);
	#ifdef debug_on
		printMatches(matches,n);
	#endif

	if (n<1 || n>100000) {
		printf("Invalid matches number. Aborting...\n");
		printf("\n--------------------\n");
		return 1;
	}
	#ifdef debug_on
		printf("\nProblem Solution:\n");
	#endif
	highestPossibleResult = getHighestPossibleResult(matches,n);
	solutions = malloc(highestPossibleResult * sizeof(int *));
	setsSizeAttempt = 1;
	for (setsSizeAttempt=highestPossibleResult; setsSizeAttempt>0; setsSizeAttempt--) {
		#ifdef debug_on
			printf("setsSizeAttempt: %d.\n", setsSizeAttempt);
		#endif
		solutions = trySolutionForSetsSize(matches,n,setsSizeAttempt,solutions,&solutionsCount);
	}

	printf("%d\n",solutionsCount);
	for (loop=0; loop<solutionsCount; loop++)
		printf("%d %d\n",solutions[loop][0],solutions[loop][1]);
	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100000
/* #define debug_on 1 */
#define true 1
#define false 0
typedef int bool;

/* read program arguments */
int readArgs (int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int n, loop;
	scanf("%d", &n);
	/* process first match result */
	scanf("%d", &serve_winner[0]);
	if (serve_winner[0] == 1) {
		player1Victories[0] = 1;
		player2Victories[0] = 0;
	}
	else /* (serve_winner[0] == 2) */ {
		player1Victories[0] = 0;
		player2Victories[0] = 1;
	}
	for (loop=1; loop<n; loop++) {
		scanf("%d", &serve_winner[loop]);
		player1Victories[loop] = player1Victories[loop-1] + 2 - serve_winner[loop];
		player2Victories[loop] = player2Victories[loop-1] - 1 + serve_winner[loop];
	}
	return n;
}

#ifdef debug_on
/* print arguments */
void printArgs (int n, int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int loop;
	printf("\nArguments:\n");
	printf(" n=%d;\n",n);
	printf(" serve_winner:\n");
	for (loop=0; loop<n; loop++)
		printf("  %d (%d x %d)\n",serve_winner[loop],player1Victories[loop],player2Victories[loop]);
}
#endif

int int_max (int x, int y) {
	return ( (x > y) ? x : y );
}

int int_min (int x, int y) {
	return ( (x < y) ? x : y );
}

/* search for an integer in array using binary search */
int binarySearch (int x, int first, int last, int *vector) {
   if (first > last) return -1;
   else {
      int middle = (first + last)/2;
      if (vector[middle] == x) return middle;
      if (vector[middle] > x)
         return binarySearch(x, first, middle-1, vector);
      else
         return binarySearch(x, middle+1, last, vector);
   }
}

bool trySolution (int s, int t, int n, int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int serve, maxSetDuration, p1WinsToCompleteSet, p2WinsToCompleteSet;
	int binarySearchMax, binarySearchResult, p1SetsCount, p2SetsCount;
	#ifdef debug_on
	/* if (s==5 && t==1) */
		printf("trySolution(s=%d, t=%d)\n",s,t);
	#endif
	serve = 0;
	p1SetsCount = 0;
	p2SetsCount = 0;
	maxSetDuration = 2 * t - 1;
	p1WinsToCompleteSet = t;
	p2WinsToCompleteSet = t;
	while (serve < n)
	{
		binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
		binarySearchResult = binarySearch(p1WinsToCompleteSet, serve, binarySearchMax, player1Victories);
		if (binarySearchResult != -1) {
		    while (player1Victories[binarySearchResult-1] == p1WinsToCompleteSet)
		        binarySearchResult--;
			p1SetsCount++;
			p1WinsToCompleteSet = p1WinsToCompleteSet + t;
			p2WinsToCompleteSet = p2WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
		}
		else {
			binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
			binarySearchResult = binarySearch(p2WinsToCompleteSet, serve, binarySearchMax, player2Victories);
		    while (player2Victories[binarySearchResult-1] == p2WinsToCompleteSet)
		        binarySearchResult--;
			p2SetsCount++;
			p1WinsToCompleteSet = p1WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
			p2WinsToCompleteSet = p2WinsToCompleteSet + t;
			if (binarySearchResult == -1)
			    return false;
		}
        #ifdef debug_on
        if (s==5 && t==1)
            printf("WinsInSet: %d x %d (SetsWon: %d x %d) [toSet: %d %d] serve = %d\n",player1Victories[binarySearchResult],player2Victories[binarySearchResult],p1SetsCount,p2SetsCount,p1WinsToCompleteSet,p2WinsToCompleteSet,serve);
        #endif
		serve = binarySearchResult + 1;
	}
    #ifdef debug_on
    if (s==5 && t==1)
        printf("|Result| p1Sets:%d; p2Sets:%d; serve:%d;\n",p1SetsCount,p2SetsCount,serve);
    #endif
	if (serve == n) {
	    if (p1SetsCount == s && p2SetsCount != s && p1SetsCount > p2SetsCount && player1Victories[n-1] > player1Victories[n-2])
		    return true;
	    if (p2SetsCount == s && p1SetsCount != s && p2SetsCount > p1SetsCount &&  player2Victories[n-1] > player2Victories[n-2])
		    return true;
	}
	return false;
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, setsCountRoof, setsCountAttempt, setsSizeRoof, setsSizeAttempt, resultsCount, loop;
	int serve_winner[MAX_SIZE], player1Victories[MAX_SIZE], player2Victories[MAX_SIZE], result[MAX_SIZE][2];
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif

	n = readArgs(serve_winner, player1Victories, player2Victories);

	#ifdef debug_on
		printArgs(n,serve_winner,player1Victories,player2Victories);
		printf("\nProblem Solution:\n");
	#endif

	/* solution */
	resultsCount = 0;
	setsCountRoof = int_max(player1Victories[n-1], player2Victories[n-1]) + 1;
	for (setsCountAttempt=1; setsCountAttempt<setsCountRoof; setsCountAttempt++) {
		setsSizeRoof = setsCountRoof/setsCountAttempt + 1;
		for (setsSizeAttempt=1; setsSizeAttempt<setsSizeRoof; setsSizeAttempt++) {
			if (trySolution(setsCountAttempt,setsSizeAttempt,n,player1Victories,player2Victories)) {
				result[resultsCount][0] = setsCountAttempt;
				result[resultsCount][1] = setsSizeAttempt;
				resultsCount++;
			}
		}
	}
	printf("%d\n",resultsCount);
	for (loop=0; loop<resultsCount; loop++)
		printf("%d %d\n",result[loop][0],result[loop][1]);

	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/


/***************************************************************/
/**                                                           **/
/**   Leonardo Haddad                           nº 7295361    **/
/**   Desafios de Programação              Professora Cris    **/
/**   Problema 4 - Tennis Game                  Curso: BCC    **/
/**                                                           **/
/***************************************************************/

#include<stdio.h>
#include<stdlib.h>
#define MAX_SIZE 100000
/* #define debug_on 1 */
#define true 1
#define false 0
typedef int bool;

/* read program arguments */
int readArgs (int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int n, loop;
	scanf("%d", &n);
	/* process first serve result */
	scanf("%d", &serve_winner[0]);
	player1Victories[0] = 2 - serve_winner[0];
	player2Victories[0] = serve_winner[0] - 1;
	/* process other serve results */
	for (loop=1; loop<n; loop++) {
		scanf("%d", &serve_winner[loop]);
		player1Victories[loop] = player1Victories[loop-1] - serve_winner[loop] + 2;
		player2Victories[loop] = player2Victories[loop-1] + serve_winner[loop] - 1;
	}
	return n;
}

#ifdef debug_on
/* print arguments */
void printArgs (int n, int serve_winner[MAX_SIZE], int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE]) {
	int loop;
	printf("\nArguments:\n");
	printf(" n=%d;\n",n);
	printf(" serve_winner:\n");
	for (loop=0; loop<n; loop++)
		printf("  %d (%d x %d)\n",serve_winner[loop],player1Victories[loop],player2Victories[loop]);
}
#endif

int int_max (int x, int y) {
	return ( (x > y) ? x : y );
}

int int_min (int x, int y) {
	return ( (x < y) ? x : y );
}

/* search for an integer in array using binary search */
int binarySearch (int x, int first, int last, int *vector) {
   if (first > last) return -1;
   else {
      int middle = (first + last)/2;
      if (vector[middle] == x) return middle;
      if (vector[middle] > x)
         return binarySearch(x, first, middle-1, vector);
      else
         return binarySearch(x, middle+1, last, vector);
   }
}

/* merge two sorted arrays in a sorted way */
void merge (int p, int q, int r, int v[MAX_SIZE][2])
{
   int i, j, k, w[MAX_SIZE][2];

   for (i = 0, k = p; k < q; ++i, ++k) {
		w[i][0] = v[k][0];
		w[i][1] = v[k][1];
   }
   for (j = r-p-1, k = q; k < r; --j, ++k) {
	   w[j][0] = v[k][0];
	   w[j][1] = v[k][1];
   }
   i = 0; j = r-p-1;
   for (k = p; k < r; ++k)
      if (w[i][0] < w[j][0]) {
		v[k][0] = w[i][0];
		v[k][1] = w[i++][1];
	  }
      else if (w[i][0] > w[j][0])  {
		v[k][0] = w[j][0];
		v[k][1] = w[j--][1];
	  }
	  else /* (w[i][0] == w[j][0]) */ {
		if (w[i][1] <= w[j][1]) {
			v[k][0] = w[i][0];
			v[k][1] = w[i++][1];
		}
		else /* (w[i][1] > w[j][1]) */ {
			v[k][0] = w[j][0];
			v[k][1] = w[j--][1];
		}
	  }
}

/* sort array using mergesort algorithm */
void merge_sort (int p, int r, int v[MAX_SIZE][2])
{
   if (p < r-1) {
      int q = (p + r)/2;
      merge_sort (p, q, v);
      merge_sort (q, r, v);
      merge (p, q, r, v);
   }
}

void trySolution (int t, int n, int player1Victories[MAX_SIZE], int player2Victories[MAX_SIZE], int result[MAX_SIZE][2], int *resultsCount) {
	int serve, maxSetDuration, p1WinsToCompleteSet, p2WinsToCompleteSet;
	int binarySearchMax, binarySearchResult, p1SetsCount, p2SetsCount;
	#ifdef debug_on
		printf("trySolution(t=%d)\n",t);
	#endif
if (n == 100000 && *resultsCount == 35 && result[34][1] == 2)
	printf("testou!");
	serve = 0;
	p1SetsCount = 0;
	p2SetsCount = 0;
	maxSetDuration = 2 * t - 1;
	p1WinsToCompleteSet = t;
	p2WinsToCompleteSet = t;
	while (serve < n)
	{
		binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
		binarySearchResult = binarySearch(p1WinsToCompleteSet, serve, binarySearchMax, player1Victories);
		if (binarySearchResult != -1) {
			p1SetsCount++;
			while (player1Victories[binarySearchResult-1] == p1WinsToCompleteSet)
				binarySearchResult--;
			p1WinsToCompleteSet = p1WinsToCompleteSet + t;
			p2WinsToCompleteSet = p2WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
		}
		else {
			binarySearchMax = int_min(serve+maxSetDuration-1, n-1);
			binarySearchResult = binarySearch(p2WinsToCompleteSet, serve, binarySearchMax, player2Victories);
			if (binarySearchResult == -1)
				return;
			p2SetsCount++;
			while (player2Victories[binarySearchResult-1] == p2WinsToCompleteSet)
				binarySearchResult--;
			p1WinsToCompleteSet = p1WinsToCompleteSet + (binarySearchResult - serve + 1 - t);
			p2WinsToCompleteSet = p2WinsToCompleteSet + t;
		}
        #ifdef debug_on
        if (t==1)
            printf("WinsInSet: %d x %d (SetsWon: %d x %d) [toSet: %d %d] serve = %d\n",player1Victories[binarySearchResult],player2Victories[binarySearchResult],p1SetsCount,p2SetsCount,p1WinsToCompleteSet,p2WinsToCompleteSet,serve);
        #endif
		serve = binarySearchResult + 1;
	}
    #ifdef debug_on
    if (t==1)
        printf("|Result| p1Sets:%d; p2Sets:%d; serve:%d;\n",p1SetsCount,p2SetsCount,serve);
    #endif
	if (serve == n) {
	    if (p1SetsCount > p2SetsCount && player1Victories[n-1] > player1Victories[n-2]) {
			result[*resultsCount][0] = p1SetsCount;
			result[*resultsCount][1] = t;
			*resultsCount = *resultsCount + 1;
		}
	    else if (p2SetsCount > p1SetsCount && player2Victories[n-1] > player2Victories[n-2]) {
			result[*resultsCount][0] = p2SetsCount;
			result[*resultsCount][1] = t;
			*resultsCount = *resultsCount + 1;
		}
	}
}

/* solve the problem */
int main (int argc, char *argv[]) {
	int n, maxServesWon, setsSizeAttempt, resultsCount, loop;
	int serve_winner[MAX_SIZE], player1Victories[MAX_SIZE], player2Victories[MAX_SIZE], result[MAX_SIZE][2];
	#ifdef debug_on
		printf("\nP4 - Tennis Game:\n");
	#endif

	n = readArgs(serve_winner, player1Victories, player2Victories);

	#ifdef debug_on
		printArgs(n,serve_winner,player1Victories,player2Victories);
		printf("\nProblem Solution:\n");
	#endif

	/* solution */
	resultsCount = 0;
	maxServesWon = int_max(player1Victories[n-1], player2Victories[n-1]);

	for (setsSizeAttempt=maxServesWon; setsSizeAttempt>0; setsSizeAttempt--) {
		trySolution(setsSizeAttempt,n,player1Victories,player2Victories,result,&resultsCount);
	}
	merge_sort(0,resultsCount-1,result);
	printf("%d\n",resultsCount);
	for (loop=0; loop<resultsCount; loop++)
		printf("%d %d\n",result[loop][0],result[loop][1]);

	#ifdef debug_on
		printf("\n--------------------\n");
	#endif
	return 0;
}

/*

D. Tennis Game
time limit per test: 2 seconds
memory limit per test: 256 megabytes
input: standard input
output: standard output
url: http://codeforces.com/problemset/problem/496/D

Petya and Gena love playing table tennis. A single match is played according to the following rules: a match consists of multiple sets, each set consists of multiple serves. Each serve is won by one of the players, this player scores one point. As soon as one of the players scores t points, he wins the set; then the next set starts and scores of both players are being set to 0. As soon as one of the players wins the total of s sets, he wins the match and the match is over. Here s and t are some positive integer numbers.
To spice it up, Petya and Gena choose new numbers s and t before every match. Besides, for the sake of history they keep a record of each match: that is, for each serve they write down the winner. Serve winners are recorded in the chronological order. In a record the set is over as soon as one of the players scores t points and the match is over as soon as one of the players wins s sets.
Petya and Gena have found a record of an old match. Unfortunately, the sequence of serves in the record isn't divided into sets and numbers s and t for the given match are also lost. The players now wonder what values of s and t might be. Can you determine all the possible options?

Input:
The first line contains a single integer n — the length of the sequence of games (1 ≤ n ≤ 10^5).
The second line contains n space-separated integers ai. If ai = 1, then the i-th serve was won by Petya, if ai = 2, then the i-th serve was won by Gena.
It is not guaranteed that at least one option for numbers s and t corresponds to the given record.

Output:
In the first line print a single number k — the number of options for numbers s and t.
In each of the following k lines print two integers si and ti — the option for numbers s and t. Print the options in the order of increasing si, and for equal si — in the order of increasing ti.

Sample test(s):

Input:
5
1 2 1 2 1
Output:
2
1 3
3 1

Input:
4
1 1 1 1
Output:
3
1 4
2 2
4 1

Input:
4
1 2 1 2
Output:
0

Input:
8
2 1 2 1 1 1 1 1
Output:
3
1 6
2 3
6 1

*/