#include <bits/stdc++.h>
using namespace std;
int pre_row[1010][1010];
int pre_col[1010][1010];
int post_row[1010][1010];
int post_col[1010][1010];
int arr[1010][1010];
int lazy1[1010 * 3][1010 * 3];
int lazy2[1010 * 3][1010 * 3];
int ans[1010][1010];
vector<pair<int, pair<int, int> > > v;
void push_down_row(int i, int node) {
  lazy1[i][2 * node] += lazy1[i][node];
  lazy1[i][2 * node + 1] += lazy1[i][node];
  lazy1[i][node] = 0;
}
void push_down_col(int i, int node) {
  lazy2[2 * node][i] += lazy2[node][i];
  lazy2[2 * node + 1][i] += lazy2[node][i];
  lazy2[node][i] = 0;
}
void update_row(int node, int i, int l, int r, int p, int q, int val) {
  if (r < p || q < l) return;
  if (l >= p && r <= q) {
    lazy1[i][node]++;
    return;
  }
  if (lazy1[i][node]) push_down_row(i, node);
  update_row(2 * node, i, l, (l + r) / 2, p, q, val);
  update_row(2 * node + 1, i, (l + r) / 2 + 1, r, p, q, val);
}
void update_col(int node, int i, int l, int r, int p, int q, int val) {
  if (r < p || q < l) return;
  if (l >= p && r <= q) {
    lazy2[node][i]++;
    return;
  }
  if (lazy2[node][i]) push_down_col(i, node);
  update_col(2 * node, i, l, (l + r) / 2, p, q, val);
  update_col(2 * node + 1, i, (l + r) / 2 + 1, r, p, q, val);
}
void query_row(int node, int i, int l, int r) {
  if (l == r) {
    ans[i][l] += lazy1[i][node];
    return;
  }
  if (lazy1[i][node]) push_down_row(i, node);
  query_row(2 * node, i, l, (l + r) / 2);
  query_row(2 * node + 1, i, (l + r) / 2 + 1, r);
}
void query_col(int node, int i, int l, int r) {
  if (l == r) {
    ans[l][i] += lazy2[node][i];
    return;
  }
  if (lazy2[node][i]) push_down_col(i, node);
  query_col(2 * node, i, l, (l + r) / 2);
  query_col(2 * node + 1, i, (l + r) / 2 + 1, r);
}
int main() {
  int r, c;
  scanf("%d %d", &r, &c);
  for (int i = 1; i <= r; i++) {
    char p;
    for (int j = 1; j <= c; j++) {
      scanf(" %c", &p);
      if (p == '*') arr[i][j] = 1;
    }
  }
  for (int i = 1; i <= r; i++) {
    for (int j = 1; j <= c; j++) {
      if (arr[i][j]) pre_row[i][j] = pre_row[i][j - 1] + 1;
    }
    for (int j = c; j >= 1; j--) {
      if (arr[i][j]) post_row[i][j] = post_row[i][j + 1] + 1;
    }
  }
  for (int j = 1; j <= c; j++) {
    for (int i = 1; i <= r; i++) {
      if (arr[i][j]) pre_col[i][j] = pre_col[i - 1][j] + 1;
    }
    for (int i = r; i >= 1; i--) {
      if (arr[i][j]) post_col[i][j] = post_col[i + 1][j] + 1;
    }
  }
  for (int i = 1; i <= r; i++) {
    for (int j = 1; j <= c; j++) {
      if (!arr[i][j]) continue;
      int val = min(pre_row[i][j - 1], post_row[i][j + 1]);
      int val1 = min(pre_col[i - 1][j], post_col[i + 1][j]);
      val = min(val, val1);
      if (val) {
        update_row(1, i, 1, c, j - val, j + val, 1);
        update_col(1, j, 1, r, i - val, i + val, 1);
        v.push_back(make_pair(i, make_pair(j, val)));
      }
    }
  }
  for (int i = 1; i <= r; i++) {
    query_row(1, i, 1, c);
  }
  for (int i = 1; i <= c; i++) {
    query_col(1, i, 1, r);
  }
  for (int i = 1; i <= r; i++) {
    for (int j = 1; j <= c; j++) {
      if (arr[i][j]) {
        if (!ans[i][j]) {
          printf("-1\n");
          return 0;
        }
      }
    }
  }
  cout << v.size() << endl;
  for (int i = 0; i < v.size(); i++) {
    printf("%d %d %d\n", v[i].first, v[i].second.first, v[i].second.second);
  }
}
