/*
 * used for validating answers; won't run in time limit
 */
import java.util.*;

public class Tensor {
  public static Scanner in;
  public static int caseNum;
  public static int r, c; // number of rows and columns
  public static int mat[][]; // matrix
  public static ArrayList<Integer> rdiv, cdiv;

  public static void main(String[] args) {
    in = new Scanner(System.in);
    caseNum = 0;
    while (true) {
      r = in.nextInt();
      c = in.nextInt();
      if (r == 0 && c == 0)
        break;
      caseNum++;
      mat = new int[r][c];
      for (int i = 0; i < r; i++)
        for (int j = 0; j < c; j++)
          mat[i][j] = in.nextInt();
      rdiv = new ArrayList<Integer>();
      cdiv = new ArrayList<Integer>();
      System.out.println(solve());
    }
  }

  public static int solve() {
    int count = 0;
    for (int i = 1; i <= r; i++) {
      if (r % i == 0)
        rdiv.add(i);
    }

    for (int i = 1; i <= c; i++) {
      if (c % i == 0)
        cdiv.add(i);
    }

    for (int i1 = 0; i1 < rdiv.size(); i1++) {
      int p = rdiv.get(i1);
      int n = r/p;
      for (int j1 = 0; j1 < cdiv.size(); j1++) {
        int q = cdiv.get(j1);
        int m = c/q;
        if ((p==1 && q == 1) || (n==1 && m ==1))
          continue; // neither matrix is allowed to be 1x1



        int agcd = 0;
        for (int i3 = 0; i3 < n; i3++) {
          for (int j3 = 0; j3 < m; j3++) {
            agcd = GCD(agcd,mat[i3][j3]);
          }
        }


        ArrayList<Integer> adiv = new ArrayList<Integer>();
        int lim = (int)Math.sqrt(agcd);
        for (int i = 1; i <= lim; i++) {
          if (agcd%i == 0) {
            adiv.add(i);
            if (i != agcd/i)
              adiv.add(agcd/i);
          }
        }

        for (int i = 0; i < adiv.size(); i++) {
          int k = adiv.get(i);
          if (agcd % k != 0) continue;
          int trialB[][] = new int[n][m];
          boolean quit = false;
          for (int i2 = 0; i2 < n && !quit; i2++) {
            for (int j2 = 0; j2 < m && !quit; j2++) {
              if (mat[i2][j2] % k != 0) {
                quit = true;
              }
              else
                trialB[i2][j2] = mat[i2][j2]/k;
            }
          }
          if (quit)
            continue;
          int trialA[][] = new int[p][q];
          for (int i2 = 0; i2 < p && !quit; i2++) {
            for (int j2 = 0; j2 < q && !quit; j2++) {
              if (mat[i2*n][j2*m] % trialB[0][0] != 0)
                quit = true;
              else
                trialA[i2][j2] = mat[i2*n][j2*m] / trialB[0][0];
            }
          }

          if (quit)
            continue;
          for (int i2 = 0; i2 < r && !quit; i2++) {
            for (int j2 = 0; j2 < c && !quit; j2++) {
              if (mat[i2][j2] != trialA[i2/n][j2/m] * trialB[i2%n][j2%m])
                quit = true;
            }
          }
          if (!quit)
            count++;
        }
      }
    }
    return count;
  }

  public static int GCD(int a, int b) {
    if (b == 0) return a;
    return GCD(b, a % b);
  }
}
