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"
using namespace std;
#define int long long
#define REP(i, n) for (int i = 0; i < (int)n; ++i)
#define RREP(i, n) for (int i = (int)n - 1; i >= 0; --i)
#define FOR(i, s, n) for (int i = s; i < (int)n; ++i)
#define RFOR(i, s, n) for (int i = (int)n - 1; i >= s; --i)
#define ALL(a) a.begin(), a.end()
#define IN(a, x, b) (a <= x && x < b)
template<class T>istream&operator >>(istream&is,vector<T>&vec){for(T&x:vec)is>>x;return is;}
template<class T>inline void out(T t){cout << t << "\n";}
template<class T,class... Ts>inline void out(T t,Ts... ts){cout << t << " ";out(ts...);}
template<class T>inline bool CHMIN(T&a,T b){if(a > b){a = b;return true;}return false;}
template<class T>inline bool CHMAX(T&a,T b){if(a < b){a = b;return true;}return false;}
constexpr int INF = 1e18;



signed main(){
	int H, W;
	cin >> H >> W;
	vector<string>s(H);
	cin >> s;
	auto f = [&]() {
		vector<vector<int>>dp(660, vector<int>(660));
		vector<vector<int>>d(660, vector<int>(660));
		int mid = 330;
		REP(i, H) {
			REP(j, W) {
				if(s[i][j] == '#') {
					//dp[i + j][i - j + mid]++;
					d[i + j][i - j + mid]++;
				}
			}
		}
		REP(i, 660) {
			REP(j, 659) {
				dp[i][j + 1] += dp[i][j] + d[i][j];
			}
		}
		int ans = 0;
		int triple = 0;
		REP(i, 660) {
			REP(j, 660) {
				FOR(k, j + 1, 660) {
					if(d[i][j] && d[i][k]) {
						int diff = abs(j - k);
						if(diff % 2) continue;
						//out(i, j, k);
						if(i - diff >= 0) {
							ans += dp[i - diff][k + 1] - dp[i - diff][j];
							triple += d[i - diff][k] + d[i - diff][j];
						}
						if(i + diff < 660) {
							ans += dp[i + diff][k + 1] - dp[i + diff][j];
							triple += d[i + diff][k] + d[i + diff][j];
						}
					}
				}
			}
		}
		return make_pair(ans, triple);
	};

	int ans = 0, triples = 0;
	REP(_, 2) {
		auto[val, triple] = f();
		ans += val;
		triples += triple;
		vector<string>tmp(W);
		REP(j, W) {
			RREP(i, H) tmp[j] += s[i][j];
		}
		swap(H, W);
		s = tmp;
	}
	out(ans - triples / 2);
}