#include <bits/stdc++.h>
using namespace std;
class PMA {
  int n;
  vector<vector<int> > next;
  vector<bitset<256> > match;
  vector<int> failure;

 public:
  PMA(const vector<string>& pattern) {
    next.assign(1, vector<int>(128, -1));
    match.assign(1, 0);
    for (unsigned i = 0; i < pattern.size(); ++i) {
      int curr = 0;
      for (unsigned j = 0; j < pattern[i].size(); ++j) {
        if (next[curr][pattern[i][j]] == -1) {
          next[curr][pattern[i][j]] = next.size();
          next.push_back(vector<int>(128, -1));
          match.push_back(0);
        }
        curr = next[curr][pattern[i][j]];
      }
      match[curr][i] = true;
    }
    n = next.size();
    failure.resize(n, 0);
    vector<int> node1(1, 0);
    while (!node1.empty()) {
      vector<int> node2;
      for (unsigned i = 0; i < node1.size(); ++i) {
        for (int j = 0; j < 128; ++j) {
          int s = node1[i];
          if (next[s][j] == -1) continue;
          node2.push_back(next[s][j]);
          int t = s;
          while (t != 0) {
            if (next[failure[t]][j] != -1) {
              failure[next[s][j]] = next[failure[t]][j];
              match[next[s][j]] |= match[next[failure[t]][j]];
              break;
            }
            t = failure[t];
          }
        }
      }
      node1.swap(node2);
    }
  }
  int size() { return n; }
  int transition(int curr, char c) {
    if (next[curr][c] != -1) return next[curr][c];
    if (curr == 0) return 0;
    return transition(failure[curr], c);
  }
  bitset<256> checkMatch(int curr) { return match[curr]; }
};
void search2D(const vector<string>& s, const vector<string>& t, vector<int>& y,
              vector<int>& x) {
  int h1 = s.size();
  int w1 = s[0].size();
  int h2 = t.size();
  int w2 = t[0].size();
  PMA pma(t);
  vector<vector<bitset<256> > > match(h1, vector<bitset<256> >(w1));
  for (int i = 0; i < h1; ++i) {
    int k = 0;
    for (int j = 0; j < w1; ++j) {
      k = pma.transition(k, s[i][j]);
      match[i][j] = pma.checkMatch(k);
    }
  }
  y.clear();
  x.clear();
  vector<bitset<256> > bs(w1, 0);
  for (int i = 0; i < h1; ++i) {
    for (int j = 0; j < w1; ++j) {
      bs[j] <<= 1;
      bs[j] |= 1;
      bs[j] &= match[i][j];
      if (bs[j][h2 - 1]) {
        y.push_back(i - h2 + 1);
        x.push_back(j - w2 + 1);
      }
    }
  }
}
void makeFractal(vector<string>& s, int k) {
  int n = s.size();
  bitset<4> bs(k);
  vector<string> t(2 * n, string(2 * n, '.'));
  for (int i = 0; i < 2 * n; ++i) {
    for (int j = 0; j < 2 * n; ++j) {
      if (s[i / 2][j / 2] == '*')
        t[i][j] = '*';
      else if (bs[i % 2 * 2 + j % 2])
        t[i][j] = '*';
    }
  }
  s.swap(t);
}
int main() {
  int h, w;
  cin >> h >> w;
  vector<string> s(h);
  for (int i = 0; i < h; ++i) cin >> s[i];
  int ret = 0;
  for (int k = 0; k < 16; ++k) {
    vector<string> t(1, ".");
    makeFractal(t, k);
    makeFractal(t, k);
    while (t.size() <= 500) {
      vector<int> y, x;
      search2D(s, t, y, x);
      ret += y.size();
      makeFractal(t, k);
    }
  }
  cout << ret << endl;
  return 0;
}
