#include <iostream>
#include <string>
#include <vector>
#include <queue>
#include <deque>
#include <algorithm>
#include <set>
#include <map>
#include <bitset>
#include <cmath>
#include <functional>
#include <iomanip>
#define vll vector<ll>
#define vvvl vector<vvl>
#define vvl vector<vector<ll>>
#define VV(a, b, c, d) vector<vector<d> >(a, vector<d>(b, c))
#define VVV(a, b, c, d) vector<vvl>(a, vvl(b, vll (c, d)));
#define re(c, b) for(ll c=0;c<b;c++)
#define all(obj) (obj).begin(), (obj).end()
typedef long long int ll;
typedef long double ld;
using namespace std;

struct Accum2D{
  map<ll, ll> x, y;
  ll mode = 1;
  vvl dat;
  vvl v;
  Accum2D(vvl point, ll h=0, ll w=0){
    if(point.size()==0) mode=0;
    for(int i=0;i<point.size();i++){
      if(x.find(point[i][0])==x.end()) x.emplace(point[i][0], 0);
      if(y.find(point[i][1])==y.end()) y.emplace(point[i][1], 0);
    }
    ll k = 0;
    for(auto itr = x.begin();itr!=x.end();itr++) (*itr).second = k, k++;
    k = 0;
    for(auto itr = y.begin();itr!=y.end();itr++) (*itr).second = k, k++;
    if(mode==1) {
      dat.resize(x.size(), vll(y.size(), 0));
      v.resize(x.size(), vll(y.size(), 0));
    }else {
      dat.resize(h+1, vll(w+1, 0));
      v.resize(h+1, vll(w+1, 0));
    }
  }
  void insert(ll a, ll b, ll x){
    dat[a][b] = x;
  }
  void calc(){
    for(int j=0;j<v[0].size();j++){
      for(int i=0;i<v.size();i++){
        v[i][j] = (i==0?0:v[i-1][j]) + dat[i][j];
      }
    }
    for(int i=0;i<v.size();i++){
      for(int j=0;j<v[0].size();j++){
        v[i][j] = v[i][j] + (j==0?0:v[i][j-1]);
      }
    }
  }
  ll get(ll a, ll b, ll c, ll d){
    if(a>c) swap(a, c);
    if(b>d) swap(b, d);
    if(mode==1){
      a = x.at(a), b = y.at(b);
      c = x.at(c), d = y.at(d);
    }
    ll r = v[c][d];
    ll u = (a==0?0:v[a-1][d]);
    ll l = (b==0?0:v[c][b-1]);
    ll o = (a==0||b==0?0:v[a-1][b-1]);
    return r - u - l + o;
  }
};
int main(int argc, char const *argv[]) {
  ll h, w;std::cin >> h >> w;
  ll N = max(h, w);
  vvl point;
  vvl dat = VV(2*N, 2*N, 0, ll);
  for(int i=0;i<h;i++){
    string s;std::cin >> s;
    for(int j=0;j<w;j++) if(s[j]=='#') point.push_back(vll{i-j+N, i+j});
  }
  for(auto p:point) dat[p[0]][p[1]] = 1;

  /*
  for(int i=0;i<2*N;i++){
    for(int j=0;j<2*N;j++) std::cout << dat[i][j];
    std::cout << '\n';
  }
  */
  Accum2D ac(vvl(), 2*N, 2*N);
  re(i, 2*N) re(j, 2*N) ac.insert(i, j, dat[i][j]);
  ac.calc();

  ll ans = 0;
  for(int i=0;i<2*N;i++){
    for(int j=0;j<2*N;j++){
      for(int d=1;max(i, j)+d<2*N;d++){
        ll x=0, y=0, z=0;
        //下の角 or 右の角
        if(dat[i+d][j+d]){
          if(dat[i+d][j]) x = ac.get(i, j+1, i, j+d-1);
          if(dat[i][j+d]) y = ac.get(i+1, j, i+d-1, j);
          if(dat[i][j+d]&&dat[i+d][j]) z = 1;
          ans += x + y + z;
        }
        if(!dat[i][j]) continue;
        if(dat[i+d][j]) x = ac.get(i+1, j+d, i+d, j+d);//i+1,j+d~i+d,j+d
        if(dat[i][j+d]) y = ac.get(i+d, j+1, i+d, j+d);//i+d,j+1~i+d,j+d
        if(dat[i+d][j]&&dat[i][j+d]) z = 1;
        //if(x||y||z) std::cout << i << " " << j << " " << d << x+y+z << '\n';
        ans += x + y + z;
      }
    }
  }
  std::cout << ans << '\n';
  return 0;
}


Measured memory_bytes: 13744