#include <bits/stdc++.h>
using namespace std;
const int MAX = 73;
int n;
char g[MAX][MAX];
int f[MAX][MAX][MAX];
struct Case {
  int a[3];
  Case(int first = 0, int second = 0, int z = 0) {
    a[0] = first;
    a[1] = second;
    a[2] = z;
    sort(a, a + 3);
  }
};
Case q[MAX * MAX * MAX];
pair<int, int> comex[MAX][MAX][MAX];
Case come[MAX][MAX][MAX];
int main() {
  int i, j;
  scanf("%d", &n);
  int first, second, z;
  scanf("%d%d%d", &first, &second, &z);
  for ((i) = (1); (i) <= (n); ++(i)) scanf("%s", g[i] + 1);
  memset(f, -1, sizeof f);
  Case begin(first, second, z);
  f[begin.a[0]][begin.a[1]][begin.a[2]] = 0;
  int head = 0, end = 0;
  q[end++] = begin;
  while (head < end) {
    Case c = q[head++];
    for ((i) = (0); (i) <= (2); ++(i)) {
      int l = (i + 1) % 3;
      int ll = (l + 1) % 3;
      for ((j) = (1); (j) <= (n); ++(j))
        if (j != c.a[i] && j != c.a[l] && j != c.a[ll] &&
            g[c.a[i]][j] == g[c.a[l]][c.a[ll]]) {
          Case ne(j, c.a[l], c.a[ll]);
          if (f[ne.a[0]][ne.a[1]][ne.a[2]] == -1) {
            q[end++] = ne;
            f[ne.a[0]][ne.a[1]][ne.a[2]] = f[c.a[0]][c.a[1]][c.a[2]] + 1;
            come[ne.a[0]][ne.a[1]][ne.a[2]] = c;
            comex[ne.a[0]][ne.a[1]][ne.a[2]] = make_pair(c.a[i], j);
          }
        }
    }
  }
  if (f[1][2][3] == -1)
    printf("-1\n");
  else {
    printf("%d\n", f[1][2][3]);
    Case now(1, 2, 3);
    vector<pair<int, int> > ans;
    while (comex[now.a[0]][now.a[1]][now.a[2]].first) {
      ans.push_back(comex[now.a[0]][now.a[1]][now.a[2]]);
      now = come[now.a[0]][now.a[1]][now.a[2]];
    }
    reverse(ans.begin(), ans.end());
    for ((i) = (0); (i) != ((int)ans.size()); ++(i))
      printf("%d %d\n", ans[i].first, ans[i].second);
  }
  return 0;
}
