#include <bits/stdc++.h>
using namespace std;
using namespace rel_ops;
using ll = int64_t;
using Pii = pair<int, int>;
using ull = uint64_t;
using Vi = vector<int>;
void run();
int main() {
  cin.sync_with_stdio(0);
  cin.tie(0);
  cout << fixed << setprecision(10);
  run();
  return 0;
}
int uplg(int n) { return 32 - __builtin_clz(n); }
int uplg(ll n) { return 64 - __builtin_clzll(n); }
struct Vert {
  int ver{-1};
  int defPar{-1}, par;
  bool defBlocked{1}, blocked;
};
int hei, wid, nQuestions;
vector<Vert> G;
set<Pii> permEdges, tempEdges;
int currentVer = 1;
void update(int i) {
  if (G[i].ver != currentVer) {
    G[i].ver = currentVer;
    G[i].par = G[i].defPar;
    G[i].blocked = G[i].defBlocked;
  }
}
int find(int i) {
  update(i);
  if (G[i].par == -1) return i;
  return G[i].par = find(G[i].par);
}
int join(int i, int j) {
  i = find(i);
  j = find(j);
  if (i == j) return i;
  if (rand() % 2) swap(i, j);
  return G[i].par = j;
}
int ind(int first, int second) { return first * wid + second; }
Vert& vert(int i) {
  update(i);
  return G[i];
}
Vert& vert(int first, int second) { return vert(ind(first, second)); }
void eachNeigh(int i, int j, function<void(int, int)> func) {
  for (int dx = (-1); dx < (2); dx++)
    for (int dy = (-1); dy < (2); dy++)
      if (dx != 0 || dy != 0) {
        int first = i + dx, second = j + dy;
        if (first >= 0 && second >= 0 && first < hei && second < wid) {
          func(first, second);
        }
      }
}
void addEdges(int i, int j) {
  assert(vert(i, j).blocked);
  eachNeigh(i, j, [&](int first, int second) {
    if (vert(first, second).blocked) return;
    eachNeigh(first, second, [&](int a, int b) {
      if (vert(a, b).blocked) {
        int p1 = find(ind(i, j)), p2 = find(ind(a, b));
        tempEdges.insert({p1, p2});
        tempEdges.insert({p2, p1});
      }
    });
  });
}
void query() {
  int k;
  cin >> k;
  vector<Pii> toBlock(k);
  for (auto& p : (toBlock)) cin >> p.first >> p.second;
  Vi toCheck;
  currentVer++;
  tempEdges.clear();
  for (auto& p : (toBlock)) {
    vert(p.first, p.second).blocked = 1;
    toCheck.push_back(find(ind(p.first, p.second)));
    eachNeigh(p.first, p.second, [&](int i, int j) {
      if (vert(i, j).blocked) {
        toCheck.push_back(find(ind(i, j)));
        join(ind(i, j), ind(p.first, p.second));
      }
    });
    addEdges(p.first, p.second);
    toCheck.push_back(find(ind(p.first, p.second)));
    eachNeigh(p.first, p.second, [&](int i, int j) {
      if (vert(i, j).blocked) {
        toCheck.push_back(find(ind(i, j)));
      }
    });
  }
  int top = find(ind(0, 3)), bottom = find(ind(3, 0));
  toCheck.push_back(top);
  toCheck.push_back(bottom);
  for (auto& i : (toCheck))
    if (find(i) == top) {
      for (auto& j : (toCheck))
        if (find(j) == bottom) {
          if (permEdges.count({i, j}) || tempEdges.count({i, j})) {
            cout << "NO" << endl;
            return;
          }
        }
    }
  cout << "YES" << endl;
}
void run() {
  cin >> hei >> wid >> nQuestions;
  hei += 2;
  wid += 2;
  G.resize(hei * wid);
  for (int i = (0); i < (3); i++) {
    vert(i, 0).defBlocked = vert(0, i).defBlocked = 0;
    vert(hei - i - 1, wid - 1).defBlocked =
        vert(hei - 1, wid - i - 1).defBlocked = 0;
  }
  for (int i = (1); i < (hei - 1); i++) {
    string tmp;
    cin >> tmp;
    for (int j = (1); j < (wid - 1); j++)
      vert(i, j).defBlocked = (tmp[j - 1] == '#');
  }
  for (int first = (0); first < (hei); first++)
    for (int second = (0); second < (wid); second++) {
      auto& cur = vert(first, second);
      if (!cur.defBlocked) continue;
      eachNeigh(first, second, [&](int i, int j) {
        if (vert(i, j).defBlocked) {
          join(ind(first, second), ind(i, j));
        }
      });
    }
  for (auto& v : (G)) v.defPar = v.par;
  currentVer++;
  for (int i = (0); i < (hei); i++)
    for (int j = (0); j < (wid); j++) {
      auto& cur = vert(i, j);
      if (cur.defBlocked) addEdges(i, j);
    }
  swap(tempEdges, permEdges);
  while (nQuestions--) query();
}
