#include <bits/stdc++.h>
using namespace std;
const int N = 510, M = 6e5 + 10;
int n, m;
int ans[M];
char s[N][N];
bitset<N> f[2][N][N];
struct query {
  int id;
  int x1, y1;
  int x2, y2;
} que[M], tmp[M];
inline void dfs(int l, int r, int ql, int qr) {
  if (l > r || ql > qr) return;
  int mid = (l + r) / 2;
  for (int i = m; i >= 1; i--) {
    f[0][mid][i].reset();
    if (s[mid][i] != '.') continue;
    f[0][mid][i].set(i);
    if (i < m) f[0][mid][i] |= f[0][mid][i + 1];
  }
  for (int i = 1; i <= m; i++) {
    f[1][mid][i].reset();
    if (s[mid][i] != '.') continue;
    f[1][mid][i].set(i);
    if (i > 1) f[1][mid][i] |= f[1][mid][i - 1];
  }
  for (int i = mid - 1; i >= l; i--) {
    for (int j = m; j >= 1; j--) {
      f[0][i][j].reset();
      if (s[i][j] != '.') continue;
      if (j < m) f[0][i][j] |= f[0][i][j + 1];
      f[0][i][j] |= f[0][i + 1][j];
    }
  }
  for (int i = mid + 1; i <= r; i++) {
    for (int j = 1; j <= m; j++) {
      f[1][i][j].reset();
      if (s[i][j] != '.') continue;
      if (j > 1) f[1][i][j] |= f[1][i][j - 1];
      f[1][i][j] |= f[1][i - 1][j];
    }
  }
  int cnt1 = ql - 1, cnt2 = qr + 1;
  for (int i = ql; i <= qr; i++) {
    if (que[i].x2 < mid) {
      tmp[++cnt1] = que[i];
      continue;
    }
    if (que[i].x1 > mid) {
      tmp[--cnt2] = que[i];
      continue;
    }
    ans[que[i].id] =
        (f[0][que[i].x1][que[i].y1] & f[1][que[i].x2][que[i].y2]).any();
  }
  for (int i = ql; i <= cnt1; i++) que[i] = tmp[i];
  for (int i = qr; i >= cnt2; i--) que[i] = tmp[i];
  dfs(l, mid - 1, ql, cnt1), dfs(mid + 1, r, cnt2, qr);
}
int main() {
  int Q;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%s", s[i] + 1);
  scanf("%d", &Q);
  for (int i = 1; i <= Q; i++)
    scanf("%d%d%d%d", &que[i].x1, &que[i].y1, &que[i].x2, &que[i].y2),
        que[i].id = i;
  dfs(1, n, 1, Q);
  for (int i = 1; i <= Q; i++) {
    if (ans[i])
      printf("Yes\n");
    else
      printf("No\n");
  }
  return 0;
}
