#include <deque>
#include <cstdio>
#include <cstring>
#include <algorithm>

using namespace std;
const int Max_N(1550);
const int INF(0X3F3F3F3F); 
typedef long long int LL;

int N, A[Max_N][Max_N], U[Max_N][Max_N], D[Max_N][Max_N];
int Left[Max_N][Max_N], Right[Max_N][Max_N], _Top[Max_N][Max_N], _Bottom[Max_N][Max_N], Top[Max_N], Bottom[Max_N], MeetingPoint[Max_N][Max_N]; 
int V1[Max_N], V2[Max_N][Max_N], V3[Max_N][Max_N], V4[Max_N][Max_N]; 
int Min[Max_N][Max_N], Max[Max_N][Max_N], Only[Max_N];
LL Ans;
char input[Max_N];

inline void cmin(int &a, int b)
{
	a = min(a, b);
}

inline void cmax(int &a, int b)
{
	a = max(a, b);
}

inline int BothReachable(int a, int b, int l)
{
	cmin(l, min(Bottom[a], Bottom[b]));
	if (MeetingPoint[a][b] > l)
		return 0;
	return V1[l] - V2[l][a] - V3[l][b] + V4[a][b];
}

deque<int> Q;
int SUM;

inline void insert(int y)
{
	SUM += (Only[y] = BothReachable(y, y, Bottom[y]));
	for (int Jp, Jp1 = -1, temp;Q.empty() == false;)
	{
		Jp = Q.back();
		temp = BothReachable(Jp, y, min(Bottom[Jp], Bottom[y]));
		if (Jp1 != -1)
			temp -= BothReachable(Jp, y, min(Bottom[Jp1], Bottom[y]));
		SUM -= Only[Jp], SUM += (Only[Jp] -= temp), Jp1 = Jp;
		if (Bottom[Jp] > Bottom[y])
			break;
		else
			Q.pop_back(); 
	}
	Q.push_back(y);
}

inline void erase(int y)
{
	SUM -= Only[y];
	while (Q.empty() == false && Q.front() <= y)
		Q.pop_front();
}

void solve(int xl, int xr, int yl, int yr)
{
	int H = xr - xl + 1, W = yr - yl + 1, U_H, D_H;
	if (H == 1 && W == 1)
		return;
	if (H >= W)
	{
		U_H = (H >> 1) + (H & 1), D_H = (H >> 1);
		solve(xl, xl + U_H - 1, yl, yr), solve(xl + U_H, xr, yl, yr);
		for (int i = 1;i <= U_H;++i)
			for (int j = 1;j <= W;++j)
				U[i][j] = A[xl + i - 1][yl + j - 1];
		for (int i = U_H + 1;i <= H;++i)
			for (int j = 1;j <= W;++j)
				D[i - U_H][j] = A[xl + i - 1][yl + j - 1];
	}
	else
	{
		U_H = (W >> 1) + (W & 1), D_H = (W >> 1);
		solve(xl, xr, yl, yl + U_H - 1), solve(xl, xr, yl + U_H, yr);
		for (int i = 1;i <= U_H;++i)
			for (int j = 1;j <= H;++j)
				U[i][j] = A[xl + j - 1][yl + i - 1];
		for (int i = U_H + 1;i <= W;++i)
			for (int j = 1;j <= H;++j)
				D[i - U_H][j] = A[xl + j - 1][yl + i - 1];
		W = H;
	}
	for (int i = 1;i <= D_H;++i)
		for (int j = 1;j <= W;++j)
		{
			Left[i][j] = +INF, Right[i][j] = -INF;
			if (D[i][j] != -1)
			{
				if (i == 1)
					Left[i][j] = Right[i][j] = j;
				if (i - 1 >= 1)
					cmin(Left[i][j], Left[i - 1][j]), cmax(Right[i][j], Right[i - 1][j]);
				if (j - 1 >= 1)
					cmin(Left[i][j], Left[i][j - 1]), cmax(Right[i][j], Right[i][j - 1]);
			}
		}
	for (int i = D_H;i >= 1;--i)
		for (int j = W;j >= 1;--j)
		{
			_Bottom[i][j] = -INF;
			if (D[i][j] != -1)
			{
				_Bottom[i][j] = i;
				if (i + 1 <= D_H)
					cmax(_Bottom[i][j], _Bottom[i + 1][j]);
				if (j + 1 <= W)
					cmax(_Bottom[i][j], _Bottom[i][j + 1]);
			}
		}
	for (int j = 1;j <= W;++j)
		Bottom[j] = _Bottom[1][j];
	for (int j = 1;j <= W;++j)
		U[U_H + 1][j] = D[1][j];
	for (int i = 1;i <= U_H + 1;++i)
		for (int j = 1;j <= W;++j)
		{
			_Top[i][j] = +INF;
			if (U[i][j] != -1)
			{
				if (i != U_H + 1)
					_Top[i][j] = i;
				if (i - 1 >= 1)
					cmin(_Top[i][j], _Top[i - 1][j]);
				if (j - 1 >= 1)
					cmin(_Top[i][j], _Top[i][j - 1]);
			}
		}
	for (int j = 1;j <= W;++j)
		Top[j] = _Top[U_H + 1][j];
	for (int a = 1;a <= W;++a)
	{
		MeetingPoint[a][a] = 1;
		for (int b = a + 1;b <= W;++b)
			MeetingPoint[a][b] = -1;
	}
	for (int i = 1;i <= D_H;++i)
		for (int j = 1;j <= W;++j)
			for (int b = Right[i][j];b > Left[i][j];--b)
			{
				if (MeetingPoint[Left[i][j]][b] != -1)
					break;
				for (int a = Left[i][j];a < b;++a)
				{
					if (MeetingPoint[a][b] != -1)
						break;
					if (i <= min(Bottom[a], Bottom[b]))
						MeetingPoint[a][b] = i;
					else
						MeetingPoint[a][b] = +INF;
				}
			}
	for (int a = 1;a <= W;++a)
		for (int b = a + 1;b <= W;++b)
			if (MeetingPoint[a][b] == -1)
				MeetingPoint[a][b] = +INF;
	for (int x = 0;x <= D_H + 1;++x)
	{
		V1[x] = 0;
		for (int y = 0;y <= W + 1;++y)
			V2[x][y] = V3[x][y] = 0;
	}
	for (int a = 0;a <= W + 1;++a)
		for (int b = 0;b <= W + 1;++b)
			V4[a][b] = 0;
	for (int x = 1;x <= D_H;++x)
		for (int y = 1;y <= W;++y)
			if (Left[x][y] <= Right[x][y])
			{
				V1[x] += D[x][y];
				V2[x][Left[x][y] - 1] += D[x][y];
				V3[x][Right[x][y] + 1] += D[x][y];
				V4[Left[x][y] - 1][Right[x][y] + 1] += D[x][y];
			}
	for (int l = 1;l <= D_H;++l)
	{
		V1[l] += V1[l - 1];
		for (int a = W;a >= 0;--a)
			V2[l][a] += V2[l][a + 1];
		for (int b = 1;b <= W + 1;++b)
			V3[l][b] += V3[l][b - 1];
		for (int ab = 0;ab <= W + 1;++ab)
			V2[l][ab] += V2[l - 1][ab], V3[l][ab] += V3[l - 1][ab];
	}
	for (int a = W;a >= 0;--a)
		for (int b = 1;b <= W + 1;++b)
			V4[a][b] += V4[a + 1][b] + V4[a][b - 1] - V4[a + 1][b - 1];
	for (int i = U_H + 1;i >= 1;--i)
		for (int j = W;j >= 1;--j)
		{
			Min[i][j] = +INF, Max[i][j] = -INF;
			if (U[i][j] != -1)
			{
				if (i == U_H + 1)
					Min[i][j] = Max[i][j] = j;
				if (i + 1 <= U_H + 1)
					cmin(Min[i][j], Min[i + 1][j]), cmax(Max[i][j], Max[i + 1][j]);
				if (j + 1 <= W)
					cmin(Min[i][j], Min[i][j + 1]), cmax(Max[i][j], Max[i][j + 1]);
			}
		}
	for (int i = 1;i <= U_H;++i)
	{
		Q = deque<int>(), SUM = 0;
		for (int j = 1, l = -1, r = -1;j <= W;++j)
		{
			if (Min[i][j] > Max[i][j])
				continue;
			if (l == -1 && r == -1)
			{
				for (int y = Min[i][j];y <= Max[i][j];++y)
					if (Top[y] <= i)
						insert(y);
				l = Min[i][j], r = Max[i][j];
			}
			else
			{
				while (r < Max[i][j])
				{
					++r;
					if (Top[r] <= i)
						insert(r);
				}
				while (l < Min[i][j])
				{
					if (Top[l] <= i)
						erase(l);
					++l;
				}
			}
			Ans += U[i][j] * 1LL * SUM;
		}
	}
}

int main()
{ 
	scanf("%d", &N);
	for (int i = 1;i <= N;++i)
	{
		scanf("%s", input + 1);
		for (int j = 1;j <= N;++j)
			if ('0' <= input[j] && input[j] <= '9')
				A[i][j] = input[j] - '0';
			else
				A[i][j] = -1;
	}
	solve(1, N, 1, N);
	printf("%lld", Ans);
	return 0;
}

Measured memory_bytes: 91264