bfs
#include<iostream>
#include<cstring>
#include<string>
#include<queue>
using namespace std;
struct node {
int cp1;
int cp2;
int cp3;
};
int n;
int mx[51][51];
int vis[51][51][51];
vector<int> to[51][27];
int p1, p2, p3;
int ans;
void init() {
memset(vis, 0, sizeof(vis));
for (int i = 1; i <= n; i++) {
for (int j = 0; j <= 26; j++) {
to[i][j].clear();
}
}
}
void build() {
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
to[i][mx[i][j]].push_back(j);
}
}
}
bool bfs() {
node sta = {p1, p2, p3};
vis[p1][p2][p3] = 1;
queue<node> q;
q.push(sta);
vector<int> v;
int coun = 0;
while (!q.empty()) {
int x = q.size();
for (int i = 0; i < x; i++) {
node nd = q.front();
q.pop();
int c1 = nd.cp1;
int c2 = nd.cp2;
int c3 = nd.cp3;
if(c1==c2 && c1==c3){
ans=coun;
return true;
}
//move c1
int color23 = mx[c2][c3];
v = to[c1][color23];
for (int i = 0; i < v.size(); i++) {
if (!vis[v[i]][c2][c3]) {
vis[v[i]][c2][c3] = 1;
node nnd = {v[i], c2, c3};
q.push(nnd);
}
}
//move c2
int color13 = mx[c1][c3];
v = to[c2][color13];
for (int i = 0; i < v.size(); i++) {
if (!vis[c1][v[i]][c3]) {
vis[c1][v[i]][c3] = 1;
node nnd = {c1, v[i], c3};
q.push(nnd);
}
}
//move c3
int color12 = mx[c1][c2];
v = to[c3][color12];
for (int i = 0; i < v.size(); i++) {
if (!vis[c1][c2][v[i]]) {
vis[c1][c2][v[i]] = 1;
node nnd = {c1, c2, v[i]};
q.push(nnd);
}
}
}
coun++;
}
return false;
}
int main() {
char ch;
while (scanf("%d", &n) && n) {
scanf("%d%d%d", &p1, &p2, &p3);
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= n; j++) {
cin >> ch;
mx[i][j] = (int)(ch - 'a');
}
}
if (p1 == p2 && p1 == p3) {
printf("0\n");
continue;
}
init();
build();
if(bfs()){
printf("%d\n",ans);
}else {
printf("impossible\n");
}
}
}