#include <bits/stdc++.h>
using namespace std;
int X, Y, BLACK;
char a[1010][1010];
vector<int> vx, vy;
bool used[1010][1010];
int put_rect(int x1, int y1, int x2, int y2) {
  int x, y, ans = 0;
  for (y = y1; y <= y2; y++) {
    if (a[x1][y] == '.') return -1;
    if (!used[x1][y]) {
      used[x1][y] = true;
      ans++;
    }
    if (a[x2][y] == '.') return -1;
    if (!used[x2][y]) {
      used[x2][y] = true;
      ans++;
    }
  }
  for (x = x1 + 1; x < x2; x++) {
    if (a[x][y1] == '.') return -1;
    if (!used[x][y1]) {
      used[x][y1] = true;
      ans++;
    }
    if (a[x][y2] == '.') return -1;
    if (!used[x][y2]) {
      used[x][y2] = true;
      ans++;
    }
  }
  return ans;
}
void remove_rect(int x1, int y1, int x2, int y2) {
  int x, y;
  for (y = y1; y <= y2; y++) used[x1][y] = used[x2][y] = false;
  for (x = x1 + 1; x < x2; x++) used[x][y1] = used[x][y2] = false;
}
bool check(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
  int z1 = put_rect(x1, y1, x2, y2);
  remove_rect(x1, y1, x2, y2);
  if (z1 != (x2 - x1 + y2 - y1) * 2) return false;
  int z2 = put_rect(x3, y3, x4, y4);
  remove_rect(x3, y3, x4, y4);
  if (z2 != (x4 - x3 + y4 - y3) * 2) return false;
  int z3 = put_rect(x1, y1, x2, y2);
  z3 += put_rect(x3, y3, x4, y4);
  remove_rect(x1, y1, x2, y2);
  remove_rect(x3, y3, x4, y4);
  if (z3 != BLACK) return false;
  return true;
}
bool check2(int x1, int y1, int x2, int y2, int x3, int y3, int x4, int y4) {
  int p[] = {x1, x2, x3, x4}, q[] = {y1, y2, y3, y4};
  sort(p, p + 4);
  sort(q, q + 4);
  do {
    do {
      if (p[1] - p[0] >= 2 && q[1] - q[0] >= 2 && p[3] - p[2] >= 2 &&
          q[3] - q[2] >= 2 && p[2] >= p[0]) {
        bool ans = check(p[0], q[0], p[1], q[1], p[2], q[2], p[3], q[3]);
        if (ans) {
          cout << "YES" << endl;
          printf("%d %d %d %d\n", p[0] + 1, q[0] + 1, p[1] + 1, q[1] + 1);
          printf("%d %d %d %d\n", p[2] + 1, q[2] + 1, p[3] + 1, q[3] + 1);
          return true;
        }
      }
    } while (next_permutation(q, q + 4));
  } while (next_permutation(p, p + 4));
  return false;
}
vector<vector<int> > generate(vector<int> v, set<int> s) {
  vector<vector<int> > ans;
  if (v.size() == 4) {
    ans.push_back(v);
    return ans;
  }
  if (v.size() == 3) {
    for (__typeof((s).begin()) itr = (s).begin(); itr != (s).end(); itr++) {
      vector<int> w = v;
      w.push_back(*itr);
      ans.push_back(w);
    }
    return ans;
  }
  for (__typeof((s).begin()) itr1 = (s).begin(); itr1 != (s).end(); itr1++)
    for (__typeof((s).begin()) itr2 = (s).begin(); itr2 != (s).end(); itr2++) {
      if ((*itr1) > (*itr2)) continue;
      vector<int> w = v;
      w.push_back(*itr1);
      w.push_back(*itr2);
      ans.push_back(w);
    }
  return ans;
}
int main(void) {
  int i, j;
  scanf("%d%d", &X, &Y);
  for ((i) = 0; (i) < (int)(X); (i)++) scanf("%s", a[i]);
  for ((i) = 0; (i) < (int)(X); (i)++) {
    int cnt = 0;
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (a[i][j] == '#') cnt++;
    bool flag = (cnt >= 5);
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (a[i][j] == '#')
        if (i - 1 < 0 || a[i - 1][j] == '.') flag = true;
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (a[i][j] == '#')
        if (i + 1 >= X || a[i + 1][j] == '.') flag = true;
    if (flag) vx.push_back(i);
  }
  for ((j) = 0; (j) < (int)(Y); (j)++) {
    int cnt = 0;
    for ((i) = 0; (i) < (int)(X); (i)++)
      if (a[i][j] == '#') cnt++;
    bool flag = (cnt >= 5);
    for ((i) = 0; (i) < (int)(X); (i)++)
      if (a[i][j] == '#')
        if (j - 1 < 0 || a[i][j - 1] == '.') flag = true;
    for ((i) = 0; (i) < (int)(X); (i)++)
      if (a[i][j] == '#')
        if (j + 1 >= Y || a[i][j + 1] == '.') flag = true;
    if (flag) vy.push_back(j);
  }
  for ((i) = 0; (i) < (int)(X); (i)++)
    for ((j) = 0; (j) < (int)(Y); (j)++)
      if (a[i][j] == '#') BLACK++;
  if (vx.size() < 2 || vx.size() > 4 || vy.size() < 2 || vy.size() > 4) {
    cout << "NO" << endl;
    return 0;
  }
  set<int> sx, sy;
  for ((i) = 0; (i) < (int)(vx.size()); (i)++)
    for (j = -2; j <= 2; j++) {
      int x = vx[i] + j;
      if (x >= vx[0] && x <= vx[vx.size() - 1]) sx.insert(x);
    }
  for ((i) = 0; (i) < (int)(vy.size()); (i)++)
    for (j = -2; j <= 2; j++) {
      int y = vy[i] + j;
      if (y >= vy[0] && y <= vy[vy.size() - 1]) sy.insert(y);
    }
  vector<vector<int> > xcand = generate(vx, sx);
  vector<vector<int> > ycand = generate(vy, sy);
  for ((i) = 0; (i) < (int)(xcand.size()); (i)++)
    for ((j) = 0; (j) < (int)(ycand.size()); (j)++) {
      vector<int> vx2 = xcand[i];
      vector<int> vy2 = ycand[j];
      if (check2(vx2[0], vy2[0], vx2[1], vy2[1], vx2[2], vy2[2], vx2[3],
                 vy2[3]))
        return 0;
    }
  cout << "NO" << endl;
  return 0;
}
