#include <bits/stdc++.h>
using namespace std;
template <typename T, typename NT = T>
class Graph {
 public:
  struct EDGE {
    int to;
    T val;
    EDGE() {}
    EDGE(int TO, T V) { to = TO, val = V; }
  };
  int n;
  vector<vector<EDGE> > g;
  Graph() {}
  Graph(int N) { init(N); }
  inline void add(int x, int y, T v = 1) { g[x].push_back(EDGE(y, v)); }

 private:
  void init(int N) {
    n = N;
    g.clear();
    g.resize(N + 1);
  }

 protected:
  bool equalT(const T &x, const T &y) const { return (!(x < y)) && (!(y < x)); }
};
namespace santongding {
Graph<int> G;
int n, m, k;
short v[1005][1005];
int getid(int x, int y) { return (x - 1) * m + y; }
int getid(int x) { return n * m + x; }
bool check(int x, int y) { return x >= 1 && x <= n && y >= 1 && y <= m; }
short d[41][1005 * 1005];
int fx[] = {1, 0};
int fy[] = {0, 1};
void getshortest(int);
int Abs(int x) { return x < 0 ? -x : x; }
void solve() {
  scanf("%d%d%d", &n, &m, &k);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) scanf("%d", &v[i][j]);
  }
  G = Graph<int>(n * m + k);
  for (int i = 1; i <= n; i++) {
    for (int j = 1; j <= m; j++) {
      G.add(getid(i, j), getid(v[i][j]), 1);
      G.add(getid(v[i][j]), getid(i, j), 1);
      for (int p = 0; p < 2; p++) {
        int nx = i + fx[p];
        int ny = j + fy[p];
        if (check(nx, ny)) {
          G.add(getid(i, j), getid(nx, ny), 2);
          G.add(getid(nx, ny), getid(i, j), 2);
        }
      }
    }
  }
  for (int i = 1; i <= k; i++) getshortest(i);
  int q;
  scanf("%d", &q);
  while (q--) {
    int sx, sy, tx, ty;
    scanf("%d%d%d%d", &sx, &sy, &tx, &ty);
    int ans = Abs(tx - sx) + Abs(ty - sy);
    for (int i = 1; i <= k; i++) {
      if (d[i][getid(sx, sy)] != -1 && d[i][getid(tx, ty)] != -1) {
        ans = min(ans, (d[i][getid(tx, ty)] + d[i][getid(sx, sy)]) / 2);
      }
    }
    printf("%d\n", ans);
  }
}
void getshortest(int col) {
  vector<pair<int, bool> > Q;
  memset(d[col], -1, sizeof(d[col]));
  short *dp = d[col];
  int s = getid(col);
  dp[s] = 0;
  Q.push_back(make_pair(s, true));
  for (int i = 0; i < Q.size(); i++) {
    int x = Q[i].first;
    if (!Q[i].second) {
      Q.push_back(make_pair(x, true));
      continue;
    }
    for (auto e : G.g[x]) {
      if (dp[e.to] == -1) {
        Q.push_back(make_pair(e.to, e.val == 1));
        dp[e.to] = dp[x] + e.val;
      }
    }
  }
}
}  // namespace santongding
int main() {
  int t = 1;
  while (t--) {
    santongding::solve();
  }
}
