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<stdio.h>
#include<iostream>
#include<vector>
#include<algorithm>
#include<string>
#include<string.h>
using namespace std;

typedef long long LL;
typedef vector<int> VI;

#define REP(i,n) for(int i=0, i##_len=(n); i<i##_len; ++i)
#define EACH(i,c) for(__typeof((c).begin()) i=(c).begin(),i##_end=(c).end();i!=i##_end;++i)
#define eprintf(...) fprintf(stderr, __VA_ARGS__)

template<class T> inline void amin(T &x, const T &y) { if (y<x) x=y; }
template<class T> inline void amax(T &x, const T &y) { if (x<y) x=y; }
template<class Iter> void rprintf(const char *fmt, Iter begin, Iter end) {
    for (bool sp=0; begin!=end; ++begin) { if (sp) putchar(' '); else sp = true; printf(fmt, *begin); }
    putchar('\n');
}

int H, W;
char F[333][333];

const int LIMIT = 611;
bool B[621][621];
int M[621][621];

void MAIN() {
    scanf("%d%d", &H, &W);
    REP (i, H) scanf("%s", F[i]);
    REP (i, H) REP (j, W) if (F[i][j] == '#') {
	int y = i - j + 300;
	int x = i + j;
	B[y][x] = true;
    }
    LL ans = 0;

    REP (i, LIMIT) REP (j, LIMIT) {
	M[i][j+1] = M[i][j] + (int)B[i][j];
    }

    REP (i, LIMIT) REP (j, LIMIT) if (B[i][j]) {
	for (int k=j+1; k<LIMIT; k++) if (B[i][k]) {
	    int d = k-j;
	    if (0 <= i-d) {
		ans += M[i-d][k+1] - M[i-d][j];
	    }
	    if (i+d < LIMIT) {
		ans += M[i+d][k+1] - M[i+d][j];
	    }
	}
    }

    memset(M, 0, sizeof M);
    REP (i, LIMIT) REP (j, i) swap(B[i][j], B[j][i]);
    REP (i, LIMIT) REP (j, LIMIT) {
	M[i][j+1] = M[i][j] + (int)B[i][j];
    }

    REP (i, LIMIT) REP (j, LIMIT) if (B[i][j]) {
	for (int k=j+1; k<LIMIT; k++) if (B[i][k]) {
	    int d = k-j;
	    if (0 <= i-d) {
		ans += M[i-d][k] - M[i-d][j+1];
	    }
	    if (i+d < LIMIT) {
		ans += M[i+d][k] - M[i+d][j+1];
	    }
	}
    }

    printf("%lld\n", ans);
}

int main() {
    int TC = 1;
//    scanf("%d", &TC);
    REP (tc, TC) MAIN();
    return 0;
}