#include <bits/stdc++.h>   using namespace std;   int grid[2500][2500];   int s[2500 + 1][2500 + 1];   char str[2500 + 10];   long long result = 0;   char *trim_line(char *str) { return strtok(str,   r n ); }   long long mul_ll(long long x, long long y) { return x * y; }   int count_ones(int lx, int ly, int rx, int ry) {     return s[rx + 1][ry + 1] - s[lx][ry + 1] - s[rx + 1][ly] + s[lx][ly];   }   void process_x_left(int lx, int ly, int rx, int ry, int k, int *left,                       bool omg) {     int end = rx;     left[0] = end;     for (int i = 1; i <= k + 1; i++) {       int start = omg ? left[i] : (lx - 1);       while (start < end) {         int mid = start + (end - start + 1) / 2;         int nr = count_ones(mid, ly, rx, ry);         if (nr >= i) {           start = mid;         } else {           end = mid - 1;         }       }       left[i] = start;     }   }   void process_x_right(int lx, int ly, int rx, int ry, int k, int *right,                        bool omg) {     int start = lx;     right[0] = start;     for (int i = 1; i <= k + 1; i++) {       int end = omg ? right[i] : (rx + 1);       int j = i + s[lx][ry + 1] - s[lx][ly];       while (start < end) {         int mid = start + (end - start) / 2;         int nr = s[mid + 1][ry + 1] - s[mid + 1][ly];         if (nr >= j) {           end = mid;         } else {           start = mid + 1;         }       }       right[i] = start;     }   }   void process_y_left(int lx, int ly, int rx, int ry, int k, int *left) {     int end = ry;     left[0] = end;     for (int i = 1; i <= k + 1; i++) {       int start = ly - 1;       while (start < end) {         int mid = start + (end - start + 1) / 2;         int nr = count_ones(lx, mid, rx, ry);         if (nr >= i) {           start = mid;         } else {           end = mid - 1;         }       }       left[i] = start;     }     for (int i = 0; i <= k; i++) left[i] -= left[i + 1];   }   void process_y_right(int lx, int ly, int rx, int ry, int k, int *right) {     int start = ly;     right[0] = start;     for (int i = 1; i <= k + 1; i++) {       int end = ry + 1;       while (start < end) {         int mid = start + (end - start) / 2;         int nr = count_ones(lx, ly, rx, mid);         if (nr >= i) {           end = mid;         } else {           start = mid + 1;         }       }       right[i] = start;     }     for (int i = 0; i <= k; i++) right[i] = right[i + 1] - right[i];   }   void kdtree(int lx, int ly, int rx, int ry, int k) {     int left[6 + 2];     int right[6 + 2];     int dx = rx - lx;     int dy = ry - ly;     if (dx >= dy) {       if (dy == 0) {         map<int, int> cnt;         cnt[0] = 1;         for (int i = lx; i <= rx; i++) {           int nr = count_ones(lx, ly, i, ry);           if (nr >= k) result += cnt[nr - k];           ++cnt[nr];         }       } else {         int mx = lx + (rx - lx) / 2;         for (int i = ly; i <= ry; i++)           for (int j = i; j <= ry; j++) {             process_x_left(lx, i, mx, j, k, left, (i < j));             process_x_right(mx + 1, i, rx, j, k, right, (i < j));             for (int l = 0; l <= k; l++) {               int a = left[l] - left[l + 1];               int b = right[k - l + 1] - right[k - l];               result += a * b;             }           }         kdtree(lx, ly, mx, ry, k);         kdtree(mx + 1, ly, rx, ry, k);       }     } else {       if (dx == 0) {         map<int, int> cnt;         cnt[0] = 1;         for (int i = ly; i <= ry; i++) {           int nr = count_ones(lx, ly, rx, i);           if (nr >= k) result += cnt[nr - k];           ++cnt[nr];         }       } else {         int my = ly + (ry - ly) / 2;         for (int i = lx; i <= rx; i++)           for (int j = i; j <= rx; j++) {             process_y_left(i, ly, j, my, k, left);             process_y_right(i, my + 1, j, ry, k, right);             for (int l = 0; l <= k; l++) result += left[l] * right[k - l];           }         kdtree(lx, ly, rx, my, k);         kdtree(lx, my + 1, rx, ry, k);       }     }   }   int solve_problem() {     int n, m, k;     if (fgets(str, sizeof(str), stdin) == NULL) return 1;     n = atoi(strtok(str,    ));     m = atoi(strtok(NULL,    ));     k = atoi(strtok(NULL,    ));     for (int i = 0; i < n; i++) {       if (fgets(str, sizeof(str), stdin) == NULL) return 1;       for (int j = 0; j < m; j++) grid[i][j] = str[j] -  0 ;     }     for (int i = 0; i < n; i++) {       for (int j = 0; j < m; j++) s[i + 1][j + 1] = s[i + 1][j] + grid[i][j];       for (int j = 0; j < m; j++) s[i + 1][j + 1] += s[i][j + 1];     }     kdtree(0, 0, n - 1, m - 1, k);     cout << result << endl;     return 0;   }   int main() {     solve_problem();     return 0;   }