A tourist wants to visit country Zeydabad for Zbazi (a local game in Zeydabad).

The country Zeydabad is a rectangular table consisting of n rows and m columns. Each cell on the country is either 'z' or '.'.

The tourist knows this country is named Zeydabad because there are lots of ''Z-pattern"s in the country. A ''Z-pattern" is a square which anti-diagonal is completely filled with 'z' and its upper and lower rows are also completely filled with 'z'. All other cells of a square can be arbitrary.

<image>

Note that a ''Z-pattern" can consist of only one cell (see the examples).

So he wants to count the number of ''Z-pattern"s in the country (a necessary skill for Zbazi).

Now your task is to help tourist with counting number of ''Z-pattern"s.

As input/output can reach huge size it is recommended to use fast input/output methods: for example, prefer to use gets/scanf/printf instead of getline/cin/cout in C++, prefer to use BufferedReader/PrintWriter instead of Scanner/System.out in Java.

Input

The first line contains two integers n, m (1 ≤ n, m ≤ 3000) — the number of rows and columns respectively.

Each of the next n lines contains m characters 'z' or '.' — the description of Zeydabad.

Output

Print the only integer a — the number of ''Z-pattern"s in Zeydabad.

Examples

Input

4 4
zzzz
zzz.
.z..
zzzz


Output

16


Input

1 4
z.z.


Output

2


Input

2 2
zz
zz


Output

5
#include <bits/stdc++.h>
using namespace std;
int a[3005][3005];
int c[3005][3005];
int d[3005][3005];
char ch[3005][3005];
const int MAXN = 3010;
struct Node {
  int l, r;
  int len() { return r - l; }
  int mid() { return (l + r) / 2; }
  bool in(int ll, int rr) { return l >= ll && r <= rr; }
  void lr(int ll, int rr) {
    l = ll;
    r = rr;
  }
} node[MAXN * 4];
int num_left[15][MAXN], seg[15][MAXN], sa[MAXN];
void Init() {
  memset(num_left, 0, sizeof(num_left));
  memset(node, 0, sizeof(node));
}
void PaBuild(int t, int l, int r, int d) {
  node[t].lr(l, r);
  if (node[t].len() == 0) return;
  int mid = (l + r) / 2, lsame = mid - l + 1;
  for (int i = l; i <= r; i++)
    if (seg[d][i] < sa[mid]) lsame--;
  int lpos = l, rpos = mid + 1;
  for (int i = l; i <= r; i++) {
    if (i == l)
      num_left[d][i] = 0;
    else
      num_left[d][i] = num_left[d][i - 1];
    if (seg[d][i] < sa[mid]) {
      num_left[d][i]++;
      seg[d + 1][lpos++] = seg[d][i];
    }
    if (seg[d][i] > sa[mid]) seg[d + 1][rpos++] = seg[d][i];
    if (seg[d][i] == sa[mid])
      if (lsame > 0) {
        lsame--;
        num_left[d][i]++;
        seg[d + 1][lpos++] = seg[d][i];
      } else
        seg[d + 1][rpos++] = seg[d][i];
  }
  PaBuild(t * 2, l, mid, d + 1);
  PaBuild(t * 2 + 1, mid + 1, r, d + 1);
}
void Build(int s, int t) {
  sort(sa + s, sa + t + s);
  PaBuild(1, s, t, 1);
}
int find_rank(int t, int l, int r, int d, int val) {
  if (node[t].len() == 0) return seg[d][l];
  int s, ss;
  if (l == node[t].l)
    ss = 0;
  else
    ss = num_left[d][l - 1];
  s = num_left[d][r] - ss;
  if (s >= val)
    return find_rank(t * 2, node[t].l + ss, node[t].l + ss + s - 1, d + 1, val);
  else {
    int mid = node[t].mid();
    int bb = l - node[t].l - ss;
    int b = r - l + 1 - s;
    return find_rank(t * 2 + 1, mid + bb + 1, mid + bb + b, d + 1, val - s);
  }
}
int Query(int s, int t, int k) { return find_rank(1, s, t, 1, k); }
int main() {
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 1; i <= n; i++) scanf("%s", ch[i] + 1);
  n = max(n, m);
  for (int i = 1; i <= n; i++)
    for (int j = 1; j <= n; j++) {
      if (ch[i][j] == 'z') a[i][j] = 1;
    }
  for (int i = 1; i <= n; i++) {
    int sum = 0;
    for (int j = n; j >= 1; j--) {
      if (a[i][j])
        sum++;
      else
        sum = 0;
      c[i][j] = sum;
    }
  }
  for (int i = 1; i <= n; i++) {
    int sum = 0;
    for (int j = 1; j <= n; j++) {
      if (a[i][j])
        sum++;
      else
        sum = 0;
      d[i][j] = sum;
    }
  }
  long long ans = 0;
  for (int i = 1; i < 2 * n; i++) {
    int len = 1;
    Init();
    for (int j = 1; j <= n; j++, len++) {
      int x = i - j + 1, y = j;
      if (i - j + 1 <= 0) break;
      if (i - j + 1 > n) {
        sa[len] = seg[1][len] = 0;
        continue;
      }
      sa[len] = seg[1][len] = d[y][x] + j;
    }
    Build(1, len - 1);
    int h = 1;
    for (int j = 1; j <= n; j++) {
      if (i - j + 1 <= 0) break;
      if (i - j + 1 > n) continue;
      int x = i - j + 1, y = j;
      if (d[y][x] == 0) {
        h = j + 1;
        continue;
      }
      int t = max(j - c[y][x] + 1, h);
      int l = 1, r = j - t + 1;
      int ret = r;
      while (l <= r) {
        int mid = (l + r) / 2;
        int q = Query(t, j, mid);
        if (q >= j + 1) {
          r = mid - 1;
          ret = mid;
        } else {
          l = mid + 1;
        }
      }
      ans += j - t + 1 - ret + 1;
    }
  }
  printf("%lld\n", ans);
  return 0;
}
