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 <cstdio>
#include <cstdlib>
#include <algorithm>
#include <vector>
#include <cstring>
#include <queue>
#include <functional>
#include <cmath>
#include <string>
#include <set>
#include <map>
#include <cassert>
#define SIZE 605

using namespace std;
typedef long long int ll;
typedef pair <int,int> P;

char mp[SIZE][SIZE];
bool use[SIZE][SIZE];
int tt[SIZE][SIZE],yy[SIZE][SIZE];

int xsum(int x,int i,int j)
{
	return tt[x][j]-(i==0?0:tt[x][i-1]);
}
int ysum(int y,int i,int j)
{
	return yy[j][y]-(i==0?0:yy[i-1][y]);
}
int main()
{
	int n,m;
	scanf("%d %d",&n,&m);
	for(int i=0;i<n;i++) scanf("%s",&mp[i]);
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<m;j++)
		{
			if(mp[i][j]=='#')
			{
				int x=i+j,y=i-j+m-1;
				use[x][y]=true;
			}
		}
	}
	n=n+m;//[0,n-1]*[0,n-1] 内にある
	ll ret=0;
	for(int i=0;i<n;i++)
	{
		for(int j=0;j<n;j++)
		{
			tt[i][j]=yy[i][j]=use[i][j];
			if(j>0) tt[i][j]+=tt[i][j-1];
			if(i>0) yy[i][j]+=yy[i-1][j];
		}
	}
	for(int i=0;i<n;i++)
	{
		for(int s=0;s<n;s++)
		{
			for(int t=s+1;t<n;t++)
			{
				if(use[i][s]&&use[i][t])
				{
					int l=t-s;
					if(i>=l)
					{
						ret+=xsum(i-l,s,t);
						if(use[i-l][s]) ret--;
						if(use[i-l][t]) ret--;
					}
					if(i+l<n)
					{
						ret+=xsum(i+l,s,t);
						if(use[i+l][s]) ret--;
						if(use[i+l][t]) ret--;
					}
				}
				if(use[s][i]&&use[t][i])
				{
					int l=t-s;
					if(i>=l)
					{
						ret+=ysum(i-l,s,t);
					}
					if(i+l<n)
					{
						ret+=ysum(i+l,s,t);
					}
				}
			}
		}
	}
	printf("%lld\n",ret);
	return 0;
}