#include <bits/stdc++.h>
using namespace std;
short dp[1123][1123];
short board[1123][1123];
short st[1010][1010][11][11];
int ptwo[31], x[1010];
int read();
void write(int);
inline short query(int X1, int Y1, int X2, int Y2) {
  int t1(x[X2 - X1 + 1]), t2(x[Y2 - Y1 + 1]);
  return max(
      max(st[X1][Y1][t1][t2], st[X2 - ptwo[t1] + 1][Y2 - ptwo[t2] + 1][t1][t2]),
      max(st[X1][Y2 - ptwo[t2] + 1][t1][t2],
          st[X2 - ptwo[t1] + 1][Y1][t1][t2]));
}
int main() {
  for (int i(0); i < 31; ++i) ptwo[i] = 1 << i;
  for (int i(1); i <= 1000; ++i) {
    int tmp(0);
    while (ptwo[tmp] <= i) ++tmp;
    x[i] = tmp - 1;
  }
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i(1); i <= n; ++i) {
    for (int j(1); j <= m; ++j) {
      char ch(getchar());
      while (ch != '0' && ch != '1') ch = getchar();
      board[i][j] = ch - '0';
    }
  }
  for (int i(1); i <= n; ++i) {
    for (int j(1); j <= m; ++j) {
      if (board[i][j])
        dp[i][j] = min(min(dp[i][j - 1], dp[i - 1][j]), dp[i - 1][j - 1]) + 1;
      st[i][j][0][0] = dp[i][j];
    }
  }
  for (int i(1); i <= n; ++i) {
    for (int k(1); k <= 10; ++k) {
      for (int j(1); j <= m; ++j) {
        st[i][j][0][k] = st[i][j][0][k - 1];
        if (j + ptwo[k] - 1 <= m) {
          st[i][j][0][k] =
              max(st[i][j][0][k], st[i][j + ptwo[k - 1]][0][k - 1]);
        }
      }
    }
  }
  for (int i(1); i <= m; ++i) {
    for (int k(1); k <= 10; ++k) {
      for (int j(1); j <= n; ++j) {
        st[j][i][k][0] = st[j][i][k - 1][0];
        if (j + ptwo[k] - 1 <= n) {
          st[j][i][k][0] =
              max(st[j][i][k][0], st[j + ptwo[k - 1]][i][k - 1][0]);
        }
      }
    }
  }
  for (int k(1); k <= 10; ++k) {
    for (int t(1); t <= 10; ++t) {
      for (int i(1); i <= n; ++i) {
        for (int j(1); j <= m; ++j) {
          st[i][j][k][t] = max(st[i][j][k - 1][t], st[i][j][k][t - 1]);
          if (i + ptwo[k] - 1 <= n) {
            st[i][j][k][t] =
                max(st[i][j][k][t], st[i + ptwo[k - 1]][j][k - 1][t]);
          }
          if (j + ptwo[t] - 1 <= m) {
            st[i][j][k][t] =
                max(st[i][j][k][t], st[i][j + ptwo[t - 1]][k][t - 1]);
          }
        }
      }
    }
  }
  int q;
  q = read();
  while (q--) {
    int x1(read()), t1(read()), x2(read()), t2(read());
    int l(1), r(min(x2 - x1, t2 - t1) + 1), ans(0);
    while (l <= r) {
      int mid((l + r) >> 1);
      if (query(x1 + mid - 1, t1 + mid - 1, x2, t2) >= mid) {
        ans = mid;
        l = mid + 1;
      } else {
        r = mid - 1;
      }
    }
    write(ans);
  }
  return 0;
}
inline void write(int x) {
  static char box[20];
  if (x == 0) {
    putchar('0');
    putchar('\n');
    return;
  }
  int pos(0);
  while (x) {
    box[pos] = x % 10 + '0';
    x /= 10;
    ++pos;
  }
  for (pos = pos - 1; pos >= 0; --pos) putchar(box[pos]);
  putchar('\n');
}
inline char getc() {
  static char buf[1 << 12], *p1 = buf, *p2 = buf;
  return (p1 == p2) &&
                 (p2 = (p1 = buf) + fread(buf, 1, 1 << 12, stdin), p1 == p2)
             ? EOF
             : *p1++;
}
inline int read() {
  static int x;
  x = 0;
  char ch(getc());
  while (ch < '0' || ch > '9') {
    ch = getc();
  }
  while (ch >= '0' && ch <= '9') {
    x = (x << 1) + (x << 3) + ch - '0';
    ch = getc();
  }
  return x;
}
