Problem: There are some coins in the xy-plane. The positions of the coins are represented by a grid of characters with H rows and W columns. If the character at the i-th row and j-th column, s_{ij}, is `#`, there is one coin at point (i,j); if that character is `.`, there is no coin at point (i,j). There are no other coins in the xy-plane.

There is no coin at point (x,y) where 1\leq i\leq H,1\leq j\leq W does not hold. There is also no coin at point (x,y) where x or y (or both) is not an integer. Additionally, two or more coins never exist at the same point.

Find the number of triples of different coins that satisfy the following condition:

* Choosing any two of the three coins would result in the same Manhattan distance between the points where they exist.



Here, the Manhattan distance between points (x,y) and (x',y') is |x-x'|+|y-y'|. Two triples are considered the same if the only difference between them is the order of the coins.

Constraints

* 1 \leq H,W \leq 300
* s_{ij} is `#` or `.`.

Input

Input is given from Standard Input in the following format:


H W
s_{11}...s_{1W}
:
s_{H1}...s_{HW}


Output

Print the number of triples that satisfy the condition.

Examples

Input

5 4
#.##
.##.
#...
..##
...#


Output

3


Input

5 4
.##
.##.
...
..##
...#


Output

3


Input

13 27
......#.........#.......#..
...#.....###..
..............#####...##...
...#######......#...#######
...#.....#.....###...#...#.
...#######....#.#.#.#.###.#
..............#.#.#...#.#..
.#.#.#...###..
...........#...#...#######
..#######..#...#...#.....#
..#.....#..#...#...#.###.#
..#######..#...#...#.#.#.#
..........##...#...#.#####


Output

870

Solution (in CPP):

Solution:
#include <cassert>
#include <iostream>
#include <vector>
using namespace std;

#define FOR(i,m,n) for(int i=(m);i<(n);++i)
#define REP(i,n) FOR(i,0,n)
/*-------------------------------------------------*/
template <typename T>
vector<vector<T> > rot(const vector<vector<T> > &grid, int angle) {
  int h = grid.size(), w = grid.front().size();
  if (angle == 45) {
    vector<vector<T> > rotated_grid(h + w - 1, vector<T>(h + w - 1, ' '));
    REP(i, h) REP(j, w) rotated_grid[i + j][j - i + h - 1] = grid[i][j];
    return rotated_grid;
  } else if (angle == 90) {
    vector<vector<T> > rotated_grid(w, vector<T>(h));
    REP(i, h) REP(j, w) rotated_grid[w - 1 - j][i] = grid[i][j];
    return rotated_grid;
  } else {
    assert(false);
  }
}

// http://phyllo-algo.hatenablog.com/entry/2018/10/29/000320
int main() {
  cin.tie(0); ios::sync_with_stdio(false);
  // freopen("input.txt", "r", stdin);

  int h, w; cin >> h >> w;
  vector<vector<char> > s(h, vector<char>(w)); REP(i, h) REP(j, w) cin >> s[i][j];
  // マンハッタン距離を考えるため45度回転させる
  s = rot(s, 45);

  int ans = 0;
  REP(_, 4) {
    h = s.size(); w = s.front().size();
    vector<vector<int> > row(h, vector<int>(w + 1, 0));
    REP(i, h) {
      REP(j, w) row[i][j + 1] = row[i][j] + (s[i][j] == '#' ? 1 : 0);
    }
    REP(i, h) REP(j, w) if (s[i][j] == '#') {
      FOR(k, j + 1, w) if (s[i][k] == '#') {
        int r = i - (k - j);
        if (r >= 0) ans += row[r][k] - row[r][j];
      }
    }
    s = rot(s, 90);
  }
  cout << ans << '\n';
  return 0;
}