#include <bits/stdc++.h>
using namespace std;
struct FastIO {
  template <typename T>
  FastIO& operator>>(T& x) {
    char c, l;
    for (c = 0; !isdigit(c); c = getchar()) l = c;
    for (x = 0; isdigit(c); c = getchar()) x = x * 10 - '0' + c;
    if (l == '-') x = -x;
    return *this;
  }
} IO;
const int MX = 510, MY = 610000;
struct Query {
  int x, y, nx, ans;
} E[MY];
int H[MX][MX], ec;
void Add(int xa, int ya, int xb, int yb) {
  E[++ec].x = xa, E[ec].y = ya, E[ec].nx = H[xb][yb], H[xb][yb] = ec;
}
int N, M, Q;
char S[MX][MX];
struct Bitset {
  unsigned long long x[MX][8];
  void set(int i, int j) { x[i][((j) >> 6)] |= 1ull << ((j)&63); }
  int get(int i, int j) { return (x[i][((j) >> 6)] >> ((j)&63)) & 1; }
  void clear() { memset(x, 0, sizeof(x)); }
} B[2][MX];
void Merge(Bitset& c, Bitset& a, Bitset& b, int n, int m) {
  int m_ = ((m) >> 6);
  for (int i = (1); i <= (n); ++i)
    for (int j = (0); j <= (m_); ++j) c.x[i][j] = a.x[i][j] | b.x[i][j];
}
void Solve() {
  Bitset *a = B[0], *b = B[1];
  for (int i = (1); i <= (N); ++i) {
    for (int j = (1); j <= (M); ++j) {
      if (S[i][j] == '#')
        b[j].clear();
      else
        Merge(b[j], a[j], b[j - 1], i, j), b[j].set(i, j);
      for (int k = H[i][j]; k; k = E[k].nx) E[k].ans = b[j].get(E[k].x, E[k].y);
    }
    swap(a, b);
  }
}
int main() {
  IO >> N >> M;
  for (int i = (1); i <= (N); ++i) scanf("%s", S[i] + 1);
  IO >> Q;
  int xa, ya, xb, yb;
  for (int i = (1); i <= (Q); ++i) {
    IO >> xa >> ya >> xb >> yb;
    Add(xa, ya, xb, yb);
  }
  Solve();
  for (int i = (1); i <= (Q); ++i) printf(E[i].ans ? "Yes\n" : "No\n");
  return 0;
}
