public class Main { public static final int MOD998 = 998244353; public static final int MOD100 = 1000000007; static int nextNum = 1; public static void main(String[] args) throws Exception { ContestScanner sc = new ContestScanner(); ContestPrinter cp = new ContestPrinter(); int H = sc.nextInt(); int W = sc.nextInt(); int[][] ans = new int[H][W]; boolean suc = solveC(ans, H, W, 0, 0); if (suc) { cp.println(nextNum - 1); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { cp.print(ans[i][j]); cp.print(j == W - 1 ? "\n" : " "); } } } else { cp.println(-1); } nextNum = 1; suc = solveT(ans, H, W, 0, 0); if (suc) { cp.println(nextNum - 1); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { cp.print(ans[i][j]); cp.print(j == W - 1 ? "\n" : " "); } } } else { cp.println(-1); } nextNum = 1; suc = solveCT(ans, H, W, 0, 0); if (suc) { cp.println(nextNum - 1); for (int i = 0; i < H; i++) { for (int j = 0; j < W; j++) { cp.print(ans[i][j]); cp.print(j == W - 1 ? "\n" : " "); } } } else { cp.println(-1); } cp.close(); } static void placeVertC(int[][] mat, int hmin, int hmax, int w, int len1, int len2) { for (int i = hmin; i <= hmax; i++) { mat[i][w] = nextNum; } for (int i = Math.min(w, w + len1); i <= Math.max(w, w + len1); i++) { mat[hmin][i] = nextNum; } for (int i = Math.min(w, w + len2); i <= Math.max(w, w + len2); i++) { mat[hmax][i] = nextNum; } nextNum++; } static void placeHoriC(int[][] mat, int wmin, int wmax, int h, int len1, int len2) { for (int i = wmin; i <= wmax; i++) { mat[h][i] = nextNum; } for (int i = Math.min(h, h + len1); i <= Math.max(h, h + len1); i++) { mat[i][wmin] = nextNum; } for (int i = Math.min(h, h + len2); i <= Math.max(h, h + len2); i++) { mat[i][wmax] = nextNum; } nextNum++; } static void placeT(int[][] mat, int h, int w, int up, int down, int left, int right) { for (int i = 0; i <= up; i++) { mat[h - i][w] = nextNum; } for (int i = 0; i <= down; i++) { mat[h + i][w] = nextNum; } for (int i = 0; i <= left; i++) { mat[h][w - i] = nextNum; } for (int i = 0; i <= right; i++) { mat[h][w + i] = nextNum; } nextNum++; } static boolean solveC(int[][] mat, int h, int w, int hoff, int woff) { if (h > w) { int[][] temp = new int[w][h]; boolean flag = solveC(temp, w, h, 0, 0); if (!flag) { return false; } for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { mat[i + hoff][j + woff] = temp[j][i]; } } return true; } if (h == 2 || h == 3 && w % 2 == 1) { return false; } else if (h == 3) { for (int i = 0; i < w; i += 2) { boolean flag = i % 4 == 0; if (i == 0) { placeHoriC(mat, 0 + woff, 2 + woff, 0 + hoff, 2, 1); } else if (i == w - 2) { placeHoriC(mat, w - 3 + woff, w - 1 + woff, (flag ? 0 : 2) + hoff, flag ? 1 : -1, flag ? 2 : -2); } else { placeHoriC(mat, i - 1 + woff, i + 2 + woff, (flag ? 0 : 2) + hoff, flag ? 1 : -1, flag ? 1 : -1); } } } else if (h == 4) { placeVertC(mat, 0 + hoff, 2 + hoff, 0 + woff, w - 1, w - 2); placeVertC(mat, 1 + hoff, 3 + hoff, w - 1 + woff, -(w - 2), -(w - 1)); } else { placeHoriC(mat, 0 + woff, w - 1 + woff, 0 + hoff, h - 1, h - 1); solveC(mat, h - 1, w - 2, hoff + 1, woff + 1); } return true; } static boolean solveT(int[][] mat, int h, int w, int hoff, int woff) { if (h > w) { int[][] temp = new int[w][h]; boolean flag = solveT(temp, w, h, 0, 0); if (!flag) { return false; } for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { mat[i + hoff][j + woff] = temp[j][i]; } } return true; } if (h == 2 || h == 3 && w <= 5) { return false; } else if (h == 3) { placeT(mat, 1 + hoff, 0 + woff, 1, 1, 0, 1); placeT(mat, 1 + hoff, w - 1 + woff, 1, 1, w - 5, 0); placeT(mat, 0 + hoff, 2 + woff, 0, 1, 1, w - 4); placeT(mat, 2 + hoff, 3 + woff, 1, 0, 2, w - 5); } else if (h == 4) { placeT(mat, 0 + hoff, 1 + woff, 0, 1, 1, w - 3); placeT(mat, 1 + hoff, w - 1 + woff, 1, 1, w - 3, 0); placeT(mat, 2 + hoff, 0 + woff, 1, 1, 0, w - 3); placeT(mat, 3 + hoff, w - 2 + woff, 1, 0, w - 3, 1); } else if (h == 5) { placeT(mat, 0 + hoff, w - 2 + woff, 0, 1, w - 3, 1); placeT(mat, 1 + hoff, 0 + woff, 1, 1, 0, w - 3); placeT(mat, 2 + hoff, w - 1 + woff, 1, 1, w - 3, 0); placeT(mat, 3 + hoff, 1 + woff, 1, 0, 1, w - 4); placeT(mat, 4 + hoff, w - 2 + woff, 1, 0, w - 2, 1); } else { placeT(mat, 0 + woff, 2 + woff, 0, 1, 1, w - 4); placeT(mat, 1 + woff, 0 + woff, 1, h - 2, 0, 1); placeT(mat, 1 + woff, w - 1 + woff, 1, h - 2, w - 4, 0); solveT(mat, h - 2, w - 2, hoff + 2, woff + 1); } return true; } static boolean solveCT(int[][] mat, int h, int w, int hoff, int woff) { if (h > w) { int[][] temp = new int[w][h]; boolean flag = solveCT(temp, w, h, 0, 0); if (!flag) { return false; } for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { mat[i + hoff][j + woff] = temp[j][i]; } } return true; } if (h == 2) { return false; } else if (h == 3) { placeVertC(mat, 0 + hoff, 2 + hoff, 0 + woff, w - 2, w - 2); placeT(mat, 1 + hoff, w - 1 + woff, 1, 1, w - 2, 0); } else if (h == 4 && w == 4) { placeT(mat, 0 + hoff, 2 + woff, 0, 1, 2, 1); placeT(mat, 2 + hoff, 3 + woff, 1, 1, 2, 0); placeVertC(mat, 1 + hoff, 3 + hoff, 0 + woff, 1, 2); } else { placeHoriC(mat, 0 + woff, w - 1 + woff, 0 + hoff, h - 1, h - 1); solveCT(mat, h - 1, w - 2, hoff + 1, woff + 1); } return true; } static class ContestScanner { private final java.io.InputStream in; private final byte[] buffer = new byte[1024]; private int ptr = 0; private int buflen = 0; private static final long LONG_MAX_TENTHS = 922337203685477580L; private static final int LONG_MAX_LAST_DIGIT = 7; private static final int LONG_MIN_LAST_DIGIT = 8; public ContestScanner(java.io.InputStream in) { this.in = in; } public ContestScanner() { this(System.in); } private boolean hasNextByte() { if (ptr < buflen) { return true; } else { ptr = 0; try { buflen = in.read(buffer); } catch (java.io.IOException e) { e.printStackTrace(); } if (buflen <= 0) { return false; } } return true; } private int readByte() { if (hasNextByte()) return buffer[ptr++]; else return -1; } private static boolean isPrintableChar(int c) { return 33 <= c && c <= 126; } public boolean hasNext() { while (hasNextByte() && !isPrintableChar(buffer[ptr])) ptr++; return hasNextByte(); } public String next() { if (!hasNext()) throw new java.util.NoSuchElementException(); StringBuilder sb = new StringBuilder(); int b = readByte(); while (isPrintableChar(b)) { sb.appendCodePoint(b); b = readByte(); } return sb.toString(); } public long nextLong() { if (!hasNext()) throw new java.util.NoSuchElementException(); long n = 0; boolean minus = false; int b = readByte(); if (b == '-') { minus = true; b = readByte(); } if (b < '0' || '9' < b) { throw new NumberFormatException(); } while (true) { if ('0' <= b && b <= '9') { int digit = b - '0'; if (n >= LONG_MAX_TENTHS) { if (n == LONG_MAX_TENTHS) { if (minus) { if (digit <= LONG_MIN_LAST_DIGIT) { n = -n * 10 - digit; b = readByte(); if (!isPrintableChar(b)) { return n; } else if (b < '0' || '9' < b) { throw new NumberFormatException( String.format("%d%s... is not number", n, Character.toString(b))); } } } else { if (digit <= LONG_MAX_LAST_DIGIT) { n = n * 10 + digit; b = readByte(); if (!isPrintableChar(b)) { return n; } else if (b < '0' || '9' < b) { throw new NumberFormatException( String.format("%d%s... is not number", n, Character.toString(b))); } } } } throw new ArithmeticException( String.format("%s%d%d... overflows long.", minus ? "-" : "", n, digit)); } n = n * 10 + digit; } else if (b == -1 || !isPrintableChar(b)) { return minus ? -n : n; } else { throw new NumberFormatException(); } b = readByte(); } } public int nextInt() { long nl = nextLong(); if (nl < Integer.MIN_VALUE || nl > Integer.MAX_VALUE) throw new NumberFormatException(); return (int) nl; } public double nextDouble() { return Double.parseDouble(next()); } public long[] nextLongArray(int length) { long[] array = new long[length]; for (int i = 0; i < length; i++) array[i] = this.nextLong(); return array; } public long[] nextLongArray(int length, java.util.function.LongUnaryOperator map) { long[] array = new long[length]; for (int i = 0; i < length; i++) array[i] = map.applyAsLong(this.nextLong()); return array; } public int[] nextIntArray(int length) { int[] array = new int[length]; for (int i = 0; i < length; i++) array[i] = this.nextInt(); return array; } public int[][] nextIntArrayMulti(int length, int width) { int[][] arrays = new int[width][length]; for (int i = 0; i < length; i++) { for (int j = 0; j < width; j++) arrays[j][i] = this.nextInt(); } return arrays; } public int[] nextIntArray(int length, java.util.function.IntUnaryOperator map) { int[] array = new int[length]; for (int i = 0; i < length; i++) array[i] = map.applyAsInt(this.nextInt()); return array; } public double[] nextDoubleArray(int length) { double[] array = new double[length]; for (int i = 0; i < length; i++) array[i] = this.nextDouble(); return array; } public double[] nextDoubleArray(int length, java.util.function.DoubleUnaryOperator map) { double[] array = new double[length]; for (int i = 0; i < length; i++) array[i] = map.applyAsDouble(this.nextDouble()); return array; } public long[][] nextLongMatrix(int height, int width) { long[][] mat = new long[height][width]; for (int h = 0; h < height; h++) for (int w = 0; w < width; w++) { mat[h][w] = this.nextLong(); } return mat; } public int[][] nextIntMatrix(int height, int width) { int[][] mat = new int[height][width]; for (int h = 0; h < height; h++) for (int w = 0; w < width; w++) { mat[h][w] = this.nextInt(); } return mat; } public double[][] nextDoubleMatrix(int height, int width) { double[][] mat = new double[height][width]; for (int h = 0; h < height; h++) for (int w = 0; w < width; w++) { mat[h][w] = this.nextDouble(); } return mat; } public char[][] nextCharMatrix(int height, int width) { char[][] mat = new char[height][width]; for (int h = 0; h < height; h++) { String s = this.next(); for (int w = 0; w < width; w++) { mat[h][w] = s.charAt(w); } } return mat; } } static class ContestPrinter extends java.io.PrintWriter { public ContestPrinter(java.io.PrintStream stream) { super(stream); } public ContestPrinter() { super(System.out); } private static String dtos(double x, int n) { StringBuilder sb = new StringBuilder(); if (x < 0) { sb.append('-'); x = -x; } x += Math.pow(10, -n) / 2; sb.append((long) x); sb.append("."); x -= (long) x; for (int i = 0; i < n; i++) { x *= 10; sb.append((int) x); x -= (int) x; } return sb.toString(); } @Override public void print(float f) { super.print(dtos(f, 20)); } @Override public void println(float f) { super.println(dtos(f, 20)); } @Override public void print(double d) { super.print(dtos(d, 20)); } @Override public void println(double d) { super.println(dtos(d, 20)); } public void printArray(int[] array, String separator) { int n = array.length; for (int i = 0; i < n - 1; i++) { super.print(array[i]); super.print(separator); } super.println(array[n - 1]); } public void printArray(int[] array) { this.printArray(array, " "); } public void printArray(int[] array, String separator, java.util.function.IntUnaryOperator map) { int n = array.length; for (int i = 0; i < n - 1; i++) { super.print(map.applyAsInt(array[i])); super.print(separator); } super.println(map.applyAsInt(array[n - 1])); } public void printArray(int[] array, java.util.function.IntUnaryOperator map) { this.printArray(array, " ", map); } public void printArray(long[] array, String separator) { int n = array.length; for (int i = 0; i < n - 1; i++) { super.print(array[i]); super.print(separator); } super.println(array[n - 1]); } public void printArray(long[] array) { this.printArray(array, " "); } public void printArray(long[] array, String separator, java.util.function.LongUnaryOperator map) { int n = array.length; for (int i = 0; i < n - 1; i++) { super.print(map.applyAsLong(array[i])); super.print(separator); } super.println(map.applyAsLong(array[n - 1])); } public void printArray(long[] array, java.util.function.LongUnaryOperator map) { this.printArray(array, " ", map); } } }