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 FOR(i, begin, end) for(int i=(begin);i<(end);i++)
#define REP(i, n) FOR(i,0,n)
#define IFOR(i, begin, end) for(int i=(end)-1;i>=(begin);i--)
#define IREP(i, n) IFOR(i,0,n)
#define SORT(a) sort(a.begin(), a.end())
#define REVERSE(a) reverse(a.begin(), a.end())
#define Lower_bound(v, x) distance(v.begin(), lower_bound(v.begin(), v.end(), x))
#define Upper_bound(v, x) distance(v.begin(), upper_bound(v.begin(), v.end(), x))
#define int long long
#define INF 1000000000000000000
using namespace std;

typedef vector<int> vec;
typedef vector<vec> mat;
typedef pair<int, int> Pii;

template<typename T>
void readv(vector<T> &a){ REP(i, a.size()) cin >> a[i]; }
void readi(vector<int> &a){ REP(i, a.size()){cin >> a[i]; a[i]--;} }



signed main(){

    int H, W; cin >> H >> W;
    vector<string> s(H);
    REP(i, H) cin >> s[i];

    mat t(H + W + 1, vec(H + W + 1, 0));
    REP(i, H){
        REP(j, W){
            if(s[i][j] == '#')
            t[i + j + 1][i - j + 1 + W] = 1;
        }
    }
    mat tsum = t;
    REP(i, H + W + 1) REP(j, H + W) tsum[i][j + 1] += tsum[i][j];
    REP(j, H + W + 1) REP(i, H + W) tsum[i + 1][j] += tsum[i][j];

    int ans = 0;
    REP(i, H + W){
        REP(j, H + W){
            if(t[i + 1][j + 1] == 0) continue;
            FOR(j2, j + 1, H + W){
                if(t[i + 1][j2 + 1] == 0) continue;
                int n = j2 - j;
                if(i - n >= 0) ans += tsum[i - n + 1][j2 + 1] - tsum[i - n + 1][j] - tsum[i - n][j2 + 1] + tsum[i - n][j];
                if(i + n < H + W) ans += tsum[i + n + 1][j2 + 1] - tsum[i + n + 1][j] - tsum[i + n][j2 + 1] + tsum[i + n][j];
            }
            FOR(i2, i + 2, H + W){
                if(t[i2 + 1][j + 1] == 0) continue;
                int n = i2 - i;
                if(j - n >= 0) ans += tsum[i2][j - n + 1] - tsum[i + 1][j - n + 1] - tsum[i2][j - n] + tsum[i + 1][j - n];
                if(j + n < H + W) ans += tsum[i2][j + n + 1] - tsum[i + 1][j + n + 1] - tsum[i2][j + n] + tsum[i + 1][j + n];
            }
        }
    }
    cout << ans;
    
    return 0;
}