description: Mr. Chanek's city can be represented as a plane. He wants to build a housing complex in the city.
  
  There are some telephone poles on the plane, which is represented by a grid a of size (n + 1) × (m + 1). There is a telephone pole at (x, y) if a_{x, y} = 1.
  
  For each point (x, y), define S(x, y) as the square of the Euclidean distance between the nearest pole and (x, y). Formally, the square of the Euclidean distance between two points (x_1, y_1) and (x_2, y_2) is (x_2 - x_1)^2 + (y_2 - y_1)^2.
  
  To optimize the building plan, the project supervisor asks you the sum of all S(x, y) for each 0 ≤ x ≤ n and 0 ≤ y ≤ m. Help him by finding the value of ∑_{x=0}^{n} {∑_{y=0}^{m} {S(x, y)}}.
  
  Input
  
  The first line contains two integers n and m (0 ≤ n, m < 2000) — the size of the grid.
  
  Then (n + 1) lines follow, each containing (m + 1) integers a_{i, j} (0 ≤ a_{i, j} ≤ 1) — the grid denoting the positions of telephone poles in the plane. There is at least one telephone pole in the given grid.
  
  Output
  
  Output an integer denoting the value of ∑_{x=0}^{n} {∑_{y=0}^{m} {S(x, y)}}.
  
  Examples
  
  Input
  
  
  2 2
  101
  000
  000
  
  
  Output
  
  
  18
  
  
  Input
  
  
  5 4
  10010
  00000
  01000
  00001
  00100
  00010
  
  
  Output
  
  
  36
  
  Note
  
  <image>
  
  In the first example, the nearest telephone pole for the points (0,0), (1,0), (2,0), (0,1), (1,1), and (2,1) is at (0, 0). While the nearest telephone pole for the points (0, 2), (1,2), and (2,2) is at (0, 2). Thus, ∑_{x=0}^{n} {∑_{y=0}^{m} {S(x, y)}} = (0 + 1 + 4) + (1 + 2 + 5) + (0 + 1 + 4) = 18.
solution: import java.io.OutputStream;
  import java.io.IOException;
  import java.io.InputStream;
  import java.io.OutputStream;
  import java.io.PrintWriter;
  import java.util.Arrays;
  import java.io.BufferedWriter;
  import java.util.InputMismatchException;
  import java.io.IOException;
  import java.io.Writer;
  import java.io.OutputStreamWriter;
  import java.io.InputStream;
  
  /**
   * Built using CHelper plug-in
   * Actual solution is at the top
   */
  public class Main {
      public static void main(String[] args) {
          InputStream inputStream = System.in;
          OutputStream outputStream = System.out;
          InputReader in = new InputReader(inputStream);
          OutputWriter out = new OutputWriter(outputStream);
          MManagingTelephonePoles solver = new MManagingTelephonePoles();
          solver.solve(1, in, out);
          out.close();
      }
  
      static class MManagingTelephonePoles {
          long[] A = new long[1000000];
          long[] B = new long[1000000];
          int len;
          int ptr;
  
          public void addLine(long a, long b) {
              // intersection of (A[len-2],B[len-2]) with (A[len-1],B[len-1]) must lie to the left of intersection of
              // (A[len-1],B[len-1]) with (a,b)
              while (
                      len >= 2 && (B[len - 2] - B[len - 1]) * (a - A[len - 1]) >= (B[len - 1] - b) * (A[len - 1] - A[len - 2])) {
                  --len;
              }
              A[len] = a;
              B[len] = b;
              ++len;
          }
  
          public long minValue(long x) {
              ptr = Math.min(ptr, len - 1);
              while (ptr + 1 < len && A[ptr + 1] * x + B[ptr + 1] <= A[ptr] * x + B[ptr]) {
                  ++ptr;
              }
              return A[ptr] * x + B[ptr];
          }
  
          void init() {
              len = 0;
              ptr = 0;
          }
  
          public void solve(int testNumber, InputReader in, OutputWriter out) {
              int n = in.nextInt(), m = in.nextInt();
              n += 1;
              m += 1;
              char[][] A = new char[n][m];
              int[][] U = new int[n][m], D = new int[n][m];
              for (int i = 0; i < n; i++) {
                  Arrays.fill(U[i], -1);
                  Arrays.fill(D[i], -1);
              }
              for (int i = 0; i < n; i++) {
                  A[i] = in.next().toCharArray();
                  for (int j = 0; j < m; j++) {
                      U[i][j] = A[i][j] == '1' ? i : (i == 0 ? -1 : U[i - 1][j]);
                  }
              }
              long answer = 0;
              for (int i = n - 1; i >= 0; i--) {
                  init();
                  for (int j = 0; j < m; j++) {
                      D[i][j] = A[i][j] == '1' ? i : (i == n - 1 ? -1 : D[i + 1][j]);
                      if (U[i][j] != -1) {
                          int v = (i - U[i][j]) * (i - U[i][j]);
                          addLine(-2 * j, j * j + v);
                      }
                      if (D[i][j] != -1) {
                          int v = (i - D[i][j]) * (i - D[i][j]);
                          addLine(-2 * j, j * j + v);
                      }
                  }
  
                  for (int j = 0; j < m; j++) {
                      answer += j * j + minValue(j);
                  }
              }
              out.println(answer);
          }
  
      }
  
      static class OutputWriter {
          private final PrintWriter writer;
  
          public OutputWriter(OutputStream outputStream) {
              writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
          }
  
          public OutputWriter(Writer writer) {
              this.writer = new PrintWriter(writer);
          }
  
          public void println(Object... objects) {
              for (int i = 0; i < objects.length; i++) {
                  if (i != 0) {
                      writer.print(' ');
                  }
                  writer.print(objects[i]);
              }
              writer.print('\n');
          }
  
          public void close() {
              writer.close();
          }
  
      }
  
      static class InputReader {
          private InputStream stream;
          private byte[] buf = new byte[1024];
          private int curChar;
          private int numChars;
          private InputReader.SpaceCharFilter filter;
  
          public InputReader(InputStream stream) {
              this.stream = stream;
          }
  
          public int read() {
              if (numChars == -1) {
                  throw new InputMismatchException();
              }
              if (curChar >= numChars) {
                  curChar = 0;
                  try {
                      numChars = stream.read(buf);
                  } catch (IOException e) {
                      throw new InputMismatchException();
                  }
                  if (numChars <= 0) {
                      return -1;
                  }
              }
              return buf[curChar++];
          }
  
          public int nextInt() {
              int c = read();
              while (isSpaceChar(c)) c = read();
              int sgn = 1;
              if (c == '-') {
                  sgn = -1;
                  c = read();
              }
              int res = 0;
              do {
                  if (c < '0' || c > '9')
                      throw new InputMismatchException();
                  res *= 10;
                  res += c - '0';
                  c = read();
              } while (!isSpaceChar(c));
              return res * sgn;
          }
  
          public String next() {
              int c;
              while (isSpaceChar(c = this.read())) {
                  ;
              }
  
              StringBuilder result = new StringBuilder();
              result.appendCodePoint(c);
  
              while (!isSpaceChar(c = this.read())) {
                  result.appendCodePoint(c);
              }
  
              return result.toString();
          }
  
          public boolean isSpaceChar(int c) {
              if (filter != null) {
                  return filter.isSpaceChar(c);
              }
              return isWhitespace(c);
          }
  
          public static boolean isWhitespace(int c) {
              return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
          }
  
          public interface SpaceCharFilter {
              public boolean isSpaceChar(int ch);
  
          }
  
      }
  }
  
  