#include <bits/stdc++.h>
using namespace std;
using fst = tuple<int, int, int>;
const int N = 75;
int n, h[N][N][N], a[3], tmp[3];
fst par[N][N][N];
string s[N];
bool vis[N][N][N];
vector<pair<int, int>> ans;
queue<fst> q;
int main() {
  ios::sync_with_stdio(false), cin.tie(NULL), cout.tie(NULL);
  cin >> n;
  for (int i = 0; i < 3; i++) cin >> a[i], --a[i];
  sort(a, a + 3);
  for (int i = 0; i < n; i++) cin >> s[i];
  vis[a[0]][a[1]][a[2]] = true, par[a[0]][a[1]][a[2]] = {-1, -1, -1};
  q.push({a[0], a[1], a[2]});
  while (!q.empty()) {
    tie(tmp[0], tmp[1], tmp[2]) = q.front();
    q.pop();
    for (int i = 0; i < n; i++) {
      bool flag = false;
      for (int j = 0; j < 3; j++)
        if (tmp[j] == i) flag = true;
      if (flag) continue;
      for (int j = 0; j < 3; j++)
        for (int k = j + 1; k < 3; k++) {
          a[0] = tmp[j], a[1] = tmp[k];
          a[2] = tmp[1 ^ 2 ^ j ^ k];
          if (s[a[0]][a[1]] ^ s[a[2]][i]) continue;
          a[2] = i;
          sort(a, a + 3);
          if (!vis[a[0]][a[1]][a[2]]) {
            h[a[0]][a[1]][a[2]] = h[tmp[0]][tmp[1]][tmp[2]] + 1;
            vis[a[0]][a[1]][a[2]] = true,
            par[a[0]][a[1]][a[2]] = {tmp[0], tmp[1], tmp[2]};
            q.push({a[0], a[1], a[2]});
          }
        }
    }
  }
  if (!vis[0][1][2]) return cout << "-1\n", 0;
  cout << h[0][1][2] << '\n';
  fst sv = {0, 1, 2}, sv2;
  set<int> exist;
  int res;
  while (get<0>(sv) ^ -1 || !get<0>(sv)) {
    sv2 = par[get<0>(sv)][get<1>(sv)][get<2>(sv)];
    tie(a[0], a[1], a[2]) = sv;
    if (get<0>(sv2) == -1) {
      sv = sv2;
      continue;
    }
    exist.insert(get<0>(sv2)), exist.insert(get<1>(sv2)),
        exist.insert(get<2>(sv2));
    for (int i = 0; i < 3; i++)
      exist.count(a[i]) ? exist.erase(a[i]) : res = a[i];
    ans.push_back({*exist.begin() + 1, res + 1});
    exist.clear(), sv = sv2;
  }
  reverse(ans.begin(), ans.end());
  for (auto [x, y] : ans) cout << x << ' ' << y << '\n';
}
