Problem:
Score : 700 points

Problem Statement

There are some coins in the xy-plane.
The positions of the coins are represented by a grid of characters with H rows and W columns.
If the character at the i-th row and j-th column, s_{ij}, is #, there is one coin at point (i,j); if that character is ., there is no coin at point (i,j). There are no other coins in the xy-plane.

There is no coin at point (x,y) where 1\leq i\leq H,1\leq j\leq W does not hold.
There is also no coin at point (x,y) where x or y (or both) is not an integer.
Additionally, two or more coins never exist at the same point.

Find the number of triples of different coins that satisfy the following condition:

Choosing any two of the three coins would result in the same Manhattan distance between the points where they exist.

Here, the Manhattan distance between points (x,y) and (x',y') is |x-x'|+|y-y'|.
Two triples are considered the same if the only difference between them is the order of the coins.

Constraints

1 \leq H,W \leq 300

s_{ij} is # or ..

Input

Input is given from Standard Input in the following format:

H W
s_{11}...s_{1W}
:
s_{H1}...s_{HW}

Output

Print the number of triples that satisfy the condition.

Sample Input 1

5 4
#.##
.##.
#...
..##
...#

Sample Output 1

3

((1,1),(1,3),(2,2)),((1,1),(2,2),(3,1)) and ((1,3),(3,1),(4,4)) satisfy the condition.

Sample Input 2

13 27
......#.........#.......#..
#############...#.....###..
..............#####...##...
...#######......#...#######
...#.....#.....###...#...#.
...#######....#.#.#.#.###.#
..............#.#.#...#.#..
#############.#.#.#...###..
#...........#...#...#######
#..#######..#...#...#.....#
#..#.....#..#...#...#.###.#
#..#######..#...#...#.#.#.#
#..........##...#...#.#####

Sample Output 2

870

Solution in C# (Mono 4.6.2.0) (judge verdict: Time Limit Exceeded)

using System;
using System.Collections.Generic;
class Program
{
	static void Main(string[] args)
	{
		string[] str = Console.ReadLine().Split();
		int H = int.Parse(str[0]);
		int W = int.Parse(str[1]);
		int[,] A = new int[H,W];
		for(var i=0;i<H;i++){
			string str2 = Console.ReadLine();
			for(var j=0;j<W;j++){
				if(str2.Substring(j,1)=="#"){
					A[i,j] = 1;
				}
			}
		}
		int[,] D1 = new int[H+H*2+W*2,W+H*2+W*2];
		for(var i=0;i<H+W;i++){
			int sum = 0;
			for(var j=0;j<=i+H+W;j++){
				if(i-j>=0 && i-j<H && j>=0 && j<W){
					if(A[i-j,j] == 1){
						sum += 1;
					}
				}
				if(i-j>=H+H+W || j>=W+H+W){
					break;
				}
				D1[i-j+H+W,j+H+W] = sum;
			}
		}
		int[,] D2 = new int[H+H*2+W*2,W+H*2+W*2];
		for(var i=0;i<H+W;i++){
			int sum = 0;
			for(var j=0;j<=i+H+W;j++){
				if(j>=0 && j<H && W-1-i+j>=0 && W-1-i+j<W){
					if(A[j,W-1-i+j] == 1){
						sum += 1;
					}
				}
				if(j>=H+H+W || W-1-i+j >= W+H+W){
					break;
				}
				D2[j+H+W,W-1-i+j+H+W] = sum;
			}
		}
		for(var i=0;i<H+H*2+W*2;i++){
			string str5 = "";
			for(var j=0;j<W+H*2+W*2;j++){
				str5 += D2[i,j] + " ";
			}
			//Console.WriteLine(str5);
		}
		int ans = 0;
		for(var i=0;i<H;i++){
			for(var j=0;j<W;j++){
				int m = Math.Min(Math.Max(H,W),Math.Min(i,H-i)+Math.Min(j,W-j));
				for(var k=1;k<=m;k++){
					if(i-k>=0 && A[i-k,j] == 1 && i+k<H && A[i+k,j] == 1){
						if(j-k>=0 && A[i,j-k] == 1){
							ans += 1;
						}
						if(j+k<W && A[i,j+k] == 1){
							ans += 1;
						}
					}
					if(j-k>=0 && A[i,j-k] == 1 && j+k<W && A[i,j+k] == 1){
						if(i-k>=0 && A[i-k,j] == 1){
							ans += 1;
						}
						if(i+k<H && A[i+k,j] == 1){
							ans += 1;
						}
					}
					if(i-k>=0 && A[i-k,j] == 1 && j-k>=0 && A[i,j-k] == 1){
						ans += Math.Abs(D1[i+k+H+W,j+H+W] - D1[i+1+H+W,j+k-1+H+W]);
						//for(var l=1;l<k;l++){
						//	if(i+k-l<H && j+l<W && A[i+k-l,j+l] == 1){
						//		ans += 1;
						//	}
						//}
					}
					if(j-k>=0 && A[i,j-k] == 1 && i+k<H && A[i+k,j] == 1){
						ans += Math.Abs(D2[i-k+H+W,j+H+W] - D2[i-1+H+W,j+k-1+H+W]);
						//for(var l=1;l<k;l++){
						//	if(i-k+l>=0 && j+l<W && A[i-k+l,j+l] == 1){
						//		ans += 1;
						//	}
						//}
					}
					if(i+k<H && A[i+k,j] == 1 && j+k<W && A[i,j+k] == 1){
						ans += Math.Abs(D1[i+H+W,j-k+H+W] - D1[i-k+1+H+W,j-1+H+W]);
						//for(var l=1;l<k;l++){
						//	if(i-k+l>=0 && j-l>=0 && A[i-k+l,j-l] == 1){
						//		ans += 1;
						//	}
						//}
					}
					if(j+k<W && A[i,j+k] == 1 && i-k>=0 && A[i-k,j] == 1){
						ans += Math.Abs(D2[i+H+W,j-k+H+W] - D2[i+k-1+H+W,j-1+H+W]);
						//for(var l=1;l<k;l++){
						//	if(i+k-l<H && j-l>=0 && A[i+k-l,j-l] == 1){
						//		ans += 1;
						//	}
						//}
					}
				}
			}
		}
		Console.WriteLine(ans);
	}
}