#include <bits/stdc++.h>
#pragma comment(linker, "/STACK:100000000000,100000000000")
using namespace std;
const double eps = 1E-9;
const double Exp = 2.718281828459045;
const double Pi = 3.1415926535897932;
const int NMAX = 70 * 70 * 70 + 5;
const int KMAX = 70 + 5;
const int MMAX = 26 + 5;
const int INF = 1000000000;
const int BASE = 1000000007;
template <typename T>
inline T abs(const T a) {
  if (a < 0) return -a;
  return a;
}
template <typename T>
inline T sqr(const T& a) {
  return a * a;
}
struct state {
  int a, b, c;
  bool operator<(const state& a) const {
    if (this->a == a.a) {
      if (this->b == a.b) return this->c < a.c;
      return this->b < a.b;
    }
    return this->a < a.a;
  }
  bool operator==(const state& a) const {
    return (this->a == a.a && this->b == a.b && this->c == a.c);
  }
};
state ok(const state& a) {
  state r;
  r.a = min(a.a, min(a.b, a.c));
  r.c = max(a.a, max(a.b, a.c));
  r.b = a.a + a.b + a.c - r.a - r.c;
  return r;
}
pair<int, int> dif(state x, state y) {
  pair<int, int> r;
  if (x.a != y.a && x.a != y.b && x.a != y.c) r.first = x.a;
  if (x.b != y.a && x.b != y.b && x.b != y.c) r.first = x.b;
  if (x.c != y.a && x.c != y.b && x.c != y.c) r.first = x.c;
  if (y.a != x.a && y.a != x.b && y.a != x.c) r.second = y.a;
  if (y.b != x.a && y.b != x.b && y.b != x.c) r.second = y.b;
  if (y.c != x.a && y.c != x.b && y.c != x.c) r.second = y.c;
  return r;
}
int main() {
  int n;
  int i, j;
  static state q[NMAX];
  map<state, state> from;
  map<state, int> d;
  set<state> vis;
  vector<int> e[KMAX][MMAX];
  static char a[KMAX][KMAX];
  vector<int>::iterator it;
  int he, ta;
  state s, f;
  state cur;
  state x;
  f.a = 1;
  f.b = 2;
  f.c = 3;
  cin >> n;
  cin >> s.a >> s.b >> s.c;
  s = ok(s);
  for (i = 1; i <= n; i++)
    for (j = 1; j <= n; j++) {
      cin >> a[i][j];
      if (a[i][j] != '*') {
        a[i][j] -= 'a';
        e[i][a[i][j]].push_back(j);
      }
    }
  vis.insert(s);
  from[s] = s;
  d[s] = 0;
  he = ta = 0;
  q[ta++] = s;
  while (he < ta) {
    cur = q[he];
    x = cur;
    for (it = e[cur.a][a[cur.b][cur.c]].begin();
         it != e[cur.a][a[cur.b][cur.c]].end(); it++) {
      x = cur;
      x.a = *it;
      if (x.a == x.b) continue;
      if (x.a == x.c) continue;
      x = ok(x);
      if (vis.find(x) == vis.end()) {
        from[x] = cur;
        vis.insert(x);
        d[x] = d[cur] + 1;
        q[ta++] = x;
      }
    }
    for (it = e[cur.b][a[cur.a][cur.c]].begin();
         it != e[cur.b][a[cur.a][cur.c]].end(); it++) {
      x = cur;
      x.b = *it;
      if (x.a == x.b) continue;
      if (x.b == x.c) continue;
      x = ok(x);
      if (vis.find(x) == vis.end()) {
        from[x] = cur;
        vis.insert(x);
        d[x] = d[cur] + 1;
        q[ta++] = x;
      }
    }
    for (it = e[cur.c][a[cur.b][cur.a]].begin();
         it != e[cur.c][a[cur.b][cur.a]].end(); it++) {
      x = cur;
      x.c = *it;
      if (x.c == x.b) continue;
      if (x.a == x.c) continue;
      x = ok(x);
      if (vis.find(x) == vis.end()) {
        from[x] = cur;
        vis.insert(x);
        d[x] = d[cur] + 1;
        q[ta++] = x;
      }
    }
    he++;
  }
  stack<pair<int, int> > st;
  if (d.find(f) == d.end())
    cout << -1 << endl;
  else {
    cout << d.find(f)->second << endl;
    x = f;
    f = from[x];
    while (!(f == x)) {
      st.push(dif(f, x));
      x = f;
      f = from[x];
    }
    while (!st.empty()) {
      cout << st.top().first << " " << st.top().second << endl;
      st.pop();
    }
  }
  return 0;
}
