using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {x} {u} {v} {cnt - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
				for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
				if (s.Length > m - 1)
					nt.Append("$");
				for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
				for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
				//Console.WriteLine($"tmp {tmp.ToString()}");
				var nb = a + b + count(tmp.ToString(), p);
				a = b;
				b = nb;
				s = t;
				t = nt.ToString();
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"{s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//onsole.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (len > 14) {
					//nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					//tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					//nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					//tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//onsole.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (len > 11) {
					//nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					//tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					//nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					//tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; var k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"{s + '0'} {cnt}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {cnt - u - v}");
					k -= cnt - u - v;
				}
				else {
					s += "1";
					cnt += f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {cnt - u - v}");
					k -= cnt - u - v;

				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		long f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
				for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
				if (s.Length > m - 1)
					nt.Append("$");
				for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
				for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
				//Console.WriteLine($"tmp {tmp.ToString()}");
				var nb = Min(INF, a + b + count(tmp.ToString(), p));
				a = b;
				b = nb;
				s = t;
				t = nt.ToString();
			}
			return b;
		}
		long count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + s);
			var cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + m] >= m) cnt++;
			//Console.WriteLine($"{s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					Console.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (s.Length > 250) {
					nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					//for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					//for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					//for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					//for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;

				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
				}
				//Console.WriteLine($"{nt.ToString()} {tmp.ToString()} {nb}");
				//var ntt = s + t;
				s = t;
				t = nt.ToString();
				//t = ntt;
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					Console.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (len > 10) {
					nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					//for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					//for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					//for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					//for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (s.Length > 250) {
					nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					//for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					//for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					//for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					//for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;

				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
				}
				//Console.WriteLine($"{nt.ToString()} {tmp.ToString()} {nb}");
				//var ntt = s + t;
				s = t;
				t = nt.ToString();
				//t = ntt;
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//onsole.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return a + b + count(s + t, p);
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (s.Length >= m) {
					//nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					//tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					//nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					//tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Linq;
using System.Collections.Generic;
using System.Diagnostics;
using Debug = System.Diagnostics.Trace;
using SB = System.Text.StringBuilder;
using System.Numerics;
using static System.Math;
using static System.Console;
using Number = System.Int64;
namespace Program {
	public class Solver {
		Random rnd = new Random();
		public void Solve() {
			var n = ri; BigInteger k = rl; var m = ri;
			var s = "";
			for (int i = 0; i < m; i++) {
				var cnt = f(s + "0", n);
				//Console.WriteLine($"now {s + '0'} {cnt} {k}");
				if (k <= cnt) {
					s += "0";
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//Console.WriteLine($"{s} {cnt} {u} {v} {cnt - u - v}");
					if (cnt - u - v != 0) k--;
				}
				else {
					k -= cnt;
					s += "1";
					var x = f(s, n);
					var u = f(s + "0", n);
					var v = f(s + "1", n);
					//onsole.WriteLine($"{s} {cnt} {x} {u} {v} {x - u - v}");
					if (x - u - v != 0) k--;
				}
				if (k <= 0) break;
			}
			Console.WriteLine(s);
		}
		BigInteger f(string p, int n) {
			//Console.WriteLine($"func {p}");
			var s = "0";
			var t = "1";
			var a = count(s, p);
			var b = count(t, p);

			var m = p.Length;
			if (n == 0) return a;
			else if (n == 1) return b;
			for (int len = 1; len < n; len++) {

				var tmp = new SB();
				var nt = new SB();
				if (len > 14) {
					//nt.Append(s.Substring(0, Min(s.Length, m - 1)));
					//tmp.Append(s.Reverse().Take(Min(s.Length, m - 1)).Reverse().AsString());
					for (int i = 0; i < Min(s.Length, m - 1); i++) nt.Append(s[i]);
					for (int i = Min(m - 2, s.Length - 1); i >= 0; i--) tmp.Append(s[s.Length - 1 - i]);
					//nt.Append(t.Reverse().Take(Min(t.Length, m - 1)).Reverse().AsString());
					//tmp.Append(t.Substring(0, Min(t.Length, m - 1)));
					for (int i = Min(m - 2, t.Length - 1); i >= 0; i--) nt.Append(t[t.Length - 1 - i]);
					for (int i = 0; i < Min(t.Length, m - 1); i++) tmp.Append(t[i]);
					//Console.WriteLine($"tmp {tmp.ToString()}");
					var nb = a + b + count(tmp.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
				else {
					nt.Append(s + t);
					var nb = count(nt.ToString(), p);
					a = b;
					b = nb;
					s = t;
					t = nt.ToString();
				}
			}
			return b;
		}
		BigInteger count(string s, string p) {
			var n = s.Length;
			var m = p.Length;
			var z = stringEx.ZAlgorithm(p + "#" + s);
			long cnt = 0;
			for (int i = 0; i < n; i++)
				if (z[i + 1 + m] >= m) cnt++;
			//Console.WriteLine($"count {s} {p} {cnt}");
			return cnt;
		}

		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 < n; ++i) a[i] = f(i);
			return a;
		}
		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();
		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 Z algorithm
static public partial class stringEx {
	/// <summary> <paramref name="s"/> と <paramref name="s"/>[i:] の最長共通接頭辞を O(|<paramref name="s"/>|) で求める。</summary>
	static public int[] ZAlgorithm(string s) {
		var a = new int[s.Length + 1];
		a[0] = s.Length;
		int i = 1, j = 0;
		while (i < s.Length) {
			while (i + j < s.Length && s[j] == s[i + j]) ++j;
			a[i] = j;
			if (j == 0) { ++i; continue; }
			int k = 1;
			while (i + k < s.Length && k + a[k] < j) { a[i + k] = a[k]; ++k; }
			i += k; j -= k;
		}
		return a;
	}
}
#endregion


using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Text;

namespace codeforces
{
	class Program
	{
		public const int Osn = 1000000007;

		public class Pair
		{
			public long First;

			public long Second;
		}

		public class PairComparer : IComparer<Pair>
		{
			public int Compare(Pair x, Pair y)
			{
				if (x.First < y.First || (x.First == y.First && x.Second > y.Second))
					return -1;
				return 1;
			}
		}

		public static long GetGcd(long a, long b)
		{
			while (true)
			{
				if (b == 0)
					return a;
				var a1 = a;
				a = b;
				b = a1 % b;

			}
		}

		public static void WriteYesNo(bool x, string yes = "YES", string no = "NO")
		{
			if (x)
				Console.WriteLine(yes);
			else
			{
				Console.WriteLine(no);
			}
		}

		public static string ReadString()
		{
			return Console.ReadLine();
		}

		public static List<int> ReadListOfInts()
		{
			var s = Console.ReadLine();
			return s.Split(' ').Select(int.Parse).ToList();
		}

		public static List<long> ReadListOfLongs()
		{
			var s = Console.ReadLine();
			return s.Split(' ').Select(long.Parse).ToList();
		}

		public static int ReadInt()
		{
			var s = Console.ReadLine();
			return int.Parse(s);
		}

		public static long ReadLong()
		{
			var s = Console.ReadLine();
			return long.Parse(s);
		}

		public class Vertex
		{
			public int Was;

			public List<int> Edges;
		}

		public static List<Vertex> Graph = new List<Vertex>();

		public static bool Dfs(int u)
		{
			if (Graph[u].Was == 1) return true;
			if (Graph[u].Was == 2) return false;
			Graph[u].Was = 1;
			foreach (var t in Graph[u].Edges)
			{
				if (Dfs(t)) return true;
			}

			Graph[u].Was = 2;
			return false;
		}

		public static bool IsPrime(int x)
		{
			for (var j = 2; j * j <= x; ++j)
				if (x % j == 0)
					return false;
			return true;
		}

		public class LinkedVertex
		{
			public int Next;

			public int Prev;

			public int Value;
		}

		public static int BinarySearch(List<int> list, int value)
		{
			var l = -1;
			var r = list.Count;
			while (r - l > 1)
			{
				var m = (r + l) / 2;
				if (list[m] >= value)
					r = m;
				else
					l = m;
			}

			return r;
		}

		private static void Main()
		{
			var l = ReadListOfLongs();
			var a = l[0];
			var b = l[1];
			long ans = (a * (a + 1) / 2) % Osn;
			ans = (ans * b + a) % Osn;
			ans = (((b * (b - 1) / 2) % Osn) * ans) % Osn;
			Console.WriteLine(ans);
			Console.ReadLine();
		}
	}
}


using System;
using System.IO;

namespace CF272
{
    class Program
    {
        static void Main(string[] args)
        {
            Solution(Console.In, Console.Out);
        }

        static void Solution(TextReader sr, TextWriter sw)
        {
            const long module = 1000000007L;
            string[] input = sr.ReadLine().Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
            long a = Int64.Parse(input[0]);
            long b = Int64.Parse(input[1]);
            if (b == 1)
            {
                Console.WriteLine(0);
                return;
            }
            long sum = 0L;
            for (long i = 1; i <= a; i++)
            {
                long first = (i*b + 1)%module;
                long second = (b*(b - 1)/2)%module;
                sum += (first * second) % module;
            }
            Console.WriteLine(sum%module);
        }
    }
}


using System;
using System.Collections.Generic;
using System.IO;

namespace prC {

    class Program {
#if ONLINE_JUDGE
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024 * 10), System.Text.Encoding.ASCII, false, 1024 * 10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024 * 10), System.Text.Encoding.ASCII, 1024 * 10);
#else
        private static readonly StreamWriter writer = new StreamWriter("output");
        private static readonly StreamReader reader = new StreamReader("input");
#endif
        static void Main(string[] args) {
            long a = Next();
            long b = Next();
            long ans = 0;
            const long m = 1000000007;
            long b1 = b - 1;
            long d = b1 * (b1 + 1) / 2;
            d = d % m;
            for(long k = 1; k <= a; k++) {
                long y = k * b + 1;
                y %= m;
                long s = y * d;
                s %= m;
                ans = (ans + s) % m;
            }
            writer.WriteLine(ans);

            writer.Flush();
#if !ONLINE_JUDGE
            writer.Close();
#endif
        }
        private static long Next() {
            long c;
            long res = 0;
            do {
                c = reader.Read();
                if(c == -1)
                    return res;
            } while(c != '-' && (c < '0' || c > '9'));
            int sign = 1;
            if(c == '-') {
                sign = -1;
                c = reader.Read();
            }
            res = c - '0';
            while(true) {
                c = reader.Read();
                if(c < '0' || c > '9')
                    return res * sign;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;
using System.Linq;
using System.Numerics;
using System.Text;
using System.Threading;

// (づ°ω°)づﾐ★゜・。。・゜゜・。。・゜☆゜・。。・゜゜・。。・゜
public class Solver
{
    private const int MOD = 1000000007;

    public object Solve()
    {
        long a = ReadInt();
        long b = ReadInt();

        long ans = 0;
        for (int i = 1; i <= a; i++)
            ans = (ans + b * (b - 1) / 2 % MOD * (i * b % MOD + 1) % MOD) % MOD;

        return ans;

        return null;
    }

    #region Main

    protected static TextReader reader;
    protected static TextWriter writer;

    static void Main()
    {
#if DEBUG
        reader = new StreamReader("..\\..\\input.txt");
        writer = Console.Out;
        //writer = new StreamWriter("..\\..\\output.txt");
#else
        reader = new StreamReader(Console.OpenStandardInput());
        writer = new StreamWriter(Console.OpenStandardOutput());
//        reader = new StreamReader("army.in");
//        writer = new StreamWriter("army.out");
#endif
        try
        {
            object result = new Solver().Solve();
            if (result != null)
                writer.WriteLine(result);
        }
        catch (Exception ex)
        {
#if DEBUG
            Console.WriteLine(ex);
#else
            Console.WriteLine(ex);
            throw;
#endif
        }
        reader.Close();
        writer.Close();
    }

    #endregion

    #region Read / Write

    private static Queue<string> currentLineTokens = new Queue<string>();

    private static string[] ReadAndSplitLine()
    {
        return reader.ReadLine().Split(new[] { ' ', '\t' }, StringSplitOptions.RemoveEmptyEntries);
    }

    public static string ReadToken()
    {
        while (currentLineTokens.Count == 0)
            currentLineTokens = new Queue<string>(ReadAndSplitLine());
        return currentLineTokens.Dequeue();
    }

    public static int ReadInt()
    {
        return int.Parse(ReadToken());
    }

    public static long ReadLong()
    {
        return long.Parse(ReadToken());
    }

    public static double ReadDouble()
    {
        return double.Parse(ReadToken(), CultureInfo.InvariantCulture);
    }

    public static int[] ReadIntArray()
    {
        return ReadAndSplitLine().Select(int.Parse).ToArray();
    }

    public static long[] ReadLongArray()
    {
        return ReadAndSplitLine().Select(long.Parse).ToArray();
    }

    public static double[] ReadDoubleArray()
    {
        return ReadAndSplitLine().Select(s => double.Parse(s, CultureInfo.InvariantCulture)).ToArray();
    }

    public static int[][] ReadIntMatrix(int numberOfRows)
    {
        int[][] matrix = new int[numberOfRows][];
        for (int i = 0; i < numberOfRows; i++)
            matrix[i] = ReadIntArray();
        return matrix;
    }

    public static int[][] ReadAndTransposeIntMatrix(int numberOfRows)
    {
        int[][] matrix = ReadIntMatrix(numberOfRows);
        int[][] ret = new int[matrix[0].Length][];
        for (int i = 0; i < ret.Length; i++)
        {
            ret[i] = new int[numberOfRows];
            for (int j = 0; j < numberOfRows; j++)
                ret[i][j] = matrix[j][i];
        }
        return ret;
    }

    public static string[] ReadLines(int quantity)
    {
        string[] lines = new string[quantity];
        for (int i = 0; i < quantity; i++)
            lines[i] = reader.ReadLine().Trim();
        return lines;
    }

    public static void WriteArray<T>(IEnumerable<T> array)
    {
        writer.WriteLine(string.Join(" ", array));
    }

    public static void Write<T>(params T[] array)
    {
        WriteArray(array);
    }

    public static void WriteLines<T>(IEnumerable<T> array)
    {
        foreach (var a in array)
            writer.WriteLine(a);
    }

    #endregion
}


using System;
using System.Collections;
using System.Collections.Generic;

class TEST{
    static void Main(){
        Sol mySol =new Sol();
        mySol.Solve();
    }
}

class Sol{
    public void Solve(){
        long mod=(long)(1e9+7);
        if(B==1){
            Console.WriteLine(0);
            return;
        }

        long xx=(B-1)*B;
        xx/=2;
        xx%=mod;

        long yy=A*(A+1);
        yy/=2;yy%=mod;
        yy*=B;
        yy%=mod;
        yy+=A;

        long Ans=xx*yy;
        Ans%=mod;
        Console.WriteLine(Ans);

    }
    long A;
    long B;
    public Sol(){
        var d=rla();
        A=d[0];B=d[1];
    }

    static String rs(){return Console.ReadLine();}
    static int ri(){return int.Parse(Console.ReadLine());}
    static long rl(){return long.Parse(Console.ReadLine());}
    static double rd(){return double.Parse(Console.ReadLine());}
    static String[] rsa(){return Console.ReadLine().Split(' ');}
    static int[] ria(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>int.Parse(e));}
    static long[] rla(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>long.Parse(e));}
    static double[] rda(){return Array.ConvertAll(Console.ReadLine().Split(' '),e=>double.Parse(e));}
}


using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Test
{
    class IOHelper : IDisposable
    {
        StreamReader reader;
        StreamWriter writer;

        public IOHelper(string inputFile, string outputFile, Encoding encoding)
        {
            StreamReader iReader;
            StreamWriter oWriter;
            if (inputFile == null)
                iReader = new StreamReader(Console.OpenStandardInput(), encoding);
            else
                iReader = new StreamReader(inputFile, encoding);

            if (outputFile == null)
                oWriter = new StreamWriter(Console.OpenStandardOutput(), encoding);
            else
                oWriter = new StreamWriter(outputFile, false, encoding);

            reader = iReader;
            writer = oWriter;

            curLine = new string[] { };
            curTokenIdx = 0;
        }

        string[] curLine;
        int curTokenIdx;

        char[] whiteSpaces = new char[] { ' ', '\t', '\r', '\n' };

        public string ReadNextToken()
        {
            if (curTokenIdx >= curLine.Length)
            {
                //Read next line
                string line = reader.ReadLine();
                if (line != null)
                    curLine = line.Split(whiteSpaces, StringSplitOptions.RemoveEmptyEntries);
                else
                    curLine = new string[] { };
                curTokenIdx = 0;
            }

            if (curTokenIdx >= curLine.Length)
                return null;

            return curLine[curTokenIdx++];
        }

        public int ReadNextInt()
        {
            return int.Parse(ReadNextToken());
        }

        public double ReadNextDouble()
        {
            return double.Parse(ReadNextToken());
        }

        public void Write(string stringToWrite)
        {
            writer.Write(stringToWrite);
        }

        public void WriteLine(string stringToWrite)
        {
            writer.WriteLine(stringToWrite);
        }

        public void Dispose()
        {
            try
            {
                if (reader != null)
                {
                    reader.Dispose();
                }
                if (writer != null)
                {
                    writer.Dispose();
                }
            }
            catch { };
        }

    }

    class Program
    {
        protected IOHelper ioHelper;

        public void Solve()
        {
            int a = ioHelper.ReadNextInt();
            int b = ioHelper.ReadNextInt();
            long p = 1000000007;

            if (b <= 1)
                ioHelper.WriteLine("0");
            else
            {
                long left1 = b;
                long interm1 = (long)a * (a + 1) / 2;
                interm1 %= p;
                left1 *= interm1;
                left1 %= p;
                left1 += a;
                left1 %= p;
                long right1 = (long)b * (b - 1) / 2;
                right1 %= p;
                long result = left1 * right1;
                result %= p;
                ioHelper.WriteLine(string.Format("{0}", result));
            }
            ioHelper.Dispose();
        }

        public Program(string inputFile, string outputFile)
        {
            ioHelper = new IOHelper(inputFile, outputFile, Encoding.Default);
            Solve();
        }

        static void Main(string[] args)
        {
            Program myProgram = new Program(null, null);
        }
    }
}


using System;
using System.Collections.Generic;
using System.Linq;
using Solver.Ex;
using Watch = System.Diagnostics.Stopwatch;
using StringBuilder = System.Text.StringBuilder;
using BitVector = System.Collections.Specialized.BitVector32;
namespace Solver
{
    public class Solver
    {
        public void Solve()
        {
            var a = sc.Long();
            var b = sc.Long();
            const long mod = (long)1e9 + 7;
            var sum = (((((a * (a + 1) / 2) % mod) * b + a) % mod) * (((b * (b - 1) / 2)) % mod)) % mod;
            IO.Printer.Out.PrintLine(sum);
        }

        internal IO.StreamScanner sc;

    }

    #region Main and Settings
    static class Program
    {
        static void Main(string[] arg)
        {
#if DEBUG
            var errStream = new System.IO.FileStream(@"..\..\dbg.out", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            System.Diagnostics.Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(errStream, "debugStream"));
            System.Diagnostics.Debug.AutoFlush = false;
            var sw = new Watch();
            sw.Start();
            try
            {
#endif
                var solver = new Solver();
                solver.sc = new IO.StreamScanner(Console.OpenStandardInput());
                IO.Printer.Out = new IO.Printer(new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
                solver.Solve();
                IO.Printer.Out.Flush();
#if DEBUG
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                Console.Error.WriteLine(ex.StackTrace);
            }
            finally
            {
                sw.Stop();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Error.WriteLine("Time:{0}ms", sw.ElapsedMilliseconds);
                System.Diagnostics.Debug.Close();
                System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
            }
#endif
        }

    }
    #endregion
}
#region IO Helper
namespace Solver.IO
{
    public class Printer
    {
        static Printer()
        {
            Out = new Printer(Console.Out);
        }
        public static Printer Out { get; set; }
        private readonly System.IO.TextWriter writer;
        private readonly System.Globalization.CultureInfo info;
        public string Separator { get; set; }
        public string NewLine { get { return writer.NewLine; } set { writer.NewLine = value ?? "\n"; } }
        public Printer(System.IO.TextWriter tw = null, System.Globalization.CultureInfo ci = null, string separator = null, string newLine = null)
        {
            writer = tw ?? System.IO.TextWriter.Null;
            info = ci ?? System.Globalization.CultureInfo.InvariantCulture;
            NewLine = newLine;
            Separator = separator ?? " ";
        }
        public void Print(int num) { writer.Write(num.ToString(info)); }
        public void Print(int num, string format) { writer.Write(num.ToString(format, info)); }
        public void Print(long num) { writer.Write(num.ToString(info)); }
        public void Print(long num, string format) { writer.Write(num.ToString(format, info)); }
        public void Print(double num) { writer.Write(num.ToString("F12", info)); }
        public void Print(double num, string format) { writer.Write(num.ToString(format, info)); }
        public void Print(string str) { writer.Write(str); }
        public void Print(string format, params object[] arg) { writer.Write(string.Format(info, format, arg)); }
        public void Print<T>(string format, IEnumerable<T> sources) { writer.Write(format, sources.OfType<object>().ToArray()); }
        public void Print(IEnumerable<char> sources) { writer.Write(sources.AsString()); }
        public void Print<T>(IEnumerable<T> sources)
        {
            var res = new System.Text.StringBuilder();
            foreach (var x in sources)
            {
                res.AppendFormat(info, "{0}", x);
                if (string.IsNullOrEmpty(Separator))
                    res.Append(Separator);
            }
            writer.Write(res.ToString(0, res.Length - Separator.Length));
        }
        public void PrintLine() { writer.WriteLine(); }
        public void PrintLine(int num) { writer.WriteLine(num.ToString(info)); }
        public void PrintLine(int num, string format) { writer.WriteLine(num.ToString(format, info)); }
        public void PrintLine(long num) { writer.WriteLine(num.ToString(info)); }
        public void PrintLine(long num, string format) { writer.WriteLine(num.ToString(format, info)); }
        public void PrintLine(double num) { writer.WriteLine(num.ToString("F12", info)); }
        public void PrintLine(double num, string format) { writer.WriteLine(num.ToString(format, info)); }
        public void PrintLine(string str) { writer.WriteLine(str); }
        public void PrintLine(string format, params object[] arg) { writer.WriteLine(string.Format(info, format, arg)); }
        public void PrintLine<T>(string format, IEnumerable<T> sources) { writer.WriteLine(format, sources.OfType<object>().ToArray()); }
        public void PrintLine<T>(IEnumerable<T> sources)
        {
            var res = new StringBuilder();
            foreach (var x in sources)
            {
                res.AppendFormat(info, "{0}", x);
                if (!string.IsNullOrEmpty(Separator))
                    res.Append(Separator);
            }
            writer.WriteLine(res.ToString(0, res.Length - Separator.Length));
        }
        public void Flush() { writer.Flush(); }
    }
    public class StreamScanner
    {
        public StreamScanner(System.IO.Stream stream)
        {
            iStream = stream;
        }
        private readonly System.IO.Stream iStream;
        private readonly byte[] buf = new byte[1024];
        private int len, ptr;
        private bool eof = false;
        public bool EndOfStream { get { return eof; } }
        private byte readByte()
        {
            if (eof) throw new System.IO.EndOfStreamException();
            if (ptr >= len)
            {
                ptr = 0;
                len = iStream.Read(buf, 0, 1024);
                if (len <= 0)
                {
                    eof = true;
                    return 0;
                }
            }
            return buf[ptr++];
        }
        private bool inSpan(byte c)
        {
            const byte lb = 33, ub = 126;
            return !(c >= lb && c <= ub);
        }
        private byte skip()
        {
            byte b = 0;
            do b = readByte();
            while (!eof && inSpan(b));
            return b;
        }
        public char Char()
        {
            return (char)skip();
        }
        public char[] Char(int n)
        {
            var a = new char[n];
            for (int i = 0; i < n; i++)
                a[i] = (char)skip();
            return a;
        }
        public char[][] Char(int n, int m)
        {
            var a = new char[n][];
            for (int i = 0; i < n; i++)
                a[i] = Char(m);
            return a;
        }
        public string Scan()
        {

            const byte lb = 33, ub = 126;
            if (eof) throw new System.IO.EndOfStreamException();

            do
            {
                while (ptr < len && (buf[ptr] < lb || ub < buf[ptr]))
                {
                    ptr++;
                }
                if (ptr < len)
                    break;
                ptr = 0;
                len = iStream.Read(buf, 0, 1024);
                if (len <= 0)
                {
                    eof = true;
                    return null;
                }
                continue;
            } while (true);

            StringBuilder sb = null;
            do
            {
                var i = ptr;
                while (i < len)
                {
                    if (buf[i] < lb || ub < buf[i])
                    {
                        string s;
                        if (sb != null)
                        {
                            sb.Append(System.Text.UTF8Encoding.Default.GetChars(buf, ptr, i - ptr));
                            s = sb.ToString();
                        }
                        else s = new string(System.Text.UTF8Encoding.Default.GetChars(buf, ptr, i - ptr));
                        ptr = i + 1;
                        return s;
                    }
                    i++;
                }
                i = len - ptr;
                if (sb == null) sb = new StringBuilder(i + 32);
                sb.Append(System.Text.UTF8Encoding.Default.GetChars(buf, ptr, i));
                ptr = 0;
            } while ((len = iStream.Read(buf, 0, 1024)) > 0);
            eof = true;
            return sb.ToString();
        }
        public string[] Scan(int n)
        {
            var a = new string[n];
            for (int i = 0; i < n; i++)
                a[i] = Scan();
            return a;
        }
        public string ScanLine()
        {
            const byte el = 10;
            if (eof) throw new System.IO.EndOfStreamException();
            StringBuilder sb = null;
            do
            {
                var i = ptr;
                while (i < len)
                {
                    if (buf[i] == el)
                    {
                        string s;
                        if (sb != null)
                        {
                            sb.Append(System.Text.UTF8Encoding.Default.GetChars(buf, ptr, i - ptr));
                            s = sb.ToString();
                        }
                        else s = new string(System.Text.UTF8Encoding.Default.GetChars(buf, ptr, i - ptr));
                        ptr = i + 1;
                        return s;
                    }
                    i++;
                }
                i = len - ptr;
                if (sb == null) sb = new StringBuilder(i + 32);
                sb.Append(System.Text.UTF8Encoding.Default.GetChars(buf, ptr, i));
                ptr = 0;
            } while ((len = iStream.Read(buf, 0, 1024)) > 0);
            eof = true;
            return sb.ToString();
        }
        public double Double()
        {
            return double.Parse(Scan(), System.Globalization.CultureInfo.InvariantCulture);
        }
        public double[] Double(int n)
        {
            var a = new double[n];
            for (int i = 0; i < n; i++)
                a[i] = Double();
            return a;
        }
        public int Integer()
        {
            var ret = 0;
            byte b = 0;
            bool isMynus = false;
            const byte zero = 48, nine = 57, mynus = 45;
            do b = readByte();
            while (!eof && !((b >= zero && b <= nine) || b == mynus));

            if (b == mynus)
            {
                isMynus = true;
                b = readByte();
            }
            while (true)
            {
                if (b >= zero && b <= nine)
                {
                    ret = ret * 10 + b - zero;
                }
                else return isMynus ? -ret : ret;
                b = readByte();
            }

        }
        public int[] Integer(int n)
        {
            var a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = Integer();
            return a;
        }
        public long Long()
        {
            long ret = 0;
            byte b = 0;
            bool isMynus = false;
            const byte zero = 48, nine = 57, mynus = 45;
            do b = readByte();
            while (!eof && !((b >= zero && b <= nine) || b == mynus));
            if (b == '-')
            {
                isMynus = true;
                b = readByte();
            }
            while (true)
            {
                if (b >= zero && b <= nine)
                    ret = ret * 10 + (b - zero);
                else return isMynus ? -ret : ret;
                b = readByte();
            }

        }
        public long[] Long(int n)
        {
            var a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = Long();
            return a;
        }
        public void Flush()
        {
            iStream.Flush();
        }

    }

}
#endregion
#region Extension
namespace Solver.Ex
{
    static public partial class EnumerableEx
    {
        static public string AsString(this IEnumerable<char> source)
        {
            return new string(source.ToArray());
        }
        static public string AsJoinedString<T>(this IEnumerable<T> source, string separator = " ")
        {
            return string.Join(separator, source);
        }
        static public T[] Enumerate<T>(this int n, Func<int, T> selector)
        {
            var res = new T[n];
            for (int i = 0; i < n; i++)
                res[i] = selector(i);
            return res;
        }
    }
}
#endregion


using System;
using System.Collections.Generic;
using System.Linq;
using Solver.Ex;
using Watch = System.Diagnostics.Stopwatch;
using StringBuilder = System.Text.StringBuilder;
using BitVector = System.Collections.Specialized.BitVector32;
namespace Solver
{
    public class Solver
    {
        public void Solve()
        {
            var a = sc.Long();
            var b = sc.Long();
            const long mod = (long)1e9 + 7;
            var ret = ((((a * (a + 1) / 2) % mod) * b + a) % mod) * ((b * (b - 1) / 2) % mod) % mod;
            IO.Printer.Out.PrintLine(ret);
        }
        internal IO.Scanner sc;

    }
    #region Main and Settings
    static class Program
    {
        static void Main(string[] arg)
        {
#if DEBUG
            var errStream = new System.IO.FileStream(@"..\..\dbg.out", System.IO.FileMode.Create, System.IO.FileAccess.Write, System.IO.FileShare.ReadWrite);
            System.Diagnostics.Debug.Listeners.Add(new System.Diagnostics.TextWriterTraceListener(errStream, "debugStream"));
            System.Diagnostics.Debug.AutoFlush = false;
            var sw = new Watch();
            sw.Start();
            try
            {
#endif
            var solver = new Solver();
            solver.sc = new IO.Scanner(Console.In);
            IO.Printer.Out = new IO.Printer(new System.IO.StreamWriter(Console.OpenStandardOutput()) { AutoFlush = false });
            solver.Solve();
            IO.Printer.Out.Flush();
#if DEBUG
            }
            catch (Exception ex)
            {
                Console.Error.WriteLine(ex.Message);
                Console.Error.WriteLine(ex.StackTrace);
            }
            finally
            {
                sw.Stop();
                Console.ForegroundColor = ConsoleColor.Green;
                Console.Error.WriteLine("Time:{0}ms", sw.ElapsedMilliseconds);
                System.Diagnostics.Debug.Close();
                System.Threading.Thread.Sleep(System.Threading.Timeout.Infinite);
            }
#endif
        }

    }
    #endregion
}
#region IO Helper
namespace Solver.IO
{
    public class Printer
    {
        static Printer()
        {
            Out = new Printer(Console.Out);
        }
        public static Printer Out { get; set; }
        private readonly System.IO.TextWriter writer;
        private readonly System.Globalization.CultureInfo info;
        public string Separator { get; set; }
        public string NewLine { get { return writer.NewLine; } set { writer.NewLine = value ?? "\n"; } }
        public Printer(System.IO.TextWriter tw = null, System.Globalization.CultureInfo ci = null, string separator = null, string newLine = null)
        {
            writer = tw ?? System.IO.TextWriter.Null;
            info = ci ?? System.Globalization.CultureInfo.InvariantCulture;
            NewLine = newLine;
            Separator = separator ?? " ";
        }
        public void Print(int num) { writer.Write(num.ToString(info)); }
        public void Print(int num, string format) { writer.Write(num.ToString(format, info)); }
        public void Print(long num) { writer.Write(num.ToString(info)); }
        public void Print(long num, string format) { writer.Write(num.ToString(format, info)); }
        public void Print(double num) { writer.Write(num.ToString(info)); }
        public void Print(double num, string format) { writer.Write(num.ToString(format, info)); }
        public void Print(string str) { writer.Write(str); }
        public void Print(string format, params object[] arg) { writer.Write(string.Format(info, format, arg)); }
        public void Print<T>(string format, IEnumerable<T> sources) { writer.Write(format, sources.OfType<object>().ToArray()); }
        public void Print(IEnumerable<char> sources) { writer.Write(sources.AsString()); }
        public void Print<T>(IEnumerable<T> sources)
        {
            var res = new System.Text.StringBuilder();
            foreach (var x in sources)
            {
                res.AppendFormat(info, "{0}", x);
                if (string.IsNullOrEmpty(Separator))
                    res.Append(Separator);
            }
            writer.Write(res.ToString(0, res.Length - Separator.Length));
        }
        public void PrintLine() { writer.WriteLine(); }
        public void PrintLine(int num) { writer.WriteLine(num.ToString(info)); }
        public void PrintLine(int num, string format) { writer.WriteLine(num.ToString(format, info)); }
        public void PrintLine(long num) { writer.WriteLine(num.ToString(info)); }
        public void PrintLine(long num, string format) { writer.WriteLine(num.ToString(format, info)); }
        public void PrintLine(double num) { writer.WriteLine(num.ToString(info)); }
        public void PrintLine(double num, string format) { writer.WriteLine(num.ToString(format, info)); }
        public void PrintLine(string str) { writer.WriteLine(str); }
        public void PrintLine(string format, params object[] arg) { writer.WriteLine(string.Format(info, format, arg)); }
        public void PrintLine<T>(string format, IEnumerable<T> sources) { writer.WriteLine(format, sources.OfType<object>().ToArray()); }
        public void PrintLine<T>(IEnumerable<T> sources)
        {
            var res = new StringBuilder();
            foreach (var x in sources)
            {
                res.AppendFormat(info, "{0}", x);
                if (!string.IsNullOrEmpty(Separator))
                    res.Append(Separator);
            }
            writer.WriteLine(res.ToString(0, res.Length - Separator.Length));
        }
        public void Flush() { writer.Flush(); }
    }
    public class Scanner
    {
        readonly private System.Globalization.CultureInfo info;
        readonly System.IO.TextReader reader;
        string[] buffer = new string[0];
        int position;

        public char[] Separator { get; set; }
        public Scanner(System.IO.TextReader reader = null, string separator = null, System.Globalization.CultureInfo info = null)
        {

            this.reader = reader ?? Console.In;
            if (string.IsNullOrEmpty(separator))
                separator = " ";
            this.Separator = separator.ToCharArray();
            this.info = info ?? System.Globalization.CultureInfo.InvariantCulture;
        }
        public string Scan()
        {
            if (this.position < this.buffer.Length)
                return this.buffer[this.position++];
            do this.buffer = this.reader.ReadLine().Split(this.Separator, StringSplitOptions.RemoveEmptyEntries);
            while (this.buffer.Length == 0);
            this.position = 0;
            return this.buffer[this.position++];
        }

        public string ScanLine()
        {
            if (this.position >= this.buffer.Length)
                return this.reader.ReadLine();
            else
            {
                var sb = new System.Text.StringBuilder();
                for (; this.position < buffer.Length; this.position++)
                {
                    sb.Append(this.buffer[this.position]);
                    sb.Append(' ');
                }
                return sb.ToString();
            }
        }
        public string[] ScanArray(int length)
        {
            var ar = new string[length];
            for (int i = 0; i < length; i++)
                ar[i] = this.Scan();
            return ar;
        }

        public int Integer()
        {
            return int.Parse(this.Scan(), info);
        }
        public long Long()
        {
            return long.Parse(this.Scan(), info);
        }
        public double Double()
        {
            return double.Parse(this.Scan(), info);
        }
        public double Double(string str)
        {
            return double.Parse(str, info);
        }

        public int[] IntArray(int length)
        {
            var a = new int[length];
            for (int i = 0; i < length; i++)
                a[i] = this.Integer();
            return a;
        }
        public long[] LongArray(int length)
        {
            var a = new long[length];
            for (int i = 0; i < length; i++)
                a[i] = this.Long();
            return a;
        }
        public double[] DoubleArray(int length)
        {
            var a = new double[length];
            for (int i = 0; i < length; i++)
                a[i] = this.Double();
            return a;
        }

    }

}
#endregion
#region Extension
namespace Solver.Ex
{
    static public partial class EnumerableEx
    {
        static public string AsString(this IEnumerable<char> source)
        {
            return new string(source.ToArray());
        }
        static public string AsJoinedString<T>(this IEnumerable<T> source, string separator = " ")
        {
            return string.Join(separator, source);
        }
        static public T[] Enumerate<T>(this int n, Func<int, T> selector)
        {
            var res = new T[n];
            for (int i = 0; i < n; i++)
                res[i] = selector(i);
            return res;
        }
    }
}
#endregion
//*/


using System;
using System.Numerics;

namespace codeforces_csharp
{
    class Program
    {
        private const UInt64 P = 1000000007;

        static void Main(string[] args)
        {
            string input = Console.ReadLine();

            var input_args = input.Split(' ');

            BigInteger a = BigInteger.Parse(input_args[0].Trim());
            BigInteger b = BigInteger.Parse(input_args[1].Trim());

            BigInteger result = a*b*b*(a + 1)*(b - 1)/4 + a*b*(b - 1)/2;

            Console.WriteLine((result%P).ToString());
#if DEBUG
            Console.ReadKey();
#endif
        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

namespace Practise
{
    class Program
    {
        public static void Main()
        {
            const int MODULO = 1000000007;
            int a = 0, b = 0;

            MyReader.SplitTwoInt(out a, out b);

            long factor = (long)b * (long)(b - 1);
            factor /= 2;
            factor %= MODULO;

            long num = 0;
            for (long i = 1; i <= a; i++)
            {
                long temp = ((long)b * i) + 1;
                temp %= MODULO;

                temp *= factor;
                temp %= MODULO;

                num += temp;
                num %= MODULO;
            }

            Console.WriteLine(num);
        }
    }

    class MyReader
    {
        public static int ReadInt()
        {
            return Convert.ToInt32(Console.ReadLine());
        }

        public static long ReadLong()
        {
            return Convert.ToInt32(Console.ReadLine());
        }

        public static void SplitTwoInt(out int a, out int b)
        {
            int[] ret = ReadAndSplitInt();
            a = ret[0];
            b = ret[1];
        }

        public static void SplitThreeInt(out int a, out int b, out int c)
        {
            int[] ret = ReadAndSplitInt();
            a = ret[0];
            b = ret[1];
            c = ret[2];
        }

        public static void SplitThreeDouble(out double a, out double b, out double c)
        {
            double[] ret = ReadAndSplitDouble();
            a = ret[0];
            b = ret[1];
            c = ret[2];
        }

        public static int[] ReadAndSplitInt()
        {
            String[] input = Console.ReadLine().Split();
            int count = input.Length;
            int[] a = new int[count];
            for (int i = 0; i < count; i++)
            {
                a[i] = Convert.ToInt32(input[i]);
            }
            return a;
        }

        public static double[] ReadAndSplitDouble()
        {
            String[] input = Console.ReadLine().Split();
            int count = input.Length;
            double[] a = new double[count];
            for (int i = 0; i < count; i++)
            {
                a[i] = Convert.ToDouble(input[i]);
            }
            return a;
        }
    }

    class MyUtility
    {
        public static List<int> GetPrimes(int limit)
        {
            bool[] isPrime = GeneratePrimes(limit);
            List<int> primes = new List<int>();

            for (int i = 2; i <= limit; i++)
            {
                if (isPrime[i])
                    primes.Add(i);
            }

            return primes;
        }

        public static bool[] GeneratePrimes(int limit)
        {
            bool[] isPrime = new bool[limit + 1];
            for (int i = 2; i <= limit; i++)
                isPrime[i] = true;

            for (int i = 2; i <= limit; i++)
            {
                if (isPrime[i])
                {
                    int j = 2;
                    while (i * j <= limit)
                    {
                        isPrime[i * j] = false;
                        j++;
                    }
                }
            }

            return isPrime;
        }
    }
}


using System;
using System.IO;

class Algo
{
    const long MOD = (long)1e9 + 7;
    public void Run()
    {
        string[] tokens = cin.ReadLine().Split();
        long a = long.Parse(tokens[0]);
        long b = long.Parse(tokens[1]);
        long sum = (a * (a + 1) / 2) % MOD;
        long ans = 0;
        for (long i = 1; i < b; i++)
        {
            long first = (((b * i) % MOD) * sum) % MOD;
            long second = (i * a) % MOD;
            ans += (first + second) % MOD;
            ans %= MOD;
            //b * i * sum + i * a;
        }
        cout.WriteLine(ans);
    }

    public StreamReader cin = null;
    public StreamWriter cout = null;
}

class Program
{
    static void Main()
    {
        Algo task = new Algo();
#if DEBUG
        task.cin = new StreamReader("input.txt");
        task.cout = new StreamWriter("output.txt");
#else
        task.cin = new StreamReader(Console.OpenStandardInput());
        task.cout = new StreamWriter(Console.OpenStandardOutput());
#endif
        task.cout.AutoFlush = true;
        task.Run();
    }
}


using System;
using System.IO;
using System.Text;

namespace Dreamoon_and_Sums
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            const long mod = 1000000007;
            long a = Next();
            long b = Next();

            long sum = 0;
            for (long i = 1; i < b; i++)
            {
                long count = a;
                long b0 = (i*b + i)%mod;
                sum += (count * b0) % mod + ((((count - 1) * count / 2) % mod * i) % mod * b) % mod;
                sum = sum%mod;
            }

            writer.WriteLine(sum%mod);
            writer.Flush();
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}


using System;
using System.Collections.Generic;
using System.Globalization;
using System.IO;

namespace Practise
{
    class Program
    {
        public static void Main()
        {
            const int MODULO = 1000000007;
            int a = 0, b = 0;

            MyReader.SplitTwoInt(out a, out b);

            long factor1 = (((long)b * (long)(b - 1))) / 2;
            factor1 %= MODULO;

            long factor2 = (((long)a * (long)(a + 1))) / 2;
            factor2 %= MODULO;

            long num = (factor1 * ((factor2 * (long)b + (long)a) % MODULO)) % MODULO;
            Console.WriteLine(num);
        }
    }

    class MyReader
    {
        public static int ReadInt()
        {
            return Convert.ToInt32(Console.ReadLine());
        }

        public static long ReadLong()
        {
            return Convert.ToInt32(Console.ReadLine());
        }

        public static void SplitTwoInt(out int a, out int b)
        {
            int[] ret = ReadAndSplitInt();
            a = ret[0];
            b = ret[1];
        }

        public static void SplitThreeInt(out int a, out int b, out int c)
        {
            int[] ret = ReadAndSplitInt();
            a = ret[0];
            b = ret[1];
            c = ret[2];
        }

        public static void SplitThreeDouble(out double a, out double b, out double c)
        {
            double[] ret = ReadAndSplitDouble();
            a = ret[0];
            b = ret[1];
            c = ret[2];
        }

        public static int[] ReadAndSplitInt()
        {
            String[] input = Console.ReadLine().Split();
            int count = input.Length;
            int[] a = new int[count];
            for (int i = 0; i < count; i++)
            {
                a[i] = Convert.ToInt32(input[i]);
            }
            return a;
        }

        public static double[] ReadAndSplitDouble()
        {
            String[] input = Console.ReadLine().Split();
            int count = input.Length;
            double[] a = new double[count];
            for (int i = 0; i < count; i++)
            {
                a[i] = Convert.ToDouble(input[i]);
            }
            return a;
        }
    }

    class MyUtility
    {
        public static List<int> GetPrimes(int limit)
        {
            bool[] isPrime = GeneratePrimes(limit);
            List<int> primes = new List<int>();

            for (int i = 2; i <= limit; i++)
            {
                if (isPrime[i])
                    primes.Add(i);
            }

            return primes;
        }

        public static bool[] GeneratePrimes(int limit)
        {
            bool[] isPrime = new bool[limit + 1];
            for (int i = 2; i <= limit; i++)
                isPrime[i] = true;

            for (int i = 2; i <= limit; i++)
            {
                if (isPrime[i])
                {
                    int j = 2;
                    while (i * j <= limit)
                    {
                        isPrime[i * j] = false;
                        j++;
                    }
                }
            }

            return isPrime;
        }
    }
}


using System;
using System.IO;

namespace CF272
{
    class Program
    {
        static void Main(string[] args)
        {
            Solution(Console.In, Console.Out);
        }

        static void Solution(TextReader sr, TextWriter sw)
        {
            string[] input = sr.ReadLine().Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
            int a = Int32.Parse(input[0]);
            int b = Int32.Parse(input[1]);
            if (b == 1)
            {
                Console.WriteLine(0);
                return;
            }
            long sum = 0L;
            for (long i = 1; i <= a; i++)
            {
                sum += (i*b + 1)*(b*(b - 1)/2)%10000000007;
            }
            Console.WriteLine(sum);
        }
    }
}


using System;
using System.IO;

namespace CF272
{
    class Program
    {
        static void Main(string[] args)
        {
            Solution(Console.In, Console.Out);
        }

        static void Solution(TextReader sr, TextWriter sw)
        {
            const long module = 1000000007L;
            string[] input = sr.ReadLine().Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
            long a = Int64.Parse(input[0]);
            long b = Int64.Parse(input[1]);
            if (b == 1)
            {
                Console.WriteLine(0);
                return;
            }
            long sum = 0L;
            for (long i = 1; i <= a; i++)
            {
                sum += ((i*b + 1)*(b*(b - 1)/2));
            }
            Console.WriteLine(sum%module);
        }
    }
}


using System;
using System.IO;

namespace CF272
{
    class Program
    {
        static void Main(string[] args)
        {
            Solution(Console.In, Console.Out);
        }

        static void Solution(TextReader sr, TextWriter sw)
        {
            const long module = 1000000007L;
            string[] input = sr.ReadLine().Split(new[] {' '}, StringSplitOptions.RemoveEmptyEntries);
            long a = Int64.Parse(input[0]);
            long b = Int64.Parse(input[1]);
            if (b == 1)
            {
                Console.WriteLine(0);
                return;
            }
            long sum = 0L;
            for (long i = 1; i <= a; i++)
            {
                sum += (((i*b) + 1)*((b*(b - 1))/2))%module;
            }
            Console.WriteLine(sum);
        }
    }
}


using System;
using System.IO;
using System.Text;

namespace Dreamoon_and_Sums
{
    internal class Program
    {
        private static readonly StreamReader reader = new StreamReader(Console.OpenStandardInput(1024*10), Encoding.ASCII, false, 1024*10);
        private static readonly StreamWriter writer = new StreamWriter(Console.OpenStandardOutput(1024*10), Encoding.ASCII, 1024*10);

        private static void Main(string[] args)
        {
            const long mod = 1000000007;
            long a = Next();
            long b = Next();

            long sum = 0;
            for (long i = 1; i < b; i++)
            {
                long count = a;
                long b0 = (i*b + i)%mod;
                sum += (count*b0)%mod + ((count - 1)*count/2*b)%mod;
                sum = sum%mod;
            }

            writer.WriteLine(sum%mod);
            writer.Flush();
        }

        private static int Next()
        {
            int c;
            int res = 0;
            do
            {
                c = reader.Read();
                if (c == -1)
                    return res;
            } while (c < '0' || c > '9');
            res = c - '0';
            while (true)
            {
                c = reader.Read();
                if (c < '0' || c > '9')
                    return res;
                res *= 10;
                res += c - '0';
            }
        }
    }
}