#include <bits/stdc++.h>
using namespace std;
using ll = long long;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int n, m;
if (!(cin >> n >> m)) return 0;
vector<string> a(n);
for (int i = 0; i < n; ++i) cin >> a[i];
// U[i][j]: số ô '.' liên tiếp lên trên (tính từ hàng 1..n, cột 1..m)
vector<vector<int>> U(n, vector<int>(m, 0));
for (int j = 0; j < m; ++j) {
for (int i = 0; i < n; ++i) {
if (a[i][j] == '.') {
U[i][j] = (i == 0 ? 1 : U[i-1][j] + 1);
} else U[i][j] = 0;
}
}
// diff arrays per Hvalue (Hvalue from 0..n). We'll use indices 1..m for widths.
// For each Hval we keep coefDiff and constDiff (for linear function alpha*w + beta)
int Hmax = n;
vector<vector<ll>> coefDiff(Hmax+1, vector<ll>(m+3, 0));
vector<vector<ll>> constDiff(Hmax+1, vector<ll>(m+3, 0));
// Process each row as bottom
for (int i = 0; i < n; ++i) {
vector<int> H(m);
for (int j = 0; j < m; ++j) H[j] = U[i][j];
// prev less (strict)
vector<int> L(m);
{
vector<int> st;
for (int j = 0; j < m; ++j) {
while (!st.empty() && H[st.back()] >= H[j]) st.pop_back();
L[j] = st.empty() ? -1 : st.back();
st.push_back(j);
}
}
// next less or equal
vector<int> R(m);
{
vector<int> st;
for (int j = m-1; j >= 0; --j) {
while (!st.empty() && H[st.back()] > H[j]) st.pop_back();
R[j] = st.empty() ? m : st.back();
st.push_back(j);
}
}
for (int j = 0; j < m; ++j) {
int hval = H[j];
if (hval <= 0) continue; // không đóng góp nếu U=0
int leftIndex = L[j]; // L
int rightIndex = R[j]; // R
int S = rightIndex - leftIndex - 1; // độ dài đoạn mà j là minimum
// A = số ô có thể lấy bên trái (a từ 0..A)
int A = j - leftIndex - 1;
// B = số ô có thể lấy bên phải (b từ 0..B)
int B = rightIndex - j - 1;
int small = min(A, B);
int large = max(A, B);
// Ranges in w (1-based widths)
// Range1: w in [1 .. small+1], value = w (linear with coef=1, const=0)
int l1 = 1, r1 = small + 1;
if (l1 <= r1) {
coefDiff[hval][l1] += 1;
coefDiff[hval][r1 + 1] -= 1;
// const 0 -> no change
}
// Range2: w in [small+2 .. large+1], value = small+1 (constant)
int l2 = small + 2, r2 = large + 1;
if (l2 <= r2) {
constDiff[hval][l2] += (small + 1);
constDiff[hval][r2 + 1] -= (small + 1);
}
// Range3: w in [large+2 .. S], value = S - w + 1 = (-1)*w + (S+1)
int l3 = large + 2, r3 = S;
if (l3 <= r3) {
coefDiff[hval][l3] += -1;
coefDiff[hval][r3 + 1] -= -1;
constDiff[hval][l3] += (S + 1);
constDiff[hval][r3 + 1] -= (S + 1);
}
}
}
// Now build Smax[Hval][w] by prefixing diffs, then suffix by H to get ans[h][w]
vector<vector<ll>> ans(n+1, vector<ll>(m+1, 0)); // 1-based h and w
vector<ll> sumW(m+1, 0); // suffix accumulator for widths
// iterate Hval from high to low, produce its Smax row and add to running sumW to get ans[Hval][*]
for (int Hval = Hmax; Hval >= 1; --Hval) {
ll prefCoef = 0, prefConst = 0;
for (int w = 1; w <= m; ++w) {
prefCoef += coefDiff[Hval][w];
prefConst += constDiff[Hval][w];
ll S = prefCoef * (ll)w + prefConst; // sum of F_j(w) for j with H[j] == Hval
sumW[w] += S; // add to suffix (H' >= current Hval)
ans[Hval][w] = sumW[w];
}
}
// For h that have no direct Hval (e.g., 0) ans will be zero; output h=1..n
// print as sample: each row h (1..n) print m numbers (w=1..m) with spaces and trailing space
for (int h = 1; h <= n; ++h) {
for (int w = 1; w <= m; ++w) {
cout << ans[h][w];
if (w < m) cout << ' ';
else cout << ' ';
}
cout << '\n';
}
return 0;
}