import java.io.InputStreamReader;
import java.io.IOException;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.util.StringTokenizer;
import java.io.InputStream;
/**
* Built using CHelper plug-in
* Actual solution is at the top
* @author Rubanenko
*/
public class Main {
public static void main
(String[] args
) { InputReader in = new InputReader(inputStream);
Dag solver = new Dag();
solver.solve(1, in, out);
out.close();
}
}
class Dag {
public void solve
(int testNumber, InputReader in,
PrintWriter out
) { int n = in.nextInt();
boolean[][] a = new boolean[n + 1][n + 1];
boolean[][] newEdge = new boolean[n + 1][n + 1];
boolean[] used = new boolean[n + 1];
int[] outDegree = new int[n + 1];
int numberOfEdges = (n * (n - 1)) / 2;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
a[i][j] = (s.charAt(j) == '1');
if (a[i][j]) {
numberOfEdges--;
outDegree[i]++;
}
}
}
out.println(numberOfEdges);
for (int i = 0; i < n; i++) {
int v = -1;
for (int j = n - 1; j >= 0; j--) {
if (!used[j] && outDegree[j] == 0) {
v = j;
break;
}
}
used[v] = true;
for (int j = 0; j < n; j++) {
if (j != v && !a[j][v] && !used[j]) {
newEdge[j][v] = true;
}
}
for (int j = 0; j < n; j++) {
if (a[j][v]) outDegree[j]--;
}
}
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
if (newEdge[i][j]) out.println((i + 1) + " " + (j + 1));
}
}
}
}
class InputReader {
}
try {
line = reader.readLine();
}
return line;
}
while (tokenizer == null || !tokenizer.hasMoreTokens())
return tokenizer.nextToken();
}
public int nextInt() {
}
}