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>
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define rep1(i,n) for(int i=1;i<=(int)(n);i++)
#define all(c) c.begin(),c.end()
#define pb push_back
#define fs first
#define sc second
#define show(x) cout << #x << " = " << (x) << endl
#define chmin(x,y) x=min(x,y)
#define chmax(x,y) x=max(x,y)
using namespace std;
template<class S,class T> ostream& operator<<(ostream& o,const pair<S,T> &p){
	return o<<"("<<p.fs<<","<<p.sc<<")";
}
template<class T> ostream& operator<<(ostream& o,const vector<T> &vc){
	o<<"{";
	for(const T& v:vc) o<<v<<",";
	o<<"}";
	return o;
}
using ll = long long;
template<class T> using V = vector<T>;
template<class T> using VV = vector<vector<T>>;
int H,W;
vector<string> s;
int dx[4] = {1,1,-1,-1};
int dy[4] = {1,-1,-1,1};
bool is(int x,int y){
	return 0<=x&&x<H&&0<=y&&y<W;
}
int count3(){
	int ans = 0;
	rep(i,H) rep(j,W) if(s[i][j]=='#') rep(d,4){
		for(int k=1;;k++){
			int x1 = i+dx[d]*k, y1 = j+dy[d]*k;
			int x2 = i+dx[(d+1)%4]*k, y2 = j+dy[(d+1)%4]*k;
			if(!is(x1,y1) || !is(x2,y2)) break;
			if(s[x1][y1]=='#' && s[x2][y2]=='#') ans++;
		}
	}
	return ans;
}
const int N = 700;
bool S[N][N];
int ac[N][N+1];
void rot(){
	bool s[N][N] = {};
	rep(i,N) rep(j,N) s[i][j] = S[j][N-1-i];
	rep(i,N) rep(j,N) S[i][j] = s[i][j];
	rep(i,N){
		ac[i][0] = 0;
		rep(j,N) ac[i][j+1] = ac[i][j] + S[i][j];
	}
}
ll solve(){
	int res = 0;
	rep(i,N){
		rep(r,N) if(S[i][r]){
			rep(l,r) if(S[i][l]){
				int d = r-l;
				int j = i+d;
				if(j>=N) continue;
//				for(int x=l;x<=r;x++) if(S[j][x]) res++;
				res += ac[j][r+1] - ac[j][l];
			}
		}
	}
	return res;
}
int main(){
	cin>>H>>W;
	s.resize(H);
	rep(i,H) cin>>s[i];
	ll ans = -count3();
	rep(i,H) rep(j,W) S[i+j][i-j+W] = s[i][j]=='#';
	rep(t,4){
		rot();
		ans += solve();
	}
	cout<<ans<<endl;
}