Problem: Yaroslav calls an array of r integers a1, a2, ..., ar good, if it meets the following conditions: |a1 - a2| = 1, |a2 - a3| = 1, ..., |ar - 1 - ar| = 1, |ar - a1| = 1, at that <image>. 

An array of integers b1, b2, ..., br is called great, if it meets the following conditions:

  1. The elements in it do not decrease (bi ≤ bi + 1). 
  2. If the inequalities 1 ≤ r ≤ n and 1 ≤ bi ≤ m hold. 
  3. If we can rearrange its elements and get at least one and at most k distinct good arrays. 



Yaroslav has three integers n, m, k. He needs to count the number of distinct great arrays. Help Yaroslav! As the answer may be rather large, print the remainder after dividing it by 1000000007 (109 + 7).

Two arrays are considered distinct if there is a position in which they have distinct numbers.

Input

The single line contains three integers n, m, k (1 ≤ n, m, k ≤ 100).

Output

In a single line print the remainder after dividing the answer to the problem by number 1000000007 (109 + 7).

Examples

Input

1 1 1


Output

0


Input

3 3 3


Output

2

Solution (in JAVA):

Solution:
import java.io.*;

import java.awt.geom.Point2D;
import java.text.*;
import java.math.*;
import java.util.*;

public class Main implements Runnable {

	final String filename = "";

	final int MOD = 1000000007;

	public void solve() throws Exception {
		int MAX = 101;
		int INF = 1000;
		int[][] C = new int[MAX + 1][MAX + 1];
		for (int i = 0; i <= MAX; i++) {
			C[i][0] = C[i][i] = 1;
			for (int j = 1; j < i; j++)
				C[i][j] = Math.min(C[i - 1][j - 1] + C[i - 1][j], INF);
		}

		int N = iread(), M = iread(), K = iread();
		if (M == 1 || N == 1) {
			out.write("0\n");
			return;
		}
		long ans = 0;
		N /= 2;
		int[][][][] d = new int[2][N][N + 1][K + 1];
		for (int a = 1; a <= N; a++) {
			d[0][N - a][a][1] = 1;
		}
		int step = 0;
		for (int m = 1; m < M; m++) {
			for (int i = 0; i < N; i++)
				for (int j = 0; j <= N; j++)
					Arrays.fill(d[step ^ 1][i][j], 0);
			for (int n = 0; n < N; n++) {
				for (int prev = 1; prev <= N; prev++) {
					for (int k = 1; k <= K; k++) {
						int t = d[step][n][prev][k];
						if (t == 0)
							continue;
						// System.out.println("m=" + m + " n=" + n + " prev="
						// + prev + " k=" + k+" ans+="+(t*k*(M-m)));
						ans = (ans + t * (M - m)) % MOD;
						for (int next = 1; next <= n; next++) {
							int v = k * C[next + prev - 1][prev - 1];
							if (v > K)
								continue;
							int r = d[step ^ 1][n - next][next][v] + t;
							if (r >= MOD)
								r -= MOD;
							d[step ^ 1][n - next][next][v] = r;
						}
					}
				}
			}
			step ^= 1;
		}
		out.write(ans + "\n");
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new BufferedWriter(new OutputStreamWriter(System.out));
			// in = new BufferedReader(new FileReader(filename+".in"));
			// out = new BufferedWriter(new FileWriter(filename+".out"));
			solve();
			out.flush();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	public int iread() throws Exception {
		return Integer.parseInt(readword());
	}

	public double dread() throws Exception {
		return Double.parseDouble(readword());
	}

	public long lread() throws Exception {
		return Long.parseLong(readword());
	}

	BufferedReader in;

	BufferedWriter out;

	public String readword() throws IOException {
		StringBuilder b = new StringBuilder();
		int c;
		c = in.read();
		while (c >= 0 && c <= ' ')
			c = in.read();
		if (c < 0)
			return "";
		while (c > ' ') {
			b.append((char) c);
			c = in.read();
		}
		return b.toString();
	}

	public static void main(String[] args) {
		try {
			Locale.setDefault(Locale.US);
		} catch (Exception e) {

		}
		// new Thread(new Main()).start();
		new Thread(null, new Main(), "1", 1 << 25).start();
	}
}