const
  MAX_SIZE = 50;

var
  n, m: integer;
  p: array [1..MAX_SIZE, 1..MAX_SIZE] of byte;
  r: array [0..MAX_SIZE + 1] of record
    IsEmpty, CanFill: boolean;
    x1, y1, x2, y2: integer;
    min_y1, max_y2: integer;
  end;
  l: array [0..MAX_SIZE + 1, 0..MAX_SIZE + 1] of record
    IsEmpty, CanFill: boolean;
    x1, y1, x2, y2: integer;
    min_y1, max_y2: integer;
  end;

function Min(a, b: longint): longint;
begin
  if a < b then
    Min := a
  else
    Min := b;
end;

function Max(a, b: longint): longint;
begin
  if a > b then
    Max := a
  else
    Max := b;
end;

procedure FillRight;
var
  mnx, mny, mxx, mxy: integer;
  i, j, k: integer;
  detected1: boolean;
  aa, bb: integer;
begin
  for i := 1 to m do begin
    mnx := m + 1;
    mny := n + 1;
    mxy := 0;
    mxx := 0;
    for j := 1 to n do
      for k := i to m do
        if p[j, k] = 2 then begin
          mnx := Min(k, mnx);
          mny := Min(j, mny);
          mxx := Max(k, mxx);
          mxy := Max(j, mxy);
        end;

    if mnx = m + 1 then begin
      r[i].IsEmpty := true;
      continue;
    end;

    r[i].CanFill := true;
    for j := mny to mxy do begin
      for k := mnx to mxx do
        if p[j, k] = 1 then begin
          r[i].CanFill := false;
          Break;
        end;
      if not r[i].CanFill then
        Break;
    end;
    if not r[i].CanFill then
      Continue;

    aa := mny;
    for j := mny - 1 downto 1 do begin
      detected1 := false;
      for k := i to m do
        if p[j, k] = 1 then begin
          detected1 := true;
          break;
        end;
      if detected1 then
        break;
      aa := j;
    end;

    bb := mxy;
    for j := mxy + 1 to n do begin
      detected1 := false;
      for k := i to m do
        if p[j, k] = 1 then begin
          detected1 := true;
          break;
        end;
      if detected1 then
        break;
      bb := j;
    end;

    with r[i] do begin
      x1 := mnx; x2 := mxx;
      y1 := mny; y2 := mxy;
      min_y1 := aa;
      max_y2 := bb;
    end;
  end;
end;

procedure FillLeft;
var
  mnx, mny, mxx, mxy: integer;
  i, j, k, q: integer;
  detected1: boolean;
  aa, bb: integer;
begin
  for i := 1 to n do begin
    for j := i to n do begin
      mnx := m + 1;
      mxx := 0;
      mny := n + 1;
      mxy := 0;
      for k := 1 to m do begin
        for q := 1 to i - 1 do
          if p[q, k] = 2 then begin
            mnx := Min(k, mnx);
            mxx := Max(k, mxx);
            mny := Min(q, mny);
            mxy := Max(q, mxy);
          end;

        for q := j + 1 to n do
          if p[q, k] = 2 then begin
            mnx := Min(k, mnx);
            mxx := Max(k, mxx);
            mny := Min(q, mny);
            mxy := Max(q, mxy);
          end;
      end;
      if mnx = m + 1 then begin
        l[i, j].IsEmpty := true;
        continue;
      end;

      l[i, j].CanFill := true;
      for k := mnx to mxx do begin
        for q := mny to Min(mxy, i - 1) do
          if p[q, k] = 1 then begin
            l[i, j].CanFill := false;
            break;
          end;
        for q := Max(mny, j + 1) to mxy do
          if p[q, k] = 1 then begin
            l[i, j].CanFill := false;
            break;
          end;
        if not l[i, j].CanFill then
          break;
      end;
      if not l[i, j].CanFill then
        continue;

      aa := mny;
      for k := Min(mny, i - 1) downto 1 do begin
        detected1 := false;
        for q := 1 to m do
          if p[k, q] = 1 then begin
            detected1 := true;
            break;
          end;
        if detected1 then
          break;
      end;

      bb := mxy;
      for k := Max(mxy, j + 1) to n do begin
        detected1 := false;
        for q := 1 to m do
          if p[k, q] = 1 then begin
            detected1 := true;
            break;
          end;
        if detected1 then
          break;
      end;

      with l[i, j] do begin
        x1 := mnx; x2 := mxx;
        y1 := mny; y2 := mxy;
        min_y1 := aa;
        max_y2 := bb;
      end;
    end;
  end;
end;

var
  i, j, k, q: integer;
  aa, bb: integer;
  mnx2, mxx2, mnx0, mxx0: integer;
  mnx, mny, mxx, mxy: integer;
  square, bestSquare: longint;
  xx1, yy1, xx2, yy2: longint;
  ok, met2, met2now: boolean;
begin
  assign(input, 'input.txt'); reset(input);
  assign(output, 'output.txt'); rewrite(output);
  read(n, m);
  for i := 1 to n do
    for j := 1 to m do
      read(p[i, j]);

  FillRight;
  FillLeft;

  bestSquare := MAXLONGINT;
  for i := 1 to n do begin
    for j := i to n do begin
      mnx2 := m + 1;
      mxx2 := 0;
      mnx0 := m + 1;
      mxx0 := 0;
      met2 := false;
      for k := 1 to m do begin
        ok := true;
        met2now := false;
        for q := i to j do
          if p[q, k] = 1 then
            ok := false
          else if p[q, k] = 2 then begin
            met2 := true;
            met2now := true;
          end;

        if (not ok) and (not met2) then begin
          mnx0 := m + 1;
          mxx0 := 0;
          continue;
        end
        else if (not ok) and (met2) then
          break
        else if (not met2) then begin
          mnx0 := Min(mnx0, k);
          mxx0 := k;
          continue;
        end
        else if met2now then begin
          mnx2 := Min(mnx2, k);
          mxx2 := k;
          mnx0 := Min(mnx0, k);
          mxx0 := k;
        end;

        if
          (not l[i, j].IsEmpty) and
          (not l[i, j].CanFill or (l[i, j].x1 < mnx0))
        then
          continue;

        if
          (k <> m) and (not r[k + 1].IsEmpty) and
          (not r[k + 1].CanFill)
        then
          continue;

        if
          (l[i, j].IsEmpty) and ((k = m) or (r[k + 1].IsEmpty))
        then begin
          square := longint(k - mnx2 + 1) * longint(j - i + 1);
          bestSquare := Min(square, bestSquare);
        end
        else if l[i, j].IsEmpty then begin
          square :=
            longint(k - mnx2 + 1) * longint(j - i + 1) +
            longint(r[k + 1].x2 - r[k + 1].x1 + 1) *
            longint(r[k + 1].y2 - r[k + 1].y1 + 1);
          bestSquare := Min(square, bestSquare);
        end
        else if ((k = m) or (r[k + 1].IsEmpty)) then begin
          square :=
            longint(k - mnx2 + 1) * longint(j - i + 1) +
            longint(l[i, j].x2 - l[i, j].x1 + 1) *
            longint(l[i, j].y2 - l[i, j].y1 + 1);

          if
            (l[i, j].y1 < i) and (l[i, j].y2 > j) and
            (l[i, j].x1 < k) and (l[i, j].x2 > mnx2)
          then
            square :=
              square -
              (Max(l[i, j].x1, mnx2) - Min(l[i, j].x1, mnx2) + 1) *
              longint(j - i + 1);

          bestSquare := Min(square, bestSquare);
        end
        else begin
          if
            (r[k + 1].min_y1 > l[i, j].y1) or
            (r[k + 1].max_y2 < l[i, j].y2)
          then
            continue;

          xx1 := Min(l[i, j].x1, r[k + 1].x1);
          xx2 := Max(l[i, j].x2, r[k + 1].x2);
          yy1 := Min(r[k + 1].y1, l[i, j].y1);
          yy2 := Max(r[k + 1].y2, l[i, j].y2);

          square :=
            longint(k - mnx2 + 1) * longint(j - i + 1) +
            longint(xx2 - xx1 + 1) * longint(yy2 - yy1 + 1);

          if (xx1 <= k) and (xx2 >= mnx2) and (yy1 <= j) and (yy2 >= i) then
            square :=
              square -
              (Min(yy2, j) - Max(yy1, i) + 1) *
              (Min(xx2, k) - Max(xx1, mnx2) + 1);

          bestSquare := Min(square, bestSquare);
        end;
      end;
    end;
  end;

  if bestSquare = MAXLONGINT then
    writeln(-1)
  else
    writeln(bestSquare);


  close(output);
  close(input);
end.