#include <bits/stdc++.h>
using namespace std;
using int64 = long long int;
vector<vector<int>> ComputeStars(const vector<string>& field) {
  const int n = field.size();
  const int m = field[0].size();
  vector<vector<int>> up(n, vector<int>(m));
  vector<vector<int>> left(n, vector<int>(m));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      up[i][j] = (field[i][j] == '*' ? ((i > 0 ? up[i - 1][j] : 0) + 1) : 0);
      left[i][j] =
          (field[i][j] == '*' ? ((j > 0 ? left[i][j - 1] : 0) + 1) : 0);
    }
  }
  vector<vector<int>> down(n, vector<int>(m));
  vector<vector<int>> right(n, vector<int>(m));
  for (int i = n - 1; i >= 0; --i) {
    for (int j = m - 1; j >= 0; --j) {
      down[i][j] =
          (field[i][j] == '*' ? ((i < n - 1 ? down[i + 1][j] : 0) + 1) : 0);
      right[i][j] =
          (field[i][j] == '*' ? ((j < m - 1 ? right[i][j + 1] : 0) + 1) : 0);
    }
  }
  vector<vector<int>> result(n, vector<int>(m));
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      result[i][j] = min({left[i][j], right[i][j], up[i][j], down[i][j]});
    }
  }
  return result;
}
bool Covers(const vector<vector<int>>& stars, const vector<string>& field) {
  const int n = field.size();
  const int m = field[0].size();
  vector<vector<bool>> covered(n, vector<bool>(m));
  for (int i = 0; i < n; ++i) {
    int covered_until = 0;
    for (int j = 0; j < m; ++j) {
      const int k = stars[i][j];
      if (k > 1) {
        for (int u = max(j, covered_until); u < j + k; ++u) {
          covered[i][u] = true;
        }
        covered_until = max(covered_until, j + k);
      }
    }
    covered_until = m;
    for (int j = m - 1; j >= 0; --j) {
      const int k = stars[i][j];
      if (k > 1) {
        for (int u = j - k + 1; u <= min(j, covered_until); ++u) {
          covered[i][u] = true;
        }
        covered_until = min(covered_until, j - k);
      }
    }
  }
  for (int j = 0; j < m; ++j) {
    int covered_until = 0;
    for (int i = 0; i < n; ++i) {
      const int k = stars[i][j];
      if (k > 1) {
        for (int u = max(i, covered_until); u < i + k; ++u) {
          covered[u][j] = true;
        }
        covered_until = max(covered_until, i + k);
      }
    }
    covered_until = n;
    for (int i = n - 1; i >= 0; --i) {
      const int k = stars[i][j];
      if (k > 1) {
        for (int u = i - k + 1; u <= min(i, covered_until); ++u) {
          covered[u][j] = true;
        }
        covered_until = min(covered_until, i - k);
      }
    }
  }
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (field[i][j] == '*' && !covered[i][j]) {
        return false;
      }
    }
  }
  return true;
}
void solve() {
  int n, m;
  cin >> n >> m;
  vector<string> field(n);
  for (int i = 0; i < n; ++i) {
    cin >> field[i];
  }
  const vector<vector<int>> stars = ComputeStars(field);
  if (!Covers(stars, field)) {
    cout << "-1\n";
    return;
  }
  int count = 0;
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (field[i][j] == '*' && stars[i][j] > 1) {
        ++count;
      }
    }
  }
  cout << count << "\n";
  for (int i = 0; i < n; ++i) {
    for (int j = 0; j < m; ++j) {
      if (field[i][j] == '*' && stars[i][j] > 1) {
        cout << (i + 1) << " " << (j + 1) << " " << (stars[i][j] - 1) << "\n";
      }
    }
  }
}
int main() {
  solve();
  return 0;
}
