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<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 702
using namespace std;
namespace IO{
	const int BS=(1<<20)+5; int Top=0;
	char Buffer[BS],OT[BS],*OS=OT,*HD,*TL,SS[20]; const char *fin=OT+BS-1;
	char Getchar(){if(HD==TL){TL=(HD=Buffer)+fread(Buffer,1,BS,stdin);} return (HD==TL)?EOF:*HD++;}
	void flush(){fwrite(OT,1,OS-OT,stdout);}
	void Putchar(char c){*OS++ =c;if(OS==fin)flush(),OS=OT;}
	void write(int x){
		if(!x){Putchar('0');return;} if(x<0) x=-x,Putchar('-');
		while(x) SS[++Top]=x%10,x/=10;
		while(Top) Putchar(SS[Top]+'0'),--Top;
	}
	int read(){
		int nm=0,fh=1; char cw=getchar();
		for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;
		for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');
		return nm*fh;
	}
}
using namespace IO;
int n,m,p[M][M],g[M][M],f[M][M],ans;
char ch[M];
#define S(a,b,c,d) (f[c][d]-f[a-1][d]-f[c][b-1]+f[a-1][b-1])
int main(){
	//freopen(".in","r",stdin);
//	freopen("map.out","w",stdout);
	n=read(),m=read();
	for(int i=1;i<=n;i++){
		scanf("%s",ch+1);
		for(int j=1;j<=m;j++) if(ch[j]=='#') g[i+j][i-j+m+1]=1;
	}
	n=n+m,m=n;
	for(int i=1;i<=n;i++) for(int j=1;j<=n;j++) f[i][j]=f[i][j-1]+f[i-1][j]-f[i-1][j-1]+g[i][j];
//	for(int i=1;i<=n;i++,puts("")) for(int j=1;j<=n;j++) printf("%d ",g[i][j]);
	for(int i=1;i<=n;i++){
		for(int j=1;j<=n;j++){
			if(!g[i][j]) continue;
			for(int d=2;j+d<=n;d++){
				if(!g[i][j+d]) continue;
				if(i>d) ans+=S(i-d,j+1,i-d,j+d-1);
				if(i+d<=n) ans+=S(i+d,j+1,i+d,j+d-1);
			}
			for(int d=2;i+d<=n;d++){
				if(!g[i+d][j]) continue;
				if(j>d) ans+=S(i+1,j-d,i+d-1,j-d);
				if(j+d<=n) ans+=S(i+1,j+d,i+d-1,j+d);
			}
			for(int d=1;d<=n;d++){
				if(i>d&&j>d) ans+=(g[i-d][j]&g[i][j-d]);
				if(i>d&&j+d<=n) ans+=(g[i-d][j]&g[i][j+d]);
				if(i+d<=n&&j>d) ans+=(g[i+d][j]&g[i][j-d]);
				if(i+d<=n&&j+d<=n) ans+=(g[i+d][j]&g[i][j+d]);
			} 
		}
	}
	printf("%d\n",ans);
	return 0;
}