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<cstring>
#include<algorithm>
#include<cstdlib>
#include<ctime>
#include<utility>
#include<functional>
#include<cmath>
#include<vector>
#include<assert.h>
//using namespace std;
using std::min;
using std::max;
using std::swap;
using std::sort;
using std::reverse;
using std::random_shuffle;
using std::lower_bound;
using std::upper_bound;
using std::unique;
using std::vector;
typedef long long ll;
typedef unsigned long long ull;
typedef double db;
typedef std::pair<int,int> pii;
typedef std::pair<ll,ll> pll;
void open(const char *s){
#ifndef ONLINE_JUDGE
	char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
void open2(const char *s){
#ifdef DEBUG
	char str[100];sprintf(str,"%s.in",s);freopen(str,"r",stdin);sprintf(str,"%s.out",s);freopen(str,"w",stdout);
#endif
}
int rd(){int s=0,c,b=0;while(((c=getchar())<'0'||c>'9')&&c!='-');if(c=='-'){c=getchar();b=1;}do{s=s*10+c-'0';}while((c=getchar())>='0'&&c<='9');return b?-s:s;}
void put(int x){if(!x){putchar('0');return;}static int c[20];int t=0;while(x){c[++t]=x%10;x/=10;}while(t)putchar(c[t--]+'0');}
int upmin(int &a,int b){if(b<a){a=b;return 1;}return 0;}
int upmax(int &a,int b){if(b>a){a=b;return 1;}return 0;}
const int N=310;
int a[N][N];
int b[N][N];
int s1[N][N];
int n,m;
void rotate()
{
	memset(b,0,sizeof b);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			b[j][n-i+1]=a[i][j];
	swap(n,m);
	memcpy(a,b,sizeof a);
}
ll gao1()
{
	memset(s1,0,sizeof s1);
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			s1[i][j]=a[i][j]+s1[i-1][j-1];
	ll res=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=2;i+k-1<=n&&j-k+1>=1&&i-1+m-j>=k-1;k++)
				if(a[i+k-1][j]&&a[i][j-k+1])
				{
					ll temp=0;
					temp+=(j+k-1>m?s1[i-(j+k-1-m+1)+1][m]:s1[i][j+k-1]);
					temp-=(i-k+1<1?s1[0][j-(i-k+1)+1-1]:s1[i-k][j-1]);
					res+=temp;
				}
	return res;
}
ll gao2()
{
	ll res=0;
	for(int i=1;i<=n;i++)
		for(int j=1;j<=m;j++)
			for(int k=2;i+k-1<=n&&j+k-1<=m&&j-k+1>=1;k++)
				if(a[i][j-k+1]&&a[i][j+k-1]&&a[i+k-1][j])
					res++;
	return res;
}
char str[N];
ll ans;
int main()
{
	scanf("%d%d",&n,&m);
	for(int i=1;i<=n;i++)
	{
		scanf("%s",str+1);
		
		for(int j=1;j<=m;j++)
			a[i][j]=(str[j]=='#');
	}
	ans+=gao1();
	ans-=gao2();
	rotate();
	ans+=gao1();
	ans-=gao2();
	rotate();
	ans+=gao1();
	ans-=gao2();
	rotate();
	ans+=gao1();
	ans-=gao2();
	rotate();
	printf("%lld\n",ans);
	return 0;
}