using System;
using System.Collections.Generic;
using System.Linq;
class Program
{
static string InputPattern = "InputX";
static List<string> GetInputList()
{
var WillReturn = new List<string>();
if (InputPattern == "Input1") {
WillReturn.Add("5 5");
WillReturn.Add(".....");
WillReturn.Add(".###.");
WillReturn.Add(".###.");
WillReturn.Add(".###.");
WillReturn.Add(".....");
//4
}
else {
string wkStr;
while ((wkStr = Console.ReadLine()) != null) WillReturn.Add(wkStr);
}
return WillReturn;
}
static char[,] mBanArr;
static int UB_X;
static int UB_Y;
struct VectorInfoDef
{
internal int X1;
internal int Y1;
internal int X2;
internal int Y2;
}
static void Main()
{
List<string> InputList = GetInputList();
mBanArr = CreateBanArr(InputList.Skip(1));
UB_X = mBanArr.GetUpperBound(0);
UB_Y = mBanArr.GetUpperBound(1);
// 盤面の外周のベクトルのList
var VectorInfoList = DeriveGaisyuuVectorList();
// 内積が0のベクトルのペアの数が解
long Answer = 0;
for (int I = 0; I <= VectorInfoList.Count - 1; I++) {
for (int J = I + 1; J <= VectorInfoList.Count - 1; J++) {
// 単位ベクトルなので、始点と終点の少なくとも1点が一致してれば交点あり
if (HasKouten(VectorInfoList[I], VectorInfoList[J]) == false) {
continue;
}
if (DeriveDot(VectorInfoList[I], VectorInfoList[J]) == 0) {
Answer++;
}
}
}
Console.WriteLine(Answer);
}
// ベクトル同士が交点を持つかを判定
static bool HasKouten(VectorInfoDef pVect1, VectorInfoDef pVect2)
{
if (pVect1.X1 == pVect2.X1 && pVect1.Y1 == pVect2.Y1) return true;
if (pVect1.X1 == pVect2.X1 && pVect1.Y2 == pVect2.Y2) return true;
if (pVect1.X2 == pVect2.X2 && pVect1.Y1 == pVect2.Y1) return true;
if (pVect1.X2 == pVect2.X2 && pVect1.Y2 == pVect2.Y2) return true;
return false;
}
// ベクトル同士の内積を求める
static long DeriveDot(VectorInfoDef pVect1, VectorInfoDef pVect2)
{
long DiffX1 = pVect1.X1 - pVect1.X2;
long DiffY1 = pVect1.Y1 - pVect1.Y2;
long DiffX2 = pVect2.X1 - pVect2.X2;
long DiffY2 = pVect2.Y1 - pVect2.Y2;
return DiffX1 * DiffX2 + DiffY1 * DiffY2;
}
// 盤面の外周のベクトルのListを返す
static List<VectorInfoDef> DeriveGaisyuuVectorList()
{
var WillReturn = new List<VectorInfoDef>();
Func<int, int, bool> IsGaisyuuFunc = (pX, pY) =>
{
if (pX < 0 || UB_X < pX) return true;
if (pY < 0 || UB_Y < pY) return true;
return mBanArr[pX, pY] == '.';
};
for (int LoopX = 0; LoopX <= UB_X; LoopX++) {
for (int LoopY = 0; LoopY <= UB_Y; LoopY++) {
if (mBanArr[LoopX, LoopY] != '#') continue;
// 4方向のチェック
if (IsGaisyuuFunc(LoopX, LoopY - 1)) {
WillReturn.Add(
new VectorInfoDef() { X1 = LoopX, Y1 = LoopY, X2 = LoopX + 1, Y2 = LoopY });
}
if (IsGaisyuuFunc(LoopX, LoopY + 1)) {
WillReturn.Add(
new VectorInfoDef() { X1 = LoopX, Y1 = LoopY + 1, X2 = LoopX + 1, Y2 = LoopY + 1 });
}
if (IsGaisyuuFunc(LoopX - 1, LoopY)) {
WillReturn.Add(
new VectorInfoDef() { X1 = LoopX, Y1 = LoopY, X2 = LoopX, Y2 = LoopY + 1 });
}
if (IsGaisyuuFunc(LoopX + 1, LoopY)) {
WillReturn.Add(
new VectorInfoDef() { X1 = LoopX + 1, Y1 = LoopY, X2 = LoopX + 1, Y2 = LoopY + 1 });
}
}
}
return WillReturn;
}
////////////////////////////////////////////////////////////////
// IEnumerable<string>をcharの2次元配列に設定する
////////////////////////////////////////////////////////////////
static char[,] CreateBanArr(IEnumerable<string> pStrEnum)
{
var StrList = pStrEnum.ToList();
if (StrList.Count == 0) {
return new char[0, 0];
}
int UB_X = StrList[0].Length - 1;
int UB_Y = StrList.Count - 1;
char[,] WillReturn = new char[UB_X + 1, UB_Y + 1];
for (int Y = 0; Y <= UB_Y; Y++) {
for (int X = 0; X <= UB_X; X++) {
WillReturn[X, Y] = StrList[Y][X];
}
}
return WillReturn;
}
}