int N, M; while (cin >> N >> M) { if (N == 0 && M == 0) break;
vector<vector<int>> mats(N, vector<int>(M * M)); for (int i = 0; i < N; ++i) { for (int r = 0; r < M; ++r) { for (int c = 0; c < M; ++c) { cin >> mats[i][r * M + c]; } } }
unordered_map<pair<unsignedlonglong, unsignedlonglong>, vector<int>, HashPair> pos; pos.reserve(N * 2 + 1); for (int i = 0; i < N; ++i) { pos[hashMatrix(mats[i])].push_back(i); }
vector<vector<int>> dist(N, vector<int>(N, INF)); for (int i = 0; i < N; ++i) dist[i][i] = 0;
vector<int> prod(M * M, 0);
for (int i = 0; i < N; ++i) { for (int j = 0; j < N; ++j) { if (j == i) continue; // A 和 B 不能是同一个城市 bool valid = true;
for (int r = 0; r < M && valid; ++r) { for (int c = 0; c < M; ++c) { int sum = 0; for (int t = 0; t < M; ++t) { sum += mats[i][r * M + t] * mats[j][t * M + c]; if (sum > 80) { valid = false; break; } } if (!valid) break; prod[r * M + c] = sum; } }
if (!valid) continue;
auto key = hashMatrix(prod); auto it = pos.find(key); if (it == pos.end()) continue;
for (int k : it->second) { if (k == i || k == j) continue; // A、B、C 下标两两不同 if (mats[k] == prod) { dist[i][k] = 1; } } } }
for (int k = 0; k < N; ++k) { for (int i = 0; i < N; ++i) { if (dist[i][k] == INF) continue; for (int j = 0; j < N; ++j) { if (dist[k][j] == INF) continue; dist[i][j] = min(dist[i][j], dist[i][k] + dist[k][j]); } } }
int K; cin >> K; while (K--) { int X, Y; cin >> X >> Y; --X; --Y; if (dist[X][Y] == INF) cout << "Sorry\n"; else cout << dist[X][Y] << '\n'; } }