#include <bits/stdc++.h>

using namespace std;

typedef long long ll;

const int MAX_N = 1505, INF = 1e4;

void chkmin(int &a, int b) { a = min(a, b); }
void chkmax(int &a, int b) { a = max(a, b); }

ll ans;

vector<vector<int>> flip(vector<vector<int>> grid) {
    int n = grid.size(), m = grid[0].size();
    vector<vector<int>> res(m, vector<int>(n));
    for (int i = 0; i < n; i++)
        for (int j = 0; j < m; j++)
            res[j][i] = grid[i][j];
    return res;
}

int left_u[MAX_N][MAX_N], right_u[MAX_N][MAX_N], left_l[MAX_N][MAX_N], right_l[MAX_N][MAX_N];
int bottom[MAX_N][MAX_N], top[MAX_N][MAX_N];
int sum_depth[MAX_N], sum_depth_left[MAX_N][MAX_N], sum_depth_right[MAX_N][MAX_N], sum_left_right[MAX_N][MAX_N];
int meet_point[MAX_N][MAX_N];
int only[MAX_N], que_all[MAX_N], qa_fi, qa_la, que_key[MAX_N], qk_fi, qk_la;

int common_value(int a, int b, int h, int bot[]) {
    if (h < meet_point[a][b]) return 0;
    h = min(h, min(bot[a], bot[b]));
    return sum_depth[h] - sum_depth_left[h][a + 1] - sum_depth_right[h][b - 1] + sum_left_right[a + 1][b - 1];
}

void push(int x, int bot[], int &sum) {
    que_all[++qa_la] = x;
    int last = 0;
    while (qk_la >= qk_fi && bot[x] >= bot[que_key[qk_la]]) {
        int t = que_key[qk_la];
        sum -= only[t];
        only[t] -= common_value(t, x, bot[t], bot) - common_value(t, x, last, bot);
        sum += only[t];
        last = bot[t];
        qk_la--;
    }
    if (qk_la >= qk_fi) {
        int t = que_key[qk_la];
        sum -= only[t];
        only[t] -= common_value(t, x, bot[t], bot) - common_value(t, x, last, bot);
        sum += only[t];
    }
    que_key[++qk_la] = x;
    only[x] = common_value(x, x, bot[x], bot);
    sum += only[x];
}

void solve(vector<vector<int>> grid) {
    int n = grid.size() - 1, m = grid[0].size() - 1;
    if (n < m) {
        grid = flip(grid);
        swap(n, m);
    }
    if (n == 1) return;
    int mid = n / 2 + 1;

    // left_u and right_u
    for (int i = mid; i; i--) {
        for (int j = m; j; j--) {
            left_u[i][j] = INF; right_u[i][j] = -INF;
            if (grid[i][j] == 0) {
                continue;
            }
            if (i == mid) left_u[i][j] = right_u[i][j] = j;
            if (i < mid) {
                chkmin(left_u[i][j], left_u[i + 1][j]);
                chkmax(right_u[i][j], right_u[i + 1][j]);
            }
            if (j < m) {
                chkmin(left_u[i][j], left_u[i][j + 1]);
                chkmax(right_u[i][j], right_u[i][j + 1]);
            }
        }
    }

    // left_l and right_l
    for (int i = mid; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            left_l[i][j] = INF; right_l[i][j] = -INF;
            if (grid[i][j] == 0) {
                continue;
            }
            if (i == mid) left_l[i][j] = right_l[i][j] = j;
            if (i > mid) {
                chkmin(left_l[i][j], left_l[i - 1][j]);
                chkmax(right_l[i][j], right_l[i - 1][j]);
            }
            if (j > 1) {
                chkmin(left_l[i][j], left_l[i][j - 1]);
                chkmax(right_l[i][j], right_l[i][j - 1]);
            }
        }
    }

    // bottom
    for (int i = n; i >= mid; i--) {
        for (int j = m; j; j--) {
            if (grid[i][j] == 0) {
                bottom[i][j] = -INF;
                continue;
            }
            bottom[i][j] = i;
            if (j < m) chkmax(bottom[i][j], bottom[i][j + 1]);
            if (i < n) chkmax(bottom[i][j], bottom[i + 1][j]);
        }
    }

    // top
    for (int i = 1; i <= mid; i++) {
        for (int j = 1; j <= m; j++) {
            if (grid[i][j] == 0) {
                top[i][j] = INF;
                continue;
            }
            top[i][j] = i;
            if (j > 1) chkmin(top[i][j], top[i][j - 1]);
            if (i > 1) chkmin(top[i][j], top[i - 1][j]);
        }
    }

    // sum and meet_point
    for (int i = 0; i <= n + 1; i++) {
        sum_depth[i] = 0;
        fill_n(sum_depth_left[i], m + 2, 0);
        fill_n(sum_depth_right[i], m + 2, 0);
        fill_n(sum_left_right[i], m + 2, 0);
        fill_n(meet_point[i], m + 2, INF);
    }
    for (int i = mid; i <= n; i++) {
        for (int j = 1; j <= m; j++) {
            if (left_l[i][j] > right_l[i][j]) continue;
            sum_depth[i] += grid[i][j];
            sum_depth_left[i][left_l[i][j]] += grid[i][j];
            sum_depth_right[i][right_l[i][j]] += grid[i][j];
            sum_left_right[left_l[i][j]][right_l[i][j]] += grid[i][j];
            chkmin(meet_point[left_l[i][j]][right_l[i][j]], i);
        }
    }
    for (int i = 1; i <= n; i++) {
        for (int j = m; j; j--) sum_depth_left[i][j] += sum_depth_left[i][j + 1];
        for (int j = 1; j <= m; j++) sum_depth_right[i][j] += sum_depth_right[i][j - 1];
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) sum_left_right[i][j] += sum_left_right[i][j - 1];
        for (int j = m; j; j--) chkmin(meet_point[i][j], meet_point[i][j + 1]);
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) {
            if (meet_point[i][j] > min(bottom[mid][i], bottom[mid][j])) {
                meet_point[i][j] = INF;
            }
        }
    }
    for (int i = 1; i <= n; i++) {
        sum_depth[i] += sum_depth[i - 1];
        for (int j = 1; j <= m; j++) {
            sum_depth_left[i][j] += sum_depth_left[i - 1][j];
            sum_depth_right[i][j] += sum_depth_right[i - 1][j];
        }
    }
    for (int i = m; i; i--) {
        for (int j = 1; j <= m; j++) sum_left_right[i][j] += sum_left_right[i + 1][j];
    }
    for (int i = 1; i <= m; i++) {
        for (int j = 1; j <= m; j++) {
            chkmin(meet_point[i][j], meet_point[i - 1][j]);
        }
    }

    for (int i = 1; i < mid; i++) {
        qa_fi = 1; qa_la = 0; qk_fi = 1; qk_la = 0;
        int last = 0, sum = 0;
        for (int j = 1; j <= m; j++) {
            if (left_u[i][j] > right_u[i][j]) continue;
            while (last < right_u[i][j]) {
                last++;
                if (top[mid][last] <= i) {
                    push(last, bottom[mid], sum);
                }
            }
            while (que_all[qa_fi] < left_u[i][j]) {
                int t = que_all[qa_fi];
                sum -= only[t];
                if (que_key[qk_fi] == t)
                    qk_fi++;
                qa_fi++;
            }
            ans += sum * grid[i][j];
        }
    }

    vector<vector<int>> grid_u(1, vector<int>(m + 1)), grid_l(1, vector<int>(m + 1));
    grid_u.insert(grid_u.end(), grid.begin() + 1, grid.begin() + mid);
    grid_l.insert(grid_l.end(), grid.begin() + mid, grid.end());
    solve(grid_u);
    solve(grid_l);
}

int main() {
    int N; scanf("%d", &N);
    vector<vector<int>> grid(N + 1, vector<int>(N + 1));
    for (int i = 1; i <= N; i++) {
        char tmp[MAX_N]; scanf("%s", tmp + 1);
        for (int j = 1; j <= N; j++) {
            grid[i][j] = isdigit(tmp[j]) ? tmp[j] - '0' : 0;
        }
    }
    solve(grid);
    printf("%lld\n", ans);
}


Measured memory_bytes: 126872