Problem:
Score : 900 points

Problem Statement

We have a grid with (2^N - 1) rows and (2^M-1) columns.
You are asked to write 0 or 1 in each of these squares.
Let a_{i,j} be the number written in the square at the i-th row from the top and the j-th column from the left.

For a quadruple of integers (i_1, i_2, j_1, j_2) such that 1\leq i_1 \leq i_2\leq 2^N-1, 1\leq j_1 \leq j_2\leq 2^M-1, let
S(i_1, i_2, j_1, j_2) = \displaystyle \sum_{r=i_1}^{i_2}\sum_{c=j_1}^{j_2}a_{r,c}.
Then, let the oddness of the grid be the number of quadruples (i_1, i_2, j_1, j_2) such that S(i_1, i_2, j_1, j_2) is odd.

Find a way to fill in the grid that maximizes its oddness.

Constraints

N and M are integers between 1 and 10 (inclusive).

Input

Input is given from Standard Input in the following format:

N M

Output

Print numbers to write in the grid so that its oddness is maximized, in the following format:

a_{1,1}a_{1,2}\cdots a_{1,2^M-1}
a_{2,1}a_{2,2}\cdots a_{2,2^M-1}
\vdots
a_{2^N-1,1}a_{2^N-1,2}\cdots a_{2^N-1,2^M-1}

If there are multiple solutions, you can print any of them.

Sample Input 1

1 2

Sample Output 1

111

For this grid, S(1, 1, 1, 1), S(1, 1, 2, 2), S(1, 1, 3, 3), and S(1, 1, 1, 3) are odd, so it has the oddness of 4.

We cannot make the oddness 5 or higher, so this is one of the ways that maximize the oddness.

Solution in C# (Mono 4.6.2.0) (judge verdict: Wrong Answer)

using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using static System.Math;
using Number = System.Int64;
using System.Numerics;
using static System.Numerics.BigInteger;
namespace Program {
	public class Solver {
		Random rnd = new Random(0);
		public void Solve() {
			var n = 1 << ri;
			var m = 1 << ri;
			var min = Min(n, m);
			var a = Enumerate(n, x => new int[m]);
			a[1][1] = 1;
			for (int i = 0; i < min; i++)
				for (int j = 0; j < min; j++) a[i][j] = a[i % 2][j % 2];
			for (int i = 0; i < n; i++)
				for (int j = 0; j < m; j++) a[i][j] = a[i % min][j % min];
			for (int i = 0; i < n; i++)
				Debug.WriteLine(a[i].AsJoinedString());
			var ans = Enumerate(n - 1, x => new char[m - 1]);
			for (int i = 0; i < n - 1; i++)
				for (int j = 0; j < m - 1; j++) {
					var x = 0;
					for (int u = 0; u < 2; u++)
						for (int v = 0; v < 2; v++) x ^= a[i + u][j + v];
					ans[i][j] = (char)('0' + x);
				}
			for (int i = 0; i < n - 1; i++)
				Console.WriteLine(ans[i].AsString());
		}
		void ex() {
			var n = 3;
			var m = 3;
			var k = n * m;
			var max = 0;
			for (int mask = 0; mask < 1 << k; mask++) {
				var a = Enumerate(n, m, (x, y) => mask >> (x * m + y) & 1);
				var cnt = 0;
				for (int i = 0; i < n; i++)
					for (int ni = i; ni < n; ni++)
						for (int j = 0; j < m; j++)
							for (int nj = j; nj < m; nj++) {
								var u = 0;
								for (int p = i; p <= ni; p++)
									for (int q = j; q <= nj; q++) u += a[p][q];
								if (u % 2 == 1) cnt++;
							}
				if (cnt == 24) {
					var b = Enumerate(n + 1, x => new int[m + 1]);
					for (int i = 0; i < n; i++)
						for (int j = 0; j < m; j++) b[i + 1][j + 1] = b[i + 1][j] ^ b[i][j + 1] ^ a[i][j];
					var ok = true;
					var c = Enumerate(n + 1, m + 1, (x, y) => b[x % 2][y % 2]);
					for (int i = 0; i <= n; i++)
						for (int j = 0; j <= m; j++) ok &= b[i][j] == c[i][j];
					if (ok) {
						for (int i = 0; i <= n; i++)
							Debug.WriteLine(b[i].AsJoinedString());
						Debug.WriteLine("---");
					}
				}
				max = Max(max, cnt);
			}
			Debug.WriteLine(max);
		}
		const long INF = 1L << 60;
		static int[] dx = { -1, 0, 1, 0 };
		static int[] dy = { 0, 1, 0, -1 };
		int ri { get { return sc.Integer(); } }
		long rl { get { return sc.Long(); } }
		double rd { get { return sc.Double(); } }
		string rs { get { return sc.Scan(); } }
		public IO.StreamScanner sc = new IO.StreamScanner(Console.OpenStandardInput());
		static T[] Enumerate<T>(int n, Func<int, T> f) {
			var a = new T[n]; for (int i = 0; i < a.Length; ++i) a[i] = f(i); return a;
		}
		static T[][] Enumerate<T>(int n, int m, Func<int, int, T> f) {
			return Enumerate(n, x => Enumerate(m, y => f(x, y)));
		}
		static public void Swap<T>(ref T a, ref T b) { var tmp = a; a = b; b = tmp; }
	}
}

#region main
static class Ex {
	static public string AsString(this IEnumerable<char> ie) { return new string(ie.ToArray()); }
	static public string AsJoinedString<T>(this IEnumerable<T> ie, string st = " ") {
		return string.Join(st, ie);
	}
	static public void Main() {
		Console.SetOut(new Program.IO.Printer(Console.OpenStandardOutput()) { AutoFlush = false });
		var solver = new Program.Solver();
		//* 
		var t = new System.Threading.Thread(solver.Solve, 200000000);
		t.Start();
		t.Join();
		//*/
		// solver.Solve();
		Console.Out.Flush();
	}
}
#endregion
#region Ex
namespace Program.IO {
	using System.IO;
	using System.Text;
	using System.Globalization;

	public class Printer : StreamWriter {
		public override IFormatProvider FormatProvider { get { return CultureInfo.InvariantCulture; } }
		public Printer(Stream stream) : base(stream, new UTF8Encoding(false, true)) { }
	}

	public class StreamScanner {
		public StreamScanner(Stream stream) { str = stream; }

		public readonly Stream str;
		private readonly byte[] buf = new byte[1024];
		private int len, ptr;
		public bool isEof = false;
		public bool IsEndOfStream { get { return isEof; } }

		private byte read() {
			if (isEof) return 0;
			if (ptr >= len) {
				ptr = 0;
				if ((len = str.Read(buf, 0, 1024)) <= 0) {
					isEof = true;
					return 0;
				}
			}
			return buf[ptr++];
		}

		public char Char() {
			byte b = 0;
			do b = read(); while ((b < 33 || 126 < b) && !isEof);
			return (char)b;
		}
		public string Scan() {
			var sb = new StringBuilder();
			for (var b = Char(); b >= 33 && b <= 126; b = (char)read()) sb.Append(b);
			return sb.ToString();
		}
		public string ScanLine() {
			var sb = new StringBuilder();
			for (var b = Char(); b != '\n' && b != 0; b = (char)read()) if (b != '\r') sb.Append(b);
			return sb.ToString();
		}
		public long Long() { return isEof ? long.MinValue : long.Parse(Scan()); }
		public int Integer() { return isEof ? int.MinValue : int.Parse(Scan()); }
		public double Double() { return isEof ? double.NaN : double.Parse(Scan(), CultureInfo.InvariantCulture); }
	}
}

#endregion
#region Disjoint Set
/// <summary>
/// いくつかの要素を素集合に分割して保持するコレクションです．
/// </summary>
public class DisjointSet {
	int[] par;
	byte[] rank;
	/// <summary>
	/// 0 から <paramref name="N"/>-1 までの番号がついた <paramref name="N"/> 個の要素からなる集合を作成します．
	/// </summary>
	/// <param name="N">要素数</param>
	/// <remarks>このコンストラクタは O(N) で実行されます．</remarks>
	public DisjointSet(int N) {
		par = new int[N];
		rank = new byte[N];
		for (int i = 0; i < N; i++)
			par[i] = -1;
	}
	/// <summary>
	/// 指定した要素が属する集合の代表値を取得します．
	/// </summary>
	/// <param name="id">調べたい要素の 0-indexed での番号</param>
	/// <returns>指定した要素が属する集合の代表値</returns>
	/// <remarks>最悪計算量 O(α(N)) で実行されます．</remarks>
	public int this[int id] {
		get {
			if ((par[id] < 0)) return id;
			return par[id] = this[par[id]];
		}
	}
	/// <summary>
	/// 指定した 2 つの要素が属する集合同士を 1 つに統合することを試みます．
	/// </summary>
	/// <param name="x">最初の要素の 0-indexed での番号</param>
	/// <param name="y">2 つ目の要素の 0-indexed での番号</param>
	/// <returns>統合に成功したならば true，そうでなければ false．</returns>
	/// <remarks>最悪計算量 O(α(N)) で実行されます．</remarks>
	public bool Unite(int x, int y) {
		x = this[x]; y = this[y];
		if (x == y) return false;
		if (rank[x] < rank[y]) { var tmp = x; x = y; y = tmp; }
		par[x] += par[y];
		par[y] = x;
		if (rank[x] == rank[y])
			rank[x]++;
		return true;
	}
	/// <summary>
	/// 指定した要素が属する集合のサイズを取得します．
	/// </summary>
	/// <param name="x">指定する要素の 0-indexed での番号</param>
	/// <returns>集合のサイズ</returns>
	/// <remarks>最悪計算量 O(α(N)) で実行されます．</remarks>
	public int Size(int x) { return -par[this[x]]; }

	/// <summary>
	/// 指定した 2 つの要素が属する集合が同じかどうかを判定する．計算量 O(α(N))．
	/// </summary>
	/// <param name="x">最初の要素の 0-indexed での番号</param>
	/// <param name="y">2 つ目の要素の 0-indexed での番号</param>
	/// <returns>同じならば true，そうでなければ false．</returns>
	/// <remarks>最悪計算量 O(α(N)) で実行されます．</remarks>
	public bool Same(int x, int y) { return this[x] == this[y]; }

}
#endregion
#region ModInt
/// <summary>
/// [0,<see cref="Mod"/>) までの値を取るような数
/// </summary>
public struct ModInt {
	/// <summary>
	/// 剰余を取る値．
	/// </summary>
	public const long Mod = 998244353;

	/// <summary>
	/// 実際の数値．
	/// </summary>
	public long num;
	/// <summary>
	/// 値が <paramref name="n"/> であるようなインスタンスを構築します．
	/// </summary>
	/// <param name="n">インスタンスが持つ値</param>
	/// <remarks>パフォーマンスの問題上，コンストラクタ内では剰余を取りません．そのため，<paramref name="n"/> ∈ [0,<see cref="Mod"/>) を満たすような <paramref name="n"/> を渡してください．このコンストラクタは O(1) で実行されます．</remarks>
	public ModInt(long n) { num = n; }
	/// <summary>
	/// このインスタンスの数値を文字列に変換します．
	/// </summary>
	/// <returns>[0,<see cref="Mod"/>) の範囲内の整数を 10 進表記したもの．</returns>
	public override string ToString() { return num.ToString(); }
	public static ModInt operator +(ModInt l, ModInt r) { l.num += r.num; if (l.num >= Mod) l.num -= Mod; return l; }
	public static ModInt operator -(ModInt l, ModInt r) { l.num -= r.num; if (l.num < 0) l.num += Mod; return l; }
	public static ModInt operator *(ModInt l, ModInt r) { return new ModInt(l.num * r.num % Mod); }
	public static implicit operator ModInt(long n) { n %= Mod; if (n < 0) n += Mod; return new ModInt(n); }

	/// <summary>
	/// 与えられた 2 つの数値からべき剰余を計算します．
	/// </summary>
	/// <param name="v">べき乗の底</param>
	/// <param name="k">べき指数</param>
	/// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
	public static ModInt Pow(ModInt v, long k) { return Pow(v.num, k); }

	/// <summary>
	/// 与えられた 2 つの数値からべき剰余を計算します．
	/// </summary>
	/// <param name="v">べき乗の底</param>
	/// <param name="k">べき指数</param>
	/// <returns>繰り返し二乗法により O(N log N) で実行されます．</returns>
	public static ModInt Pow(long v, long k) {
		long ret = 1;
		for (k %= Mod - 1; k > 0; k >>= 1, v = v * v % Mod)
			if ((k & 1) == 1) ret = ret * v % Mod;
		return new ModInt(ret);
	}
	/// <summary>
	/// 与えられた数の逆元を計算します．
	/// </summary>
	/// <param name="v">逆元を取る対象となる数</param>
	/// <returns>逆元となるような値</returns>
	/// <remarks>法が素数であることを仮定して，フェルマーの小定理に従って逆元を O(log N) で計算します．</remarks>
	public static ModInt Inverse(ModInt v) { return Pow(v, Mod - 2); }
}
#endregion