#include <algorithm>
#include <array>
#include <bitset>
#include <complex>
#include <functional>
#include <iomanip>
#include <iostream>
#include <map>
#include <numeric>
#include <set>
#include <stack>
#include <unordered_map>
#include <unordered_set>
#include <queue>

using namespace std;

struct BoolName : numpunct<char> {
  string t, f;
  BoolName (string t = "Yes", string f = "No") : t(t), f(f) {}
  string do_truename() const {return t;}
  string do_falsename() const {return f;}
};

struct Initializer {
  Initializer() {
    cin.tie(0);
    ios::sync_with_stdio(0);
    cout << fixed << setprecision(15) << boolalpha;
    cout.imbue(locale(cout.getloc(), new BoolName));
  }
} initializer;

template<typename T> istream& operator>>(istream &s, vector<T> &v) {
  for (T &t : v) s >> t;
  return s;
}

template<typename T> ostream& operator<<(ostream &s, const vector<T> &v) {
  for (const T &t : v) s << t << endl;
  return s;
}

int main() {
  constexpr int N = 600;
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  cin >> s;
  vector<vector<bool>> v(N, vector<bool>(N));
  for (int i = 0; i < h; ++i) {
    for (int j = 0; j < w; ++j) {
      v[i - j + w][i + j] = (s[i][j] == '#');
    }
  }
  int64_t res = 0;
  for (int x = 0; x < 4; ++x) {
    for (int d = 2; d < N; d += 2) {
      for (int i = 0; i + d < N; ++i) {
        int c = 0;
        for (int j = 0; j < d; ++j) c += v[i + d][j];
        for (int j = 0; j + d < 600; ++j) {
          if (v[i][j] && v[i][j + d]) res += c;
          c += v[i + d][j + d];
          c -= v[i + d][j];
        }
      }
    }
    auto u = v;
    for (int i = 0; i < N; ++i) {
      for (int j = 0; j < N; ++j) {
        v[i][j] = u[N - j - 1][i];
      }
    }
  }
  cout << res << endl;
}

