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<bits/stdc++.h>
using namespace std;
using Int = long long;
template<typename T1,typename T2> inline void chmin(T1 &a,T2 b){if(a>b) a=b;}
template<typename T1,typename T2> inline void chmax(T1 &a,T2 b){if(a<b) a=b;}

//INSERT ABOVE HERE
const Int MAX = 305;
const Int MAX2 = MAX*2;
signed ex[MAX2][MAX2];
signed dp[MAX2+2][MAX2+2];
signed main(){
  Int h,w;
  cin>>h>>w;
  vector<string> s(h);
  for(Int i=0;i<h;i++) cin>>s[i];

  using P = pair<Int, Int>;
  vector<P> vp;
  memset(ex,0,sizeof(ex));
  for(Int i=0;i<h;i++){
    for(Int j=0;j<w;j++){
      if(s[i][j]!='#') continue;
      vp.emplace_back(1+i+j,1+i-j+w);
      ex[1+i+j][1+i-j+w]=1;      
    }
  }
  
  auto ch=
    [&](Int i,Int j)->Int{
      if(i<0||i>=MAX2) return 0;
      if(j<0||j>=MAX2) return 0;
      return ex[i][j];
    };
  
  memset(dp,0,sizeof(dp));
  Int ans=0;
  
  const Int LIM = h+w;
  for(Int k=1;k<=LIM;k++){
    for(Int i=0;i<MAX2;i++)
      for(Int j=0;j<MAX2;j++)
        dp[i][j+1]=dp[i][j]+(ex[i][j]&&ch(i,j-k));

    for(P p:vp){
      Int i,j;
      tie(i,j)=p;
      if(i-k>=0)  ans+=dp[i-k][min(MAX2-1,j+k+1)]-dp[i-k][j];
      if(i+k<MAX2) ans+=dp[i+k][min(MAX2-1,j+k+1)]-dp[i+k][j];
    }

    for(Int j=0;j<MAX2;j++)
      for(Int i=0;i<MAX2;i++)
        dp[j][i+1]=dp[j][i]+(ex[i][j]&&ch(i-k,j));
    
    for(P p:vp){
      Int i,j;
      tie(i,j)=p;
      if(j-k>=0)  ans+=dp[j-k][min(MAX2-1,i+k+1)]-dp[j-k][i];
      if(j+k<MAX2) ans+=dp[j+k][min(MAX2-1,i+k+1)]-dp[j+k][i];   
    }            
  }

  //cout<<ans<<endl;
  for(P p:vp){
    Int i,j;
    tie(i,j)=p;
    for(Int k=1;k<=LIM;k++){
      if(ch(i+k,j)&&ch(i,j+k)) ans--;
      if(ch(i+k,j)&&ch(i,j-k)) ans--;
      if(ch(i-k,j)&&ch(i,j+k)) ans--;
      if(ch(i-k,j)&&ch(i,j-k)) ans--;
    }
  }
  cout<<ans<<endl;
  return 0;
}