The Tide is High
Difficulty: Hard

It is widely known that the Philippines has 7107 islands. But of course, that doesn't account for when some islands are covered during high tide and when some islands spring out during low tide. So it's definitely not a fixed number. Let's just say the Philippines has at least 7000 islands to be safe. In fact, there are a hundred islands nearby where you're sitting right now. Isn't that mind-blowing?

<img src="https://s3.amazonaws.com/hr-challenge-images/5493/1431360352-6b7504b826-Hundred_Island.jpg" title="Hundred_Island.jpg" />
(Image taken from [Wikipedia](http://en.m.wikipedia.org/wiki/File:Hundred_Island.jpg))

Now, you are given a map of part of the Philippines represented by `#` for each square kilometer of land and `~` for each square kilometer of water. As you might (or might have not) learned from your HeKaSi subject, an island is a contiguous land mass surrounded by water. For our purposes, we treat any contiguous land mass to be an island. We define the *productivity of an island* to be the square of the numerical value of its area (in square kilometers). And the *productivity of an area* to be the sum of the productivity of each island in that map. You can assume that everything around the map is water. During times when the tides are high, some parts of the islands may get covered in water. Hence, the productivity of an island (and consequently, the productivity of an area) may change when the tides change.

You are told that in the map given to you, the column of land with the lowest height submerge underwater during high tide. You are just told that if two land squares are in the same column, then they have the same height. Thus, being the genius that you are, you conclude that during high tide, exactly one column of land gets covered in water. Unfortunately, the map doesn't tell you how high each land is. And so, you decide to explore every case. What if the first column gets covered? What if the second column gets covered? And this is exactly what this problem asks of you. You're not that type of person who gives up just like that. So you decide to make a program that will address every possibility.

<img src="https://s3.amazonaws.com/hr-challenge-images/5493/1431339437-bcffe24005-TheTideisHigh.jpg" title="The Tide is High.jpg" />

Input Format:
The first line of input contains $T$, the number of test cases. The following lines describe the test cases.

The first line of each test case contains two integers $W$ and $L$ denoting the width and the length of the map. The next $W$ lines each contain $L$ characters where each character is either a `#` or a `~`, describing the area.

Output Format:
For each test case, output a single line containing $L$ integers, where the $x^{\text{th}}$ integer is the productivity of the area *during high tide* if the $x^{\text{th}}$ column of land has the lowest height.

**Constraints**  

$1 \le T \le 20$  
$L \ge 1$  
$W \ge 1$  

**Subtask 1** (11 points each):  
$1 \le L\cdot W \le 1000$  
Every island is a long flat island, i.e. it consists of a sequence of contiguous `#` tiles on a row, without land tiles immediately above or below it.  

**Subtask 2** (14 points each):  
$1 \le L\cdot W \le 1000$  

**Subtask 3** (25 points each):  
$1 \le L\cdot W \le 100000$  


Sample Input:
    4
    3 2
    ~~
    ~~
    ~~
    3 3
    ~~~
    ~#~
    ~~~
    5 7
    ~~~~~~~
    #######
    ~~~~~~~
    ~~~~##~
    ####~~~
    7 15
    ~~~~~~~~~~~~~~~
    ~#~~#~~##~~###~
    ~##~#~#~~#~~#~~
    ~#~##~#~~#~~#~~
    ~#~~#~#~~#~~#~~
    ~#~~#~~##~~###~
    ~~~~~~~~~~~~~~~


Sample Output:
    0 0
    1 0 1
    49 35 29 31 37 43 56
    179 144 168 168 144 179 170 173 173 170 179 147 102 147 179


Python 3 starter code:


Reference solution (C++):
```c++
#include <stdio.h>
#define L 100011
#define ll long long

char g[L];
ll lps[L];
ll rps[L];
int parent[L];
int size[L];

int find(int n) {
    return parent[n] < 0 ? n : parent[n] = find(parent[n]);
}

void onion(int i, int j) {
    if (parent[i] == parent[j]) {
        parent[i]--;
    }
    if (parent[i] > parent[j]) {
        parent[i] = j;
        size[j] += size[i];
    } else {
        parent[j] = i;
        size[i] += size[j];
    }
}


int main() {
    int z;
    scanf("%d", &z);
    while (z--) {
        int w, l;
        scanf("%d%d", &w, &l);
        for (int i = 0; i < w; i++) {
            scanf("%s", g + i*l);
        }

        ll pd;
        #define attach(_ni,_nj) do {\
                int ni = (_ni);\
                int nj = (_nj);\
                if (g[ni*l+nj] == '#') {\
                    int fd1 = find( i*l+ j);\
                    int fd2 = find(ni*l+nj);\
                    if (fd1 != fd2) {\
                        ll sz1 = size[fd1];\
                        ll sz2 = size[fd2];\
                        ll sz = sz1 + sz2;\
                        pd += sz*sz - sz1*sz1 - sz2*sz2;;\
                        onion(fd1,fd2);\
                    }\
                }\
            } while (0)

        pd = lps[0] = 0;
        for (int j = 0; j < l; j++) {
            for (int i = 0; i < w; i++) {
                if (g[i*l+j] == '#') {
                    size[i*l+j] = 1;
                    parent[i*l+j] = -1;
                    pd++;
                    if (i > 0) {
                        attach(i-1, j);
                    }
                    if (j > 0) {
                        attach(i, j-1);
                    }
                }
            }
            lps[j+1] = pd;
        }

        pd = rps[l] = 0;

        for (int j = l-1; j >= 0; j--) {
            for (int i = 0; i < w; i++) {
                if (g[i*l+j] == '#') {
                    size[i*l+j] = 1;
                    parent[i*l+j] = -1;
                    pd++;
                    if (i > 0) {
                        attach(i-1, j);
                    }
                    if (j < l-1) {
                        attach(i, j+1);
                    }
                }
            }
            rps[j] = pd;
        }

        for (int x = 0; x < l; x++) {
            if (x) printf(" ");
            printf("%lld", lps[x] + rps[x+1]);
        }
        printf("\n");
    }
}
```