#include <bits/stdc++.h>
using namespace std;
const int iinf = 1e9 + 7;
const long long linf = 1ll << 60;
const double dinf = 1e10;
void scf(int &x) {
  bool f = 0;
  x = 0;
  char c = getchar();
  while ((c < '0' || c > '9') && c != '-') c = getchar();
  if (c == '-') {
    f = 1;
    c = getchar();
  }
  while (c >= '0' && c <= '9') {
    x = x * 10 + c - '0';
    c = getchar();
  }
  if (f) x = -x;
  return;
}
void scf(int &x, int &y) {
  scf(x);
  return scf(y);
}
void scf(int &x, int &y, int &z) {
  scf(x);
  scf(y);
  return scf(z);
}
const int N = 1010;
int n, m;
short mx[N][N][11][11];
int lg2[N];
bool num[N][N];
short cnt[N][N];
short u[N][N], l[N][N];
inline short MIN(short a, short b) { return a < b ? a : b; }
inline short MAX(short a, short b) { return a > b ? a : b; }
void init() {
  int lst = 1, cur = 1, cnt = 1;
  lg2[1] = 0;
  while (cur < 1000) {
    cur <<= 1;
    if (cur > 1000) cur = 1000;
    for (int i = lst + 1; i <= cur; i++) lg2[i] = cnt;
    cnt++;
    lst = cur;
  }
}
inline short query(int x1, int y1, int x2, int y2) {
  int l1 = x2 - x1 + 1, l2 = y2 - y1 + 1;
  l1 = lg2[l1], l2 = lg2[l2];
  if (!l1 && !l2) return mx[x2][y2][l1][l2];
  if (!l1)
    return MAX(mx[x2][y2][l1][l2 - 1],
               mx[x2][y1 + (1 << l2 - 1) - 1][l1][l2 - 1]);
  if (!l2)
    return MAX(mx[x2][y2][l1 - 1][l2],
               mx[x1 + (1 << l1 - 1) - 1][y2][l1 - 1][l2]);
  return MAX(
      MAX(mx[x2][y2][l1 - 1][l2 - 1],
          mx[x1 + (1 << l1 - 1) - 1][y2][l1 - 1][l2 - 1]),
      MAX(mx[x2][y1 + (1 << l2 - 1) - 1][l1 - 1][l2 - 1],
          mx[x1 + (1 << l1 - 1) - 1][y1 + (1 << l2 - 1) - 1][l1 - 1][l2 - 1]));
}
int main() {
  init();
  scf(n, m);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= m; j++) {
      char c = getchar();
      while (c != '0' && c != '1') c = getchar();
      num[i][j] = (c == '1');
      if (num[i][j]) u[i][j] = u[i - 1][j] + 1, l[i][j] = l[i][j - 1] + 1;
      cnt[i][j] = MIN(u[i][j], l[i][j]);
      cnt[i][j] = MIN(cnt[i - 1][j - 1] + 1, cnt[i][j]);
    }
  for (int i = 0; i <= 10; i++)
    for (int j = 0; j <= 10; j++) {
      int L1 = 1 << i, L2 = 1 << j, l1 = L1 >> 1, l2 = L2 >> 1;
      for (int x = L1; x <= n; x++)
        for (int y = L2; y <= m; y++) {
          if (!i && !j)
            mx[x][y][i][j] = cnt[x][y];
          else if (!i)
            mx[x][y][i][j] = MAX(mx[x][y][i][j - 1], mx[x][y - l2][i][j - 1]);
          else if (!j)
            mx[x][y][i][j] = MAX(mx[x][y][i - 1][j], mx[x - l1][y][i - 1][j]);
          else
            mx[x][y][i][j] =
                MAX(MAX(mx[x][y][i - 1][j - 1], mx[x - l1][y][i - 1][j - 1]),
                    MAX(mx[x][y - l2][i - 1][j - 1],
                        mx[x - l1][y - l2][i - 1][j - 1]));
        }
    }
  int q;
  scf(q);
  while (q--) {
    int x1, y1, x2, y2;
    scf(x1, y1);
    scf(x2, y2);
    short l = 1, r = MIN(x2 - x1 + 1, y2 - y1 + 1);
    while (l <= r) {
      short mid = l + r >> 1;
      if (query(x1 + mid - 1, y1 + mid - 1, x2, y2) >= mid)
        l = mid + 1;
      else
        r = mid - 1;
    }
    printf("%d\n", (int)r);
  }
  return 0;
}
