Problem:
Score : 600 points

Problem Statement

There is a board with N rows and M columns.
The information of this board is represented by N strings S_1,S_2,\ldots,S_N.
Specifically, the state of the square at the i-th row from the top and the j-th column from the left is represented as follows:

S_{i,j}=. : the square is empty.

S_{i,j}=# : an obstacle is placed on the square.

S_{i,j}=o : a piece is placed on the square.

Yosupo repeats the following operation:

Choose a piece and move it to its right adjecent square or its down adjacent square.
Moving a piece to squares with another piece or an obstacle is prohibited.
Moving a piece out of the board is also prohibited.

Yosupo wants to perform the operation as many times as possible.
Find the maximum possible number of operations.

Constraints

1 \leq N \leq 50

1 \leq M \leq 50

S_i is a string of length M consisting of ., # and o.

1 \leq ( the number of pieces )\leq 100.
In other words, the number of pairs (i, j) that satisfy S_{i,j}=o is between 1 and 100, both inclusive.

Input

Input is given from Standard Input in the following format:

N M
S_1
S_2
\vdots
S_N

Output

Print the maximum possible number of operations in a line.

Sample Input 1

3 3
o..
...
o.#

Sample Output 1

4

Yosupo can perform operations 4 times as follows:

o.. .o. ..o ... ...
... -> ... -> ... -> ..o -> ..o
o.# o.# o.# o.# .o#

Sample Input 2

9 10
.#....o#..
.#..#..##o
.....#o.##
.###.#o..o
#.#...##.#
..#..#.###
#o.....#..
....###..o
o.......o#

Sample Output 2

24

Solution in C# (Mono-mcs 6.8.0.105) (judge verdict: Wrong Answer)

using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		string[] str = Console.ReadLine().Split();
		int N = int.Parse(str[0]);
		int M = int.Parse(str[1]);
		var A = new List<int[]>();
		int[,]B = new int[N,M];
		for(var i=0;i<N;i++){
			string str2 = Console.ReadLine();
			for(var j=0;j<M;j++){
				string s = str2.Substring(j,1);
				if(s=="o"){
					A.Add(new int[2]{i,j});
					B[i,j] = -1;
				} else if(s=="#"){
					B[i,j] = 1;
				}
			}
		}
		int ans = 0;
		while(true){
			int a1 = -1;
          	int am = -1;
			bool flag = false;
			for(var i=0;i<A.Count;i++){
				int cta = 0;
				int ctb = 0;
				if(A[i][0]<N-1 && B[A[i][0]+1,A[i][1]] == 0){
					cta++;
				} 
				if(A[i][1]<M-1 && B[A[i][0],A[i][1]+1] == 0){
					ctb++;
				}
				if(cta==1 && ctb==0){
					B[A[i][0],A[i][1]]=0;
					A[i][0] += 1;
					B[A[i][0],A[i][1]]=-1;
					ans++;
					flag = true;
                  	//Console.Error.WriteLine(1);
					break;
				} else if(cta==0 && ctb==1){
					B[A[i][0],A[i][1]]=0;
					A[i][1] += 1;
					B[A[i][0],A[i][1]]=-1;
					flag = true;
					ans++;
                  //Console.Error.WriteLine(2);
					break;
				} else if(cta==1 && ctb==1){
                  	if(A[i][0]*N+A[i][1] > am){
                      	am = A[i][0]*N+A[i][1];
                      	a1 = i;
                    }
                }
			}
			if(!flag){
              	if(a1==-1){
                  break;
                } else {
					int[,]C = new int[N,M];
					for(var i=0;i<N;i++){
						for(var j=0;j<M;j++){
							C[i,j] = 999999;
						}
					}
					var list = new List<int>();
                  	//Console.Error.WriteLine(A[a1][0]*M+A[a1][1]+" "+A[a1][0]+" "+A[a1][1]);
					list.Add(A[a1][0]*M+A[a1][1]);
					C[A[a1][0],A[a1][1]]=0;
					while(list.Count>0){
						var list2 = new List<int>(list);
						list.Clear();
						foreach(var j in list2){
							int i1 = j/M;
							int j1 = j%M;
							if(i1<N-1 && B[i1+1,j1] == 0 && C[i1+1,j1]>C[i1,j1]+1){
								C[i1+1,j1] = C[i1,j1]+1;
								list.Add((i1+1)*M+j1);
							}
							if(j1<M-1 && B[i1,j1+1] == 0 && C[i1,j1+1]>C[i1,j1]+1){
								C[i1,j1+1] = C[i1,j1]+1;
								list.Add((i1)*M+j1+1);
							}
						}
					}
					int maxij = -1;
					int maxa = -1;
					for(var i=0;i<N;i++){
						for(var j=0;j<M;j++){
							if(C[i,j] > maxa && C[i,j] < 999999){
								maxij = i*M+j;
								maxa = C[i,j];
							}
						}
					}
					int c1i = maxij/M;
					int c1j = maxij%M;
					while(C[c1i,c1j] > 1){
                      	//Console.Error.WriteLine(C[c1i,c1j]+" "+C[c1i-1,c1j]+" "+c1i+" "+c1j);
						if(c1i>0 && C[c1i-1,c1j] == C[c1i,c1j] - 1){
							c1i--;
						} else if(c1j>0 && C[c1i,c1j-1] == C[c1i,c1j] - 1){
							c1j--;
						}
					}
					B[A[a1][0],A[a1][1]]=0;
					A[a1][0] = c1i;
					A[a1][1] = c1j;
					B[A[a1][0],A[a1][1]]=-1;
					ans++;
                  //Console.Error.WriteLine(3);
                }
			}
		}
      	for(var i=0;i<N;i++){
          	for(var j=0;j<M;j++){
              	Console.Error.Write(B[i,j]);
            }
          	Console.Error.WriteLine();
        }
		Console.WriteLine(ans);
	}
}