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;
struct Wow {
  vector<int> tree;
  vector<int> vis;
  int offset;
  int id;
  Wow() {
    tree.clear();
    tree.resize(4 * 50000);
    vis.clear();
    vis.resize(4 * 50000);
    offset = -10000;
    id = 1;
  }
  void make(int node) {
    if (vis[node] != id) tree[node] = 0, vis[node] = id;
  }
  void update(int ind, int val, int node, int left, int right) {
    make(node);
    if (ind < left || right < ind) return;
    if (left == right) {
      make(node);
      tree[node] += val;
      assert(tree[node] >= 0);
      return;
    }
    int mid = (left + right) >> 1;
    update(ind, val, node << 1, left, mid);
    update(ind, val, (node << 1) + 1, mid + 1, right);
    make(node);
    tree[node] = tree[node << 1] + tree[(node << 1) + 1];
  }
  int get(int x, int y, int node, int left, int right) {
    if (y < left || right < x) return 0;
    if (x <= left && right <= y) {
      make(node);
      return tree[node];
    }
    int mid = (left + right) >> 1;
    return get(x, y, node << 1, left, mid) +
           get(x, y, (node << 1) + 1, mid + 1, right);
  }
  void insert(int x) {
    x -= offset;
    update(x, 1, 1, 0, 50000);
  }
  void erase(int x) {
    x -= offset;
    update(x, -1, 1, 0, 50000);
  }
  void clear() {
    id++;
    offset = -10000;
  }
  void addOne() { offset++; }
  int getLessThanOrEqual(int x) {
    x -= offset;
    return get(0, x, 1, 0, 50000);
  }
};
Wow W;
char s[3005][3005];
int prv[3005][3005];
int nxt[3005][3005];
vector<int> rem[3005];
int vis[3004];
int id;
int main() {
  ios::sync_with_stdio(false);
  int n, m;
  scanf("%d%d", &n, &m);
  for (int i = 0; i < n; i++) scanf("%s", s[i]);
  for (int i = 0; i < n; i++)
    for (int j = 0; j < m; j++) s[i][j] = s[i][j] == 'z' ? 1 : 0;
  int cur;
  for (int i = 0; i < n; i++) {
    cur = 0;
    for (int j = 0; j < m; prv[i][j++] = cur) cur = cur * s[i][j] + s[i][j];
    cur = 0;
    for (int j = m - 1; j >= 0; nxt[i][j--] = cur)
      cur = cur * s[i][j] + s[i][j];
  }
  long long ans = 0;
  for (int i = 0; i < 1; i++)
    for (int j = 0; j < m; j++) {
      int x = i, y = j;
      int dx = 1, dy = -1;
      int ind = 0;
      W.clear();
      id++;
      while (x < n && y >= 0) {
        if (vis[ind] != id) {
          vis[ind] = id;
          rem[ind].clear();
        }
        if (s[x][y] == 0) {
          W.clear();
          id++;
          x += dx;
          y += dy;
          ind += 1;
          continue;
        }
        for (int i = 0; i < int(rem[ind].size()); i++) {
          int val = rem[ind][i];
          W.erase(val);
        }
        int myNxt = nxt[x][y];
        int myPrv = prv[x][y];
        int inc = W.getLessThanOrEqual(myNxt);
        ans += inc + 1;
        W.insert(1);
        W.addOne();
        if (ind + myPrv <= 3000) {
          if (vis[ind + myPrv] != id) {
            vis[ind + myPrv] = id;
            rem[ind + myPrv].clear();
          }
          rem[ind + myPrv].push_back(myPrv + 1);
        }
        x += dx;
        y += dy;
        ind += 1;
      }
    }
  for (int j = m - 1; j == m - 1; j--)
    for (int i = 1; i < n; i++) {
      int x = i, y = j;
      int dx = 1, dy = -1;
      int ind = 0;
      W.clear();
      id++;
      while (x < n && y >= 0) {
        if (vis[ind] != id) {
          vis[ind] = id;
          rem[ind].clear();
        }
        if (s[x][y] == 0) {
          W.clear();
          id++;
          x += dx;
          y += dy;
          ind += 1;
          continue;
        }
        for (int i = 0; i < int(rem[ind].size()); i++) {
          int val = rem[ind][i];
          W.erase(val);
        }
        int myNxt = nxt[x][y];
        int myPrv = prv[x][y];
        int inc = W.getLessThanOrEqual(myNxt);
        ans += inc + 1;
        W.insert(1);
        W.addOne();
        if (ind + myPrv <= 3000) {
          if (vis[ind + myPrv] != id) {
            vis[ind + myPrv] = id;
            rem[ind + myPrv].clear();
          }
          rem[ind + myPrv].push_back(myPrv + 1);
        }
        x += dx;
        y += dy;
        ind += 1;
      }
    }
  cout << ans << endl;
  return 0;
}
