#include <bits/stdc++.h>
using namespace std;
const int maxn = 1100;
int n, m, A[maxn][maxn];
struct Tpair {
  int x, y;
  Tpair(int _x = 0, int _y = 0) { x = _x, y = _y; }
  inline bool operator<(const Tpair &b) const {
    return x != b.x ? x < b.x : y < b.y;
  }
};
vector<Tpair> B;
namespace Ninit {
char s[maxn];
void init() {
  int i, j;
  scanf("%d%d", &n, &m);
  for (i = 1; i <= n; ++i) {
    scanf("%s", s);
    for (j = 1; j <= m; ++j) {
      A[i][j] = (s[j - 1] == '.' ? 0 : 1);
      if (s[j - 1] == '#') B.push_back(Tpair(i, j));
    }
  }
}
}  // namespace Ninit
namespace Nsolve {
int Fx[maxn][maxn], Fy[maxn][maxn];
int Sx[maxn][maxn], Sy[maxn][maxn], Sn;
int Ux[maxn], Uy[maxn];
bool count(Tpair a, Tpair b) {
  int i;
  for (i = a.x; i <= b.x; ++i)
    if (!A[i][a.y] || !A[i][b.y]) return false;
  for (i = a.y + 1; i < b.y; ++i)
    if (!A[a.x][i] || !A[b.x][i]) return false;
  return true;
}
void cover(Tpair a, Tpair b, int v) {
  int i;
  for (i = a.x; i <= b.x; ++i) A[i][a.y] += v, A[i][b.y] += v;
  for (i = a.y + 1; i < b.y; ++i) A[a.x][i] += v, A[b.x][i] += v;
}
void print(Tpair a, Tpair b) { printf("%d %d %d %d\n", a.x, a.y, b.x, b.y); }
bool find() {
  int i, j;
  Sn = 0;
  vector<Tpair>::iterator p, q;
  memset(Ux, 0, sizeof Ux), memset(Uy, 0, sizeof Uy);
  for (p = B.begin(); p < B.end(); ++p)
    if (A[p->x][p->y] == 1) {
      ++Ux[p->x], Ux[0] += (Ux[p->x] == 3);
      ++Uy[p->y], Uy[0] += (Uy[p->y] == 3);
    }
  if (Ux[0] > 2 || Uy[0] > 2) return false;
  for (i = 1; i <= n; ++i)
    for (j = 1; j <= m; ++j)
      if (A[i][j] != 1)
        Sx[i][j] = Sy[i][j] = 0;
      else
        Sx[i][j] = Sy[i][j] = 1, ++Sn;
  for (i = 1; i <= n; ++i)
    for (j = 1; j <= m; ++j) Sx[i][j] += Sx[i][j - 1], Sy[i][j] += Sy[i - 1][j];
  for (p = B.begin(); p < B.end(); ++p)
    for (q = p + 1; q < B.end(); ++q)
      if (p->x + 1 < q->x && p->y + 1 < q->y) {
        if (Fx[p->x][q->y] < p->y && Fx[q->x][q->y] < p->y &&
            Fy[q->x][p->y] < p->x && Fy[q->x][q->y] < p->x &&
            Sx[p->x][q->y] - Sx[p->x][p->y - 1] + Sx[q->x][q->y] -
                    Sx[q->x][p->y - 1] + Sy[q->x - 1][p->y] - Sy[p->x][p->y] +
                    Sy[q->x - 1][q->y] - Sy[p->x][q->y] ==
                Sn)
          return printf("YES\n"), print(*p, *q), true;
      }
  return false;
}
void solve() {
  int i, j;
  vector<Tpair>::iterator p, q;
  if (B.size() > 4 * (n + m) || B.size() < 8) return printf("NO\n"), void();
  for (i = 1; i <= n; ++i)
    for (j = 1; j <= m; ++j)
      if (!A[i][j])
        Fx[i][j] = j, Fy[i][j] = i;
      else
        Fx[i][j] = Fx[i][j - 1], Fy[i][j] = Fy[i - 1][j];
  for (q = (p = B.begin()) + 1; q < B.end(); ++q)
    if (p->x + 1 < q->x && p->y + 1 < q->y) {
      if (!count(*p, *q)) continue;
      cover(*p, *q, 1);
      if (find()) return print(*p, *q), void();
      cover(*p, *q, -1);
    }
  printf("NO\n");
}
}  // namespace Nsolve
int main() {
  Ninit::init();
  Nsolve::solve();
  return 0;
}
