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:
#define _CRT_SECURE_NO_WARNINGS
#include<iostream>
#include<sstream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<climits>
#include<cmath>
#include<string>
#include<vector>
#include<set>
#include<map>
#include<queue>
#include<numeric>
#include<functional>
#include<algorithm>
#include<bitset>
#include<tuple>
#include<unordered_set>
#include<unordered_map>
#include<random>
#include<array>
#include<cassert>
using namespace std;
#define INF (1<<29)
#define rep(i,n) for(int i=0;i<(int)(n);i++)
#define all(v) v.begin(),v.end()
#define uniq(v) v.erase(unique(all(v)),v.end())



bool coin[600][600];
int sx[600][601];
int sy[600][601];



int main() {
	ios::sync_with_stdio(0);
	cin.tie(0);

	int h, w;
	cin >> h >> w;
	rep(i,h)rep(j,w) {
		char c;
		cin >> c;
		if (c=='#') {
			int y = i - j + w - 1;
			int x = i + j;
			coin[y][x] = true;
			sx[x][y+1]++;
			sy[y][x+1]++;
		}
	}

	rep(x, h+w)rep(y, h+w)sx[x][y + 1] += sx[x][y];
	rep(y, h+w)rep(x, h+w)sy[y][x + 1] += sy[y][x];



	long long ans1 = 0, ans2 = 0;
	rep(y, h+w)rep(x,h+w)if(coin[y][x]) {
		rep(y2, h+w) if (y != y2 && coin[y2][x]) {
			int ymi = min(y, y2), yma = max(y, y2);
			int d = yma - ymi;
			if (x - d >= 0) {
				ans1 += sx[x - d][yma] - sx[x - d][ymi+1];
				if (coin[y][x - d])ans2++;
				if (coin[y2][x - d])ans2++;
			}
			if (x+d < 600) {
				ans1 += sx[x + d][yma] - sx[x + d][ymi+1];
				if (coin[y][x + d])ans2++;
				if (coin[y2][x + d])ans2++;
			}
		}
		rep(x2, h+w) if (x != x2 && coin[y][x2]) {
			int xmi = min(x, x2), xma = max(x, x2);
			int d = xma - xmi;
			if (y - d >= 0) {
				ans1 += sy[y - d][xma] - sy[y - d][xmi+1];
				if (coin[y - d][x])ans2++;
				if (coin[y - d][x2])ans2++;
			}
			if (y + d < 600) {
				ans1 += sy[y + d][xma] - sy[y + d][xmi+1];
				if (coin[y + d][x])ans2++;
				if (coin[y + d][x2])ans2++;
			}
		}
	}

	cout << ans1/2 + ans2/4 << endl;


	return 0;
}