/**
 *    author:  tourist
 *    created: 27.01.2020 02:18:50       
**/
#undef _GLIBCXX_DEBUG

#include <bits/stdc++.h>

using namespace std;

int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  int n;
  cin >> n;
  vector<vector<int>> mat(n, vector<int>(n));
  for (int i = 0; i < n; i++) {
    string foo;
    cin >> foo;
    for (int j = 0; j < n; j++) {
      mat[i][j] = (foo[j] == '#' ? -1 : (int) (foo[j] - '0'));
    }
  }
  long long ans = 0;
  vector<vector<int>> a(n, vector<int>(n));
  vector<vector<int>> left(n, vector<int>(n));
  vector<vector<int>> right(n, vector<int>(n));
  vector<vector<int>> mp(n, vector<int>(n));
  vector<vector<int>> bottom(n, vector<int>(n));
  vector<vector<int>> top(n, vector<int>(n));
  vector<vector<int>> Min(n, vector<int>(n));
  vector<vector<int>> Max(n, vector<int>(n));
  vector<int> c1(n);
  vector<vector<int>> c2(n, vector<int>(n));
  vector<vector<int>> c3(n, vector<int>(n));
  vector<vector<int>> c4(n, vector<int>(n));
  vector<int> has(n);
  vector<int> st;
  function<void(int, int)> Count = [&](int h, int w) {
    assert(h >= 2);
    int mid = h >> 1;
    for (int i = mid; i < h; i++) {
      for (int j = 0; j < w; j++) {
        left[i][j] = n + 1;
        right[i][j] = -1;
        if (a[i][j] != -1) {
          if (i == mid) {
            left[i][j] = right[i][j] = j;
          }
          if (j > 0 && a[i][j - 1] != -1) {
            left[i][j] = min(left[i][j], left[i][j - 1]);
            right[i][j] = max(right[i][j], right[i][j - 1]);
          }
          if (i > mid && a[i - 1][j] != -1) {
            left[i][j] = min(left[i][j], left[i - 1][j]);
            right[i][j] = max(right[i][j], right[i - 1][j]);
          }
        }
      }
    }
    for (int i = mid - 1; i >= 0; i--) {
      for (int j = w - 1; j >= 0; j--) {
        Min[i][j] = n + 1;
        Max[i][j] = -1;
        if (a[i][j] != -1) {
          if (i == mid - 1) {
            Min[i][j] = Max[i][j] = j;
          }
          if (j < w - 1 && a[i][j + 1] != -1) {
            Min[i][j] = min(Min[i][j], Min[i][j + 1]);
            Max[i][j] = max(Max[i][j], Max[i][j + 1]);
          }
          if (i < mid - 1 && a[i + 1][j] != -1) {
            Min[i][j] = min(Min[i][j], Min[i + 1][j]);
            Max[i][j] = max(Max[i][j], Max[i + 1][j]);
          }
        }
      }
    }
    for (int i = h - 1; i >= mid; i--) {
      for (int j = w - 1; j >= 0; j--) {
        if (a[i][j] == -1) {
          bottom[i][j] = -1;
        } else {
          bottom[i][j] = i;
          if (j < w - 1) {
            bottom[i][j] = max(bottom[i][j], bottom[i][j + 1]);
          }
          if (i < h - 1) {
            bottom[i][j] = max(bottom[i][j], bottom[i + 1][j]);
          }
        }
      }
    }
    for (int i = 0; i < mid; i++) {
      for (int j = 0; j < w; j++) {
        if (a[i][j] == -1) {
          top[i][j] = n + 1;
        } else {
          top[i][j] = i;
          if (j > 0) {
            top[i][j] = min(top[i][j], top[i][j - 1]);
          }
          if (i > 0) {
            top[i][j] = min(top[i][j], top[i - 1][j]);
          }
        }
      }
    }
    for (int i = 0; i < w; i++) {
      for (int j = i; j < w; j++) {
        mp[i][j] = n + 1;
      }
    }
    for (int i = mid; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (left[i][j] <= right[i][j]) {
          mp[left[i][j]][right[i][j]] = min(mp[left[i][j]][right[i][j]], i);
        }
      }
    }
    for (int i = 0; i < w; i++) {
      for (int j = w - 1; j >= 0; j--) {
        if (i > 0) {
          mp[i][j] = min(mp[i][j], mp[i - 1][j]);
        }
        if (j < w - 1) {
          mp[i][j] = min(mp[i][j], mp[i][j + 1]);
        }
      }
    }
    for (int i = mid; i < h; i++) {
      c1[i] = (i > mid ? c1[i - 1] : 0);
      for (int j = 0; j < w; j++) {
        c1[i] += a[i][j] * (left[i][j] <= right[i][j]);
      }
    }
    for (int i = mid; i < h; i++) {
      for (int j = 0; j < w; j++) {
        c2[i][j] = 0;
      }
      for (int j = 0; j < w; j++) {
        if (left[i][j] > 0 && left[i][j] < w) {
          c2[i][left[i][j] - 1] += a[i][j];
        }
      }
      for (int j = w - 1; j > 0; j--) {
        c2[i][j - 1] += c2[i][j];
      }
      if (i > mid) {
        for (int j = 0; j < w; j++) {
          c2[i][j] += c2[i - 1][j];
        }
      }
    }
    for (int i = mid; i < h; i++) {
      for (int j = 0; j < w; j++) {
        c3[i][j] = 0;
      }
      for (int j = 0; j < w; j++) {
        if (right[i][j] >= 0 && right[i][j] < w - 1) {
          c3[i][right[i][j] + 1] += a[i][j];
        }
      }
      for (int j = 0; j < w - 1; j++) {
        c3[i][j + 1] += c3[i][j];
      }
      if (i > mid) {
        for (int j = 0; j < w; j++) {
          c3[i][j] += c3[i - 1][j];
        }
      }
    }
    for (int i = 0; i < w; i++) {
      for (int j = i; j < w; j++) {
        c4[i][j] = 0;
      }
    }
    for (int i = mid; i < h; i++) {
      for (int j = 0; j < w; j++) {
        if (left[i][j] > 0 && right[i][j] < w - 1 && left[i][j] <= right[i][j]) {
          c4[left[i][j] - 1][right[i][j] + 1] += a[i][j];
        }
      }
    }
    for (int i = w - 1; i >= 0; i--) {
      for (int j = i + 2; j < w; j++) {
        c4[i][j] += c4[i + 1][j] + c4[i][j - 1] - c4[i + 1][j - 1];
      }
    }
    auto Both = [&](int j1, int j2, int r) {
      r = min(r, min(bottom[mid][j1], bottom[mid][j2]));
      if (mp[j1][j2] > r) {
        return 0;
      }
      int ret = c1[r] - c2[r][j1] - c3[r][j2] + c4[j1][j2];
      return ret;
    };
    long long cur = 0;
    for (int i = 0; i < mid; i++) {
      int L = 0, R = 0;
      int value = 0;
      fill(has.begin(), has.begin() + w, 0);
      st.clear();
      int ptr = 0;
      for (int j = 0; j < w; j++) {
        if (Min[i][j] > Max[i][j]) {
          continue;
        }
        while (R <= Max[i][j]) {
          if (top[mid - 1][R] <= i && a[mid][R] != -1) {
            int row = mid - 1;
            while (ptr < (int) st.size()) {
              int new_row = bottom[mid][st.back()];
              int delta = Both(st.back(), R, new_row) - (row < mid ? 0 : Both(st.back(), R, row));
              value -= delta;
              has[st.back()] -= delta;
              if (new_row > bottom[mid][R]) {
                break;
              }
              row = new_row;
              st.pop_back();
            }
            st.push_back(R);
            has[R] = Both(R, R, h - 1);
            value += has[R];
          }
          R += 1;
        }
        while (L < Min[i][j]) {
          value -= has[L];
          if (ptr < (int) st.size() && st[ptr] == L) {
            ++ptr;
          }
          L += 1;
        }
        cur += a[i][j] * value;
      }
    }
    ans += cur;
  };
  function<void(int, int, int, int)> Solve = [&](int i1, int j1, int i2, int j2) {
    if (i2 - i1 == 1 && j2 - j1 == 1) {
      return;
    }
    if (i2 - i1 > j2 - j1) {
      int h = i2 - i1;
      int w = j2 - j1;
      for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
          a[i][j] = mat[i1 + i][j1 + j];
        }
      }
      Count(h, w);
      Solve(i1, j1, (i1 + i2) >> 1, j2);
      Solve((i1 + i2) >> 1, j1, i2, j2);
    } else {
      int h = j2 - j1;
      int w = i2 - i1;
      for (int i = 0; i < h; i++) {
        for (int j = 0; j < w; j++) {
          a[i][j] = mat[i1 + j][j1 + i];
        }
      }
      Count(h, w);
      Solve(i1, j1, i2, (j1 + j2) >> 1);
      Solve(i1, (j1 + j2) >> 1, i2, j2);
    }
  };
  Solve(0, 0, n, n);
  cout << ans << '\n';
  return 0;
}


Measured memory_bytes: 108544