func_code_string: #include <bits/stdc++.h>   using namespace std;   using ll = long long;   template <class T, class U>   using Pa = pair<T, U>;   template <class T>   using vec = vector<T>;   template <class T>   using vvec = vector<vec<T>>;   template <typename Monoid, typename F>   class SegmentTree {    private:     int sz;     vector<Monoid> seg;     const F op;     const Monoid e;       public:     SegmentTree(int n, const F op, const Monoid &e) : op(op), e(e) {       sz = 1;       while (sz <= n) sz <<= 1;       seg.assign(2 * sz, e);     }     void set(int k, const Monoid &x) { seg[k + sz] = x; }     void build() {       for (int i = sz - 1; i > 0; i--) {         seg[i] = op(seg[2 * i], seg[2 * i + 1]);       }     }     void update(int k, const Monoid &x) {       k += sz;       seg[k] += x;       while (k >>= 1) {         seg[k] = op(seg[2 * k], seg[2 * k + 1]);       }     }     Monoid query(int l, int r) {       Monoid L = e, R = e;       for (l += sz, r += sz; l < r; l >>= 1, r >>= 1) {         if (l & 1) L = op(L, seg[l++]);         if (r & 1) R = op(seg[--r], R);       }       return op(L, R);     }     Monoid operator[](const int &k) const { return seg[k + sz]; }   };   int main() {     cin.tie(0);     ios::sync_with_stdio(false);     int N, M;     cin >> N >> M;     vvec<char> F(N, vec<char>(M));     vec<int> len(N + M);     for (int i = 0; i < N; i++)       for (int j = 0; j < M; j++) {         cin >> F[i][j];         len[i + j]++;       }     vvec<int> L(N, vec<int>(M, 0));     vvec<int> R = L, D = L;     for (int i = N - 1; i >= 0; i--) {       for (int j = 0; j < M; j++) {         int c = (F[i][j] ==  z );         if (!c) {           L[i][j] = 0;           D[i][j] = 0;         } else {           L[i][j] = 1 + (j != 0 ? L[i][j - 1] : 0);           D[i][j] = 1 + ((j != 0 && i != N - 1) ? D[i + 1][j - 1] : 0);         }       }       for (int j = M - 1; j >= 0; j--) {         int c = (F[i][j] ==  z );         if (!c)           R[i][j] = 0;         else           R[i][j] = 1 + (j != M - 1 ? R[i][j + 1] : 0);       }     }     auto op = [](ll a, ll b) { return a + b; };     vec<SegmentTree<ll, decltype(op)>> segs;     for (int l = 0; l < N + M - 1; l++) {       SegmentTree<ll, decltype(op)> seg(M, op, 0);       segs.push_back(seg);     }     ll ans = 0;     for (int j = M - 1; j >= 0; j--) {       for (int i = 0; i < N; i++) {         int y = j;         while (y >= 0 && y + R[i][y] - 1 == j) {           segs[i + y].update(y, 1);           y--;         }       }       for (int i = 0; i < N; i++) {         int a = min(L[i][j], D[i][j]);         ans += segs[i + j].query(j - a + 1, j + 1);       }     }     cout << ans <<   n ;   }   