import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.math.BigInteger;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    private static final long MODULO = (long) 1e9 + 7;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long n = in.nextLong();
        int k = in.nextInt();
        long[][][] a = new long[k][k + 1][k + 1];
        for (int i = 0; i < k; ++i) {
            long[][] mat = a[i];
            for (int j = 0; j < k; ++j) if (j != i) mat[j][j] = 1;
            mat[i][k] = 1;
            mat[k][k] = 2;
            mat[k][i] = MODULO - 1;
        }
        int sum = 0;
        for (long m = n; m > 0; m /= k) sum += m % k;
        long[][] mul = new long[k + 1][k + 1];
        for (int i = 0; i < mul.length; ++i) mul[i][i] = 1;
        while (n > 0) {
            sum -= n % k;
            for (int i = (int) (n % k - 1); i >= 0; --i) mul = multiply(mul, a[(sum + i) % k]);
            long[][][] prefix = new long[k][][];
            for (int i = 0; i < k; ++i) {
                if (i == 0) prefix[i] = a[i];
                else prefix[i] = multiply(a[i], prefix[i - 1]);
            }
            long[][][] suffix = new long[k][][];
            for (int i = k - 1; i >= 0; --i) {
                if (i == k - 1) suffix[i] = a[i];
                else suffix[i] = multiply(suffix[i + 1], a[i]);
            }
            for (int i = 0; i < k; ++i) {
                if (i == 0) a[i] = suffix[i];
                else a[i] = multiply(prefix[i - 1], suffix[i]);
            }
            n /= k;
        }
        long[][] res = new long[k + 1][1];
        res[k][0] = 1;
        res = multiply(mul, res);
        out.println(res[k][0]);
    }

    long[][] multiply(long[][] a, long[][] b) {
        int m = a.length;
        int n = a[0].length;
        int p = b[0].length;
        long[][] c = new long[m][p];
        for (int i = 0; i < m; ++i)
            for (int j = 0; j < n; ++j)
                for (int k = 0; k < p; ++k)
                    c[i][k] = (c[i][k] + a[i][j] * b[j][k]) % MODULO;
        return c;
    }
}

class InputReader {
    private final BufferedReader bufferedReader;
    private StringTokenizer stringTokenizer;

    public InputReader(InputStream inputStream) {
        this.bufferedReader = new BufferedReader(new InputStreamReader(inputStream));
        this.stringTokenizer = null;
    }

    public String next() {
        while (stringTokenizer == null || !stringTokenizer.hasMoreTokens()) {
            try {
                stringTokenizer = new StringTokenizer(bufferedReader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return stringTokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    static final long MODULO = (long) (1e9 + 7);
    static final long BIG = Long.MAX_VALUE - Long.MAX_VALUE % MODULO;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long n = in.nextLong();
        int k = in.nextInt();
        long pk = 1;
        int pow = 0;
        while (pk <= n / k) {
            pk *= k;
            ++pow;
        }
        matrCache = new long[pow + 1][][];
        long at = 0;
        long[] ways = new long[k + 1];
        ways[k] = 1;
        while (at < n) {
            while (at + pk <= n) {
                long[][] matr = getMatr(digitSum(at, k) % k, k, pow);
                ways = mul(matr, ways);
                at += pk;
            }
            pk /= k;
            --pow;
        }
        long res = 0;
        for (long x : ways) res += x;
        res %= MODULO;
        out.println(res);
    }

    long[][][] matrCache;

    private long[][] getMatr(int pre, int k, int pow) {
        long[][] res = matrCache[pow];
        if (res == null) {
            if (pow == 0) {
                res = new long[k + 1][k + 1];
                for (int i = 0; i < k + 1; ++i) ++res[i][i];
                for (int i = 0; i < k + 1; ++i) {
                    ++res[0][i];
                }
                --res[0][0];
            } else {
                res = new long[k + 1][k + 1];
                for (int i = 0; i < k + 1; ++i) ++res[i][i];
                for (int i = 0; i < k; ++i) {
                    res = mul(getMatr(i, k, pow - 1), res);
                }
            }
            matrCache[pow] = res;
        }
        long[][] rotated = new long[k + 1][k + 1];
        for (int i = 0; i <= k; ++i)
            for (int j = 0; j <= k; ++j) {
                int ii = (i == k) ? k : (pre + i) % k;
                int jj = (j == k) ? k : (pre + j) % k;
                rotated[ii][jj] = res[i][j];
            }
        return rotated;
    }

    private long[] mul(long[][] a, long[] b) {
        long[] c = new long[b.length];
        for (int i = 0; i < c.length; ++i) {
            long s = 0;
            for (int j = 0; j < c.length; ++j) {
                s += a[i][j] * b[j];
                if (s < 0) s -= BIG;
            }
            c[i] = s % MODULO;
        }
        return c;
    }

    private long[][] mul(long[][] a, long[][] b) {
        long[][] c = new long[b.length][b.length];
        for (int i = 0; i < c.length; ++i) {
            for (int k = 0; k < c.length; ++k) {
                long s = 0;
                for (int j = 0; j < c.length; ++j) {
                    s += a[i][j] * b[j][k];
                    if (s < 0) s -= BIG;
                }
                c[i][k] = s % MODULO;
            }
        }
        return c;
    }

    private int digitSum(long at, int k) {
        int res = 0;
        while (at > 0) {
            res += at % k;
            at /= k;
        }
        return res;
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}

//package round283;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	// 012 120 201
	// 1 1 2 4 6 10 23 33 56
	void solve()
	{
		long n = nl();
		int K = ni();

		if(n <= K){
			int u = 1;
			for(int i = 0;i < n;i++){
				u = u * 2 % mod;
			}
			out.println(u);
			return;
		}

		int t = (int)(Math.log(10)*18/Math.log(K) + 1);
		int[][][] B = new int[2*K][2*K+1][2*K+1];

		int mod = 1000000007;
		for(int i = 0;i < 2*K;i++){
			for(int j = 1;j < 2*K+1;j++){
				B[i][j][j-1] = 1;
			}
			B[i][0][0] = 2;
			B[i][0][i] += mod-1;
		}
		int[][][] C = new int[K][][];
		for(int i = 0;i < K;i++){
			if(i == 0){
				C[i] = pow(B[K-i], K-i);
			}else{
				C[i] = mul(pow(B[2*K-i], i), pow(B[K-i], K-i));
			}
		}

		int[][][] M = new int[t+1][][];
		int[][][] MK = new int[t+1][][];
		int[][][] MKT = new int[t+1][][];
		M[1] = C[1];
		MK[1] = pow(C[1], K-1);
		MKT[1] = MK[1];
		for(int z = 2;z < t;z++){
			M[z] = mul(MKT[z-1], C[z%K]);
//			M[z] = C[z%K];
//			for(int y = 1;y < z;y++){
//				M[z] = mul(MK[y], M[z]);
//			}
			MK[z] = pow(M[z], K-1);
			MKT[z] = mul(MK[z], MKT[z-1]);
		}
		int[][][] rem = new int[t+1][][];
		rem[1] = MK[1];
		for(int z = 2;z < t;z++){
			rem[z] = mul(MK[z], rem[z-1]);
		}

		long[] d = new long[64];
		int p = 0;
		while(n > 0){
			d[p++] = n % K;
			n /= K;
		}

		int[] v = new int[2*K+1];
		v[K] = 1;
		for(int i = K-1;i >= 0;i--){
			v[i] = v[i+1] * 2 % mod;
		}

		int prev = -1;
		for(int u = p-1;u >= 2;u--){
			long e = d[u];
			for(int i = 0;i < e;i++){
				if(prev != -1)v = mul(C[prev], v);
				v = mul(rem[u-1], v);
				prev = u%K;
			}
		}
		{
			int u = 1;
			long e = d[u];
			if(e > 0){
				if(prev != -1)v = mul(C[prev], v);
				for(int i = 1;i < e;i++){
					v = mul(C[1], v);
					prev = u%K;
				}
				prev = 1;
			}
		}
		if(prev == -1)prev = 1;
		for(int j = 0;j < K-prev && d[0] > 0;j++, d[0]--){
			v = mul(B[K-prev], v);
		}
		for(int j = 0;j < prev && d[0] > 0;j++, d[0]--){
			v = mul(B[2*K-prev], v);
		}
		out.println(v[0]);
	}

	public static int[][] mul(int[][] A, int[][] B)
	{
		int m = A.length;
		int n = A[0].length;
		int o = B[0].length;
		int[][] C = new int[m][o];
		for(int i = 0;i < m;i++){
			long[] sum = new long[n];
			for(int k = 0;k < n;k++){
				for(int j = 0;j < n;j++){
					sum[j] += (long)A[i][k] * B[k][j];
					if(sum[j] >= BIG)sum[j] -= BIG;
				}
			}
			for(int j = 0;j < n;j++){
				C[i][j] = (int)(sum[j] % mod);
			}
		}
		return C;
	}

	///////// begin
	public static final int mod = 1000000007;
	public static final long m2 = (long)mod*mod;
	public static final long BIG = 8L*m2;

	// A^e*v
	public static int[] pow(int[][] A, int[] v, long e)
	{
		for(int i = 0;i < v.length;i++){
			if(v[i] >= mod)v[i] %= mod;
		}
		int[][] MUL = A;
		for(;e > 0;e>>>=1) {
			if((e&1)==1)v = mul(MUL, v);
			MUL = p2(MUL);
		}
		return v;
	}

	// int matrix*int vector
	public static int[] mul(int[][] A, int[] v)
	{
		int m = A.length;
		int n = v.length;
		int[] w = new int[m];
		for(int i = 0;i < m;i++){
			long sum = 0;
			for(int k = 0;k < n;k++){
				sum += (long)A[i][k] * v[k];
				if(sum >= BIG)sum -= BIG;
			}
			w[i] = (int)(sum % mod);
		}
		return w;
	}

	// int matrix^2 (be careful about minus value)
	public static int[][] p2(int[][] A)
	{
		int n = A.length;
		int[][] C = new int[n][n];
		for(int i = 0;i < n;i++){
			long[] sum = new long[n];
			for(int k = 0;k < n;k++){
				for(int j = 0;j < n;j++){
					sum[j] += (long)A[i][k] * A[k][j];
					if(sum[j] >= BIG)sum[j] -= BIG;
				}
			}
			for(int j = 0;j < n;j++){
				C[i][j] = (int)(sum[j] % mod);
			}
		}
		return C;
	}

	//////////// end

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;

	}

	public static int[][] pow(int[][] A, long e)
	{
		int[][] MUL = A;
		int n = A.length;
		int[][] C = new int[n][n];
		for(int i = 0;i < n;i++)C[i][i] = 1;
		for(;e > 0;e>>>=1) {
			if((e&1)==1)C = mul(C, MUL);
			MUL = p2(MUL);
		}
		return C;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

//package round283;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;
import java.util.InputMismatchException;

public class E {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	// 012 120 201
	// 1 1 2 4 6 10 23 33 56
	void solve()
	{
		long n = nl();
		int K = ni();

		if(n <= K){
			int u = 1;
			for(int i = 0;i < n;i++){
				u = u * 2 % mod;
			}
			out.println(u);
			return;
		}

		int t = (int)(Math.log(10)*18/Math.log(K) + 1);
		int[][][] B = new int[2*K][2*K][2*K];

		int mod = 1000000007;
		for(int i = 0;i < 2*K;i++){
			for(int j = 1;j < 2*K;j++){
				B[i][j][j-1] = 1;
			}
			B[i][0][0] = 2;
			B[i][0][i] += mod-1;
		}
		int[][][] C = new int[K][][];
		for(int i = 0;i < K;i++){
			if(i == 0){
				C[i] = pow(B[K-i], K-i);
			}else{
				C[i] = mul(pow(B[2*K-i], i), pow(B[K-i], K-i));
			}
		}

		int[][][] M = new int[t+1][][];
		int[][][] MK = new int[t+1][][];
		int[][][] MKT = new int[t+1][][];
		M[1] = C[1];
		MK[1] = pow(C[1], K-1);
		MKT[1] = MK[1];
		for(int z = 2;z < t;z++){
			M[z] = mul(MKT[z-1], C[z%K]);
//			M[z] = C[z%K];
//			for(int y = 1;y < z;y++){
//				M[z] = mul(MK[y], M[z]);
//			}
			MK[z] = pow(M[z], K-1);
			MKT[z] = mul(MK[z], MKT[z-1]);
		}
		int[][][] rem = new int[t+1][][];
		rem[1] = MK[1];
		for(int z = 2;z < t;z++){
			rem[z] = mul(MK[z], rem[z-1]);
		}

		long[] d = new long[64];
		int p = 0;
		while(n > 0){
			d[p++] = n % K;
			n /= K;
		}

		int[] v = new int[2*K];
		v[K] = 1;
		for(int i = K-1;i >= 0;i--){
			v[i] = v[i+1] * 2 % mod;
		}

		int prev = -1;
		for(int u = p-1;u >= 2;u--){
			long e = d[u];
			for(int i = 0;i < e;i++){
				if(prev != -1)v = mul(C[prev], v);
				v = mul(rem[u-1], v);
				prev = u%K;
			}
		}
		{
			int u = 1;
			long e = d[u];
			if(e > 0){
				if(prev != -1)v = mul(C[prev], v);
				for(int i = 1;i < e;i++){
					v = mul(C[1], v);
					prev = u%K;
				}
				prev = 1;
			}
		}
		if(prev == -1)prev = 1;
		for(int j = 0;j < K-prev && d[0] > 0;j++, d[0]--){
			v = mul(B[K-prev], v);
		}
		for(int j = 0;j < prev && d[0] > 0;j++, d[0]--){
			v = mul(B[2*K-prev], v);
		}
		out.println(v[0]);
	}

	public static int[][] mul(int[][] A, int[][] B)
	{
		int m = A.length;
		int n = A[0].length;
		int o = B[0].length;
		int[][] C = new int[m][o];
		for(int i = 0;i < m;i++){
			long[] sum = new long[n];
			for(int k = 0;k < n;k++){
				for(int j = 0;j < n;j++){
					sum[j] += (long)A[i][k] * B[k][j];
					if(sum[j] >= BIG)sum[j] -= BIG;
				}
			}
			for(int j = 0;j < n;j++){
				C[i][j] = (int)(sum[j] % mod);
			}
		}
		return C;
	}

	///////// begin
	public static final int mod = 1000000007;
	public static final long m2 = (long)mod*mod;
	public static final long BIG = 8L*m2;

	// A^e*v
	public static int[] pow(int[][] A, int[] v, long e)
	{
		for(int i = 0;i < v.length;i++){
			if(v[i] >= mod)v[i] %= mod;
		}
		int[][] MUL = A;
		for(;e > 0;e>>>=1) {
			if((e&1)==1)v = mul(MUL, v);
			MUL = p2(MUL);
		}
		return v;
	}

	// int matrix*int vector
	public static int[] mul(int[][] A, int[] v)
	{
		int m = A.length;
		int n = v.length;
		int[] w = new int[m];
		for(int i = 0;i < m;i++){
			long sum = 0;
			for(int k = 0;k < n;k++){
				sum += (long)A[i][k] * v[k];
				if(sum >= BIG)sum -= BIG;
			}
			w[i] = (int)(sum % mod);
		}
		return w;
	}

	// int matrix^2 (be careful about minus value)
	public static int[][] p2(int[][] A)
	{
		int n = A.length;
		int[][] C = new int[n][n];
		for(int i = 0;i < n;i++){
			long[] sum = new long[n];
			for(int k = 0;k < n;k++){
				for(int j = 0;j < n;j++){
					sum[j] += (long)A[i][k] * A[k][j];
					if(sum[j] >= BIG)sum[j] -= BIG;
				}
			}
			for(int j = 0;j < n;j++){
				C[i][j] = (int)(sum[j] % mod);
			}
		}
		return C;
	}

	//////////// end

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception { new E().run(); }

	private byte[] inbuf = new byte[1024];
	private int lenbuf = 0, ptrbuf = 0;

	private int readByte()
	{
		if(lenbuf == -1)throw new InputMismatchException();
		if(ptrbuf >= lenbuf){
			ptrbuf = 0;
			try { lenbuf = is.read(inbuf); } catch (IOException e) { throw new InputMismatchException(); }
			if(lenbuf <= 0)return -1;
		}
		return inbuf[ptrbuf++];
	}

	private boolean isSpaceChar(int c) { return !(c >= 33 && c <= 126); }
	private int skip() { int b; while((b = readByte()) != -1 && isSpaceChar(b)); return b; }

	private double nd() { return Double.parseDouble(ns()); }
	private char nc() { return (char)skip(); }

	private String ns()
	{
		int b = skip();
		StringBuilder sb = new StringBuilder();
		while(!(isSpaceChar(b))){ // when nextLine, (isSpaceChar(b) && b != ' ')
			sb.appendCodePoint(b);
			b = readByte();
		}
		return sb.toString();
	}

	private char[] ns(int n)
	{
		char[] buf = new char[n];
		int b = skip(), p = 0;
		while(p < n && !(isSpaceChar(b))){
			buf[p++] = (char)b;
			b = readByte();
		}
		return n == p ? buf : Arrays.copyOf(buf, p);
	}

	private char[][] nm(int n, int m)
	{
		char[][] map = new char[n][];
		for(int i = 0;i < n;i++)map[i] = ns(m);
		return map;
	}

	private int[] na(int n)
	{
		int[] a = new int[n];
		for(int i = 0;i < n;i++)a[i] = ni();
		return a;

	}

	public static int[][] pow(int[][] A, long e)
	{
		int[][] MUL = A;
		int n = A.length;
		int[][] C = new int[n][n];
		for(int i = 0;i < n;i++)C[i][i] = 1;
		for(;e > 0;e>>>=1) {
			if((e&1)==1)C = mul(C, MUL);
			MUL = p2(MUL);
		}
		return C;
	}

	private int ni()
	{
		int num = 0, b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private long nl()
	{
		long num = 0;
		int b;
		boolean minus = false;
		while((b = readByte()) != -1 && !((b >= '0' && b <= '9') || b == '-'));
		if(b == '-'){
			minus = true;
			b = readByte();
		}

		while(true){
			if(b >= '0' && b <= '9'){
				num = num * 10 + (b - '0');
			}else{
				return minus ? -num : num;
			}
			b = readByte();
		}
	}

	private boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	private void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.io.*;
import java.util.*;

public class EMain {
    String noResultMessage = "NoResult";
    Parser in = new Parser();
    PrintWriter out;

    long n = in.nextLong();
    int k = in.nextInteger();

    Matrix[] upRow(Matrix[] row){
        Matrix[] suffix = new Matrix[k];
        suffix[0] = Matrix.oneMatrix(k+1);
        for(int i = 1; i < k; ++i){
            suffix[i] = Matrix.mul(suffix[i-1], row[i-1]);
        }
        Matrix[] prefix = new Matrix[k];
        prefix[k-1] = row[k-1];
        for(int i = k-2; i>=0; --i){
            prefix[i] = Matrix.mul(row[i], prefix[i+1]);
        }
        Matrix[] result = new Matrix[k];
        for(int i = 0; i < k; ++i){
            result[i] = Matrix.mul(prefix[i], suffix[i]);
        }
        return result;
    }

    public void solve() {

        Matrix[][] matrixes = new Matrix[100][k];

        for(int i = 0; i < k; ++i){
            Matrix m = Matrix.oneMatrix(k + 1);
            matrixes[0][i] = m;
            for(int j = 0; j <= k; ++j){
                m.set(j, i, 1);
            }
        }
        int[] digits = new int[100];
        int index = 0;
        long limit = n;
        digits[index++] = (int) (limit % k);
        for(int row = 1; row < 100; ++row){
            limit /= k;
            if(limit == 0)break;
            digits[index++] = (int) (limit % k);
            matrixes[row] = upRow(matrixes[row-1]);
        }

        Matrix result = Matrix.oneMatrix(k+1);
        int pos = 0;
        while(index-- > 0){
            while(digits[index]-- > 0){
                result = Matrix.mul(result, matrixes[index][pos++]);
                pos %= k;
            }
        }
        Vector vec = new Vector(k+1);
        vec.set(k, 1);
        out.println(Vector.mul(vec, result).sum());

    }

    static int MOD = (int) (1e9+7);

    static public class Matrix {
        int[][] data;

        public Matrix(int size) {
            this.data = new int[size][size];
        }

        Matrix(Matrix other) {
            int size = other.data.length;
            this.data = new int[size][];
            for(int i = 0; i < size; ++i){
                this.data[i] = Arrays.copyOf(other.data[i], size);
            }
        }
        public void set(int row, int column, int value){
            data[row][column] = value;
        }

        public static Matrix oneMatrix(int size){
            Matrix result = new Matrix(size);
            for(int i = 0; i < size; ++i){
                result.data[i][i] = 1;
            }
            return result;
        }

        public static Matrix mul(Matrix left, Matrix right){
            int size = left.data.length;
            assert size == right.data.length;
            Matrix result = new Matrix(size);
            for(int i = 0; i < size; ++i){
                for(int j = 0; j < size; ++j){
                    int val = 0;
                    for(int k = 0; k < size; ++k){
                        val += 1l * left.data[i][k] * right.data[k][j] % MOD;
                        val %= MOD;
                        val += MOD;
                        val %= MOD;
                    }
                    result.data[i][j] = val;
                }
            }
            return result;
        }

        static Matrix degree(Matrix matrix, long degree){
            Matrix result = Matrix.oneMatrix(matrix.data.length);
            while(degree > 0){
                if((degree & 1) == 1){
                    result = Matrix.mul(result, matrix);
                }
                result = Matrix.mul(result, result);
                degree >>= 1;
            }
            return result;
        }
    }

    static public class Vector{
        int[] data;

        public Vector(int size) {
            this.data = new int[size];
        }

        Vector(Vector other) {
            this.data = Arrays.copyOf(other.data, other.data.length);
        }

        public void set(int pos, int val){
            data[pos] = val;
        }

        int get(int pos){
            return data[pos];
        }

        public int sum(){
            long sum = 0;
            for(int i : data){
                sum += i;
            }
            sum %= MOD;
            sum += MOD;
            sum %= MOD;
            return (int) sum;
        }

        public static Vector mul(Vector vec, Matrix matrix){
            int size = vec.data.length;
            assert size == matrix.data.length;
            Vector result = new Vector(size);
            for(int i = 0; i < size; ++i){
                int val = 0;
                for(int j = 0; j < size; ++j){
                    val += 1l * vec.data[j] * matrix.data[j][i] % MOD;
                    val += MOD;
                    val %= MOD;
                }
                result.data[i] = val;
            }
            return result;
        }
    }

    static public class Parser{
        Scanner scanner;

        public Parser() {
            scanner = new Scanner(System.in).useLocale(Locale.ENGLISH);
        }

        public Parser(String str) {
            scanner = new Scanner(str).useLocale(Locale.ENGLISH);
        }

        long nextLong(){
            return scanner.nextLong();
        }

        int nextInteger(){
            return scanner.nextInt();
        }

        double nextDouble(){
            return scanner.nextDouble();
        }

        String nextLine(){
            return scanner.nextLine();
        }

        String next(){
            return scanner.next();
        }

        int[] nextIntegers(int count){
            int[] result = new int[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextInteger();
            }
            return result;
        }

        long[] nextLongs(int count){
            long[] result = new long[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextLong();
            }
            return result;
        }

        int[][] nextIntegers(int fields, int count){
            int[][] result = new int[fields][count];
            for(int c = 0; c < count; ++c){
                for(int i = 0; i < fields; ++i){
                    result[i][c] = nextInteger();
                }
            }
            return result;
        }
    }

    void noResult(){
        throw new NoResultException();
    }

    void noResult(String str){
        throw new NoResultException(str);
    }

    void run(){
        try{
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            out = new PrintWriter(outStream);
            solve();
            out.close();
            System.out.print(outStream.toString());
        } catch (NoResultException exc){
            System.out.print(null == exc.response ? noResultMessage : exc.response);
        }
    }

    public static void main(String[] args) {
        new EMain().run();
    }

    public static class NoResultException extends RuntimeException{
        private String response;

        public NoResultException(String response) {
            this.response = response;
        }

        public NoResultException() {
        }
    }
}

import java.util.*;
import static java.lang.Math.*;

public class E {
    static void p(Object ...args) {System.out.println(Arrays.deepToString(args));}
    static long MOD = 1_000_000_007;

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long N = in.nextLong();
        int K = in.nextInt();

        int need = 4;
        long temp2 = N + 100000;
        while (temp2 > 0) {
            need++;
            temp2 /= K;
        }

        long[][][] moveBy = new long[need][][];
        long[][] prefix = identity(K+1);
        for (int i = 1; i < need - 1; i++) {
            moveBy[i] = multiply(prefix, makeMatrix(K, i+1));
            prefix = multiply(pow(moveBy[i], K-1), prefix);
        }

        long at = 0;
        long[][] f = identity(K+1);
        long temp = N / K;
        for (int i = 1; temp > 0; i++) {
            f = multiply(pow(moveBy[i], (int)(temp % K)), f);
            temp /= K;
        }
        long[] start = new long[K+1];
        for (int i = 0; i < start.length; i++)
            start[i] = (1L<<(i)) % MOD;
        start[K] = 1;

        int position = (int)(N % K);
        long ans = 0;
        for (int i = 0; i < start.length; i++)
            ans += (start[i] * f[i][position]) % MOD;
        ans %= MOD;

        System.out.println(ans);
    }
    static long[][] identity(int A) {
        long[][] ans = new long[A][A];
        for (int i = 0; i < A; i++)
            ans[i][i] = 1;
        return ans;
    }
    static long[][] pow(long[][] M, int p) {
        long[][] ans = new long[M.length][M.length];
        for (int i = 0; i < ans.length ;i++)
            ans[i][i] = 1;
        long[][] go = new long[M.length][M.length];
        for (int i = 0; i < go.length ;i++)
            for (int j = 0; j < go.length ;j++)
                go[i][j] = M[i][j];
        while (p > 0) {
            if (p % 2 == 1) {
                ans = multiply(ans, go);
            }
            p /= 2;
            go = multiply(go, go);
        }
        return ans;
    }
    static long[][] makeMatrix(int K, int a) {
        long[][] res = new long[K+1][K+1];

        int[] v = new int[2*K];
        v[2*K-1] = 0;
        for (int i = 2*K-2; i >= 0; i--) {
            if (i == K-1) {
                v[i] = (K + (K-a + v[i+1]) % K) % K;
            } else {
                v[i] = (K + (K-1 + v[i+1]) % K) % K;
            }
        }
        for (int i = 0; i <= K; i++)
            res[K][i]++;
        for (int c = 0; c < K; c++) {
            for (int i = 0; i < K; i++) {
                boolean found = false;
                for (int j = c - 1 + K; j >= 0; j--) {
                    if (v[j] == i) {
                        found = true;
                        if (j < K) {
                            res[j][c] += 1;
                        } else {
                            for (int b = 0; b <= K; b++)
                                res[b][c] += res[b][j-K];
                        }
                        break;
                    }
                }
                if (!found) {
                    p(c, i, v);
                    throw new RuntimeException();
                }
            }
        }
        return res;
    }
    static long[][] multiply(long[][] A, long[][] B) {
        long[][] res = new long[A.length][A.length];
        for (int r = 0; r < A.length; r++)
            for (int c = 0; c < A.length; c++) {
                for (int i = 0; i < A.length; i++)
                    res[r][c] += (A[r][i] * B[i][c]) % MOD;
                res[r][c] %= MOD;
            }
        return res;
    }
 }

import java.util.*;
import static java.lang.Math.*;

public class E {
    static void p(Object ...args) {System.out.println(Arrays.deepToString(args));}
    static long MOD = 1_000_000_007;

    /*static int score(int a, int k) {
        int ans = 0;
        while( a > 0) {
            ans += a % k;
            a /= k;
        }
        return ans % k;
    }

    public static long slow(int N, int K) {
        long[] V = new long[N+1];
        for (int i = 0; i <= N; i++)
            V[i] = score(i, K);
        long[] dp = new long[N+1];
        for (int i = 0; i <= N; i++) {
            for (int j = 0; j < K; j++) {
                for (int a = i - 1; a >= 0; a--) {
                    if (V[a] == j) {
                        dp[i] += dp[a];
                        break;
                    }
                }
            }
            dp[i] += 1;
            dp[i] %= MOD;
        }
        return dp[N];
    }*/
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long N = in.nextLong();
        int K = in.nextInt();

        int need = 4;
        long temp2 = N + 100000;
        while (temp2 > 0) {
            need++;
            temp2 /= K;
        }

        long[][][] M = new long[need][][];
        for (int i = 2; i < M.length; i++)
            M[i] = makeMatrix(K, i);

        /*p("M[2]");
        for (int i = 0; i < M[2].length; i++)
            p(M[2][i]);
        p("M[3]");
        for (int i = 0; i < M[3].length; i++)
            p(M[3][i]);*/

        long[][][] moveBy = new long[need][][];
        long[][][] moveByK = new long[need][][];
        for (int i = 1; i < moveBy.length - 1; i++) {
            long[][] ans = new long[K+1][K+1];
            for (int j = 0; j < ans.length; j++)
                ans[j][j] = 1;
            for (int j = i - 1; j >= 1; j--)
                ans = multiply(ans, moveByK[j]);

            ans = multiply(ans, M[i+1]);
            moveBy[i] = ans;
            moveByK[i] = new long[K+1][K+1];
            for (int j = 0; j <= K; j++)
                moveByK[i][j][j] = 1;
            moveByK[i] = pow(moveBy[i], K-1);
            /*for (int j = 0; j < K-1; j++)
                moveByK[i] = multiply(moveByK[i], moveBy[i]);*/
        }
        /*p("moveBy[2]");
        for (int i = 0; i <= K; i++)
            p(moveBy[2][i]);*/

        long at = 0;
        long[][] f = new long[K+1][K+1];
        for (int i = 0; i < f.length; i++)
            f[i][i] = 1;
        //f = multiply(f, M[2]);
        //f = multiply(f, M[3]);
        long temp = N / K;
        for (int i = 1; temp > 0; i++) {
            f = multiply(pow(moveBy[i], (int)(temp % K)), f);
            temp /= K;
        }
        /*p("f");
        for (int i = 0; i < K+1; i++)
            p(f[i]);*/
        long[] start = new long[K+1];
        for (int i = 0; i < start.length; i++)
            start[i] = (1L<<(i)) % MOD;
        start[K] = 1;

        int position = (int)(N % K);
        //p("taking: ", position);
        long ans = 0;
        for (int i = 0; i < start.length; i++)
            ans += (start[i] * f[i][position]) % MOD;
        ans %= MOD;

        /*long a2 = slow((int)N, K);
        if (ans != a2) {
            p(ans, a2);
            throw new RuntimeException();
        }*/
        System.out.println(ans);
    }
    static long[][] pow(long[][] M, int p) {
        long[][] ans = new long[M.length][M.length];
        for (int i = 0; i < ans.length ;i++)
            ans[i][i] = 1;
        long[][] go = new long[M.length][M.length];
        for (int i = 0; i < go.length ;i++)
            for (int j = 0; j < go.length ;j++)
                go[i][j] = M[i][j];
        while (p > 0) {
            if (p % 2 == 1) {
                ans = multiply(ans, go);
            }
            p /= 2;
            go = multiply(go, go);
        }
        return ans;
    }
    static long[][] makeMatrix(int K, int a) {
        long[][] res = new long[K+1][K+1];

        int[] v = new int[2*K];
        v[2*K-1] = 0;
        for (int i = 2*K-2; i >= 0; i--) {
            if (i == K-1) {
                v[i] = (K + (K-a + v[i+1]) % K) % K;
            } else {
                v[i] = (K + (K-1 + v[i+1]) % K) % K;
            }
        }
        /*if (a == 2 || a == 3) {
            p(a, v);
        }*/
        for (int i = 0; i <= K; i++)
            res[K][i]++;
        for (int c = 0; c < K; c++) {
            for (int i = 0; i < K; i++) {
                boolean found = false;
                for (int j = c - 1 + K; j >= 0; j--) {
                    if (v[j] == i) {
                        found = true;
                        if (j < K) {
                            res[j][c] += 1;
                        } else {
                            for (int b = 0; b <= K; b++)
                                res[b][c] += res[b][j-K];
                        }
                        break;
                    }
                }
                if (!found) {
                    p(c, i, v);
                    throw new RuntimeException();
                }
            }
        }
        return res;
    }
    static long[][] multiply(long[][] A, long[][] B) {
        long[][] res = new long[A.length][A.length];
        for (int r = 0; r < A.length; r++)
            for (int c = 0; c < A.length; c++) {
                for (int i = 0; i < A.length; i++)
                    res[r][c] += (A[r][i] * B[i][c]) % MOD;
                res[r][c] %= MOD;
            }
        return res;
    }
 }

import java.io.*;
import java.util.*;

public class EMain {
    String noResultMessage = "NoResult";
    Parser in = new Parser();
    PrintWriter out;

    long n = in.nextLong();
    int k = in.nextInteger();

    Matrix[] upRow(Matrix[] row){
        Matrix[] result = new Matrix[k];
        for(int i = 0; i < k; ++i){
            Matrix m = Matrix.oneMatrix(k+1);
            for(int j = 0; j < k; ++j){
                m = Matrix.mul(m, row[(i+j)%k]);
            }
            result[i] = m;
        }
        return result;
    }

    public void solve() {

        Matrix[][] matrixes = new Matrix[100][k];

        for(int i = 0; i < k; ++i){
            Matrix m = Matrix.oneMatrix(k + 1);
            matrixes[0][i] = m;
            for(int j = 0; j <= k; ++j){
                m.set(j, i, 1);
            }
        }
        int[] digits = new int[100];
        int index = 0;
        long limit = n;
        digits[index++] = (int) (limit % k);
        for(int row = 1; row < 100; ++row){
            limit /= k;
            if(limit == 0)break;
            digits[index++] = (int) (limit % k);
            matrixes[row] = upRow(matrixes[row-1]);
        }

        Matrix result = Matrix.oneMatrix(k+1);
        int pos = 0;
        while(index-- > 0){
            while(digits[index]-- > 0){
                result = Matrix.mul(result, matrixes[index][pos++]);
            }
        }
        Vector vec = new Vector(k+1);
        vec.set(k, 1);
        out.println(Vector.mul(vec, result).sum());

    }

    static int MOD = (int) (1e9+7);

    static public class Matrix {
        int[][] data;

        public Matrix(int size) {
            this.data = new int[size][size];
        }

        Matrix(Matrix other) {
            int size = other.data.length;
            this.data = new int[size][];
            for(int i = 0; i < size; ++i){
                this.data[i] = Arrays.copyOf(other.data[i], size);
            }
        }
        public void set(int row, int column, int value){
            data[row][column] = value;
        }

        public static Matrix oneMatrix(int size){
            Matrix result = new Matrix(size);
            for(int i = 0; i < size; ++i){
                result.data[i][i] = 1;
            }
            return result;
        }

        public static Matrix mul(Matrix left, Matrix right){
            int size = left.data.length;
            assert size == right.data.length;
            Matrix result = new Matrix(size);
            for(int i = 0; i < size; ++i){
                for(int j = 0; j < size; ++j){
                    int val = 0;
                    for(int k = 0; k < size; ++k){
                        val += 1l * left.data[i][k] * right.data[k][j] % MOD;
                        val += MOD;
                        val %= MOD;
                    }
                    result.data[i][j] = val;
                }
            }
            return result;
        }

        static Matrix degree(Matrix matrix, long degree){
            Matrix result = Matrix.oneMatrix(matrix.data.length);
            while(degree > 0){
                if((degree & 1) == 1){
                    result = Matrix.mul(result, matrix);
                }
                result = Matrix.mul(result, result);
                degree >>= 1;
            }
            return result;
        }
    }

    static public class Vector{
        int[] data;

        public Vector(int size) {
            this.data = new int[size];
        }

        Vector(Vector other) {
            this.data = Arrays.copyOf(other.data, other.data.length);
        }

        public void set(int pos, int val){
            data[pos] = val;
        }

        int get(int pos){
            return data[pos];
        }

        public int sum(){
            long sum = 0;
            for(int i : data){
                sum += i;
            }
            sum %= MOD;
            sum += MOD;
            sum %= MOD;
            return (int) sum;
        }

        public static Vector mul(Vector vec, Matrix matrix){
            int size = vec.data.length;
            assert size == matrix.data.length;
            Vector result = new Vector(size);
            for(int i = 0; i < size; ++i){
                int val = 0;
                for(int j = 0; j < size; ++j){
                    val += 1l * vec.data[j] * matrix.data[j][i] % MOD;
                    val += MOD;
                    val %= MOD;
                }
                result.data[i] = val;
            }
            return result;
        }
    }

    static public class Parser{
        Scanner scanner;

        public Parser() {
            scanner = new Scanner(System.in).useLocale(Locale.ENGLISH);
        }

        public Parser(String str) {
            scanner = new Scanner(str).useLocale(Locale.ENGLISH);
        }

        long nextLong(){
            return scanner.nextLong();
        }

        int nextInteger(){
            return scanner.nextInt();
        }

        double nextDouble(){
            return scanner.nextDouble();
        }

        String nextLine(){
            return scanner.nextLine();
        }

        String next(){
            return scanner.next();
        }

        int[] nextIntegers(int count){
            int[] result = new int[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextInteger();
            }
            return result;
        }

        long[] nextLongs(int count){
            long[] result = new long[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextLong();
            }
            return result;
        }

        int[][] nextIntegers(int fields, int count){
            int[][] result = new int[fields][count];
            for(int c = 0; c < count; ++c){
                for(int i = 0; i < fields; ++i){
                    result[i][c] = nextInteger();
                }
            }
            return result;
        }
    }

    void noResult(){
        throw new NoResultException();
    }

    void noResult(String str){
        throw new NoResultException(str);
    }

    void run(){
        try{
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            out = new PrintWriter(outStream);
            solve();
            out.close();
            System.out.print(outStream.toString());
        } catch (NoResultException exc){
            System.out.print(null == exc.response ? noResultMessage : exc.response);
        }
    }

    public static void main(String[] args) {
        new EMain().run();
    }

    public static class NoResultException extends RuntimeException{
        private String response;

        public NoResultException(String response) {
            this.response = response;
        }

        public NoResultException() {
        }
    }
}

import java.io.*;
import java.util.*;

public class EMain {
    String noResultMessage = "NoResult";
    Parser in = new Parser();
    PrintWriter out;

    long n = in.nextLong();
    int k = in.nextInteger();

    Matrix[] upRow(Matrix[] row){
        Matrix[] result = new Matrix[k];
        for(int i = 0; i < k; ++i){
            Matrix m = Matrix.oneMatrix(k+1);
            for(int j = 0; j < k; ++j){
                m = Matrix.mul(m, row[(i+j)%k]);
            }
            result[i] = m;
        }
        return result;
    }

    public void solve() {

        Matrix[][] matrixes = new Matrix[100][k];

        for(int i = 0; i < k; ++i){
            Matrix m = Matrix.oneMatrix(k + 1);
            matrixes[0][i] = m;
            for(int j = 0; j <= k; ++j){
                m.set(j, i, 1);
            }
        }
        int[] digits = new int[100];
        int index = 0;
        long limit = n;
        digits[index++] = (int) (limit % k);
        for(int row = 1; row < 100; ++row){
            limit /= k;
            if(limit == 0)break;
            digits[index++] = (int) (limit % k);
            matrixes[row] = upRow(matrixes[row-1]);
        }

        Matrix result = Matrix.oneMatrix(k+1);
        int pos = 0;
        while(index-- > 0){
            while(digits[index]-- > 0){
                result = Matrix.mul(result, matrixes[index][pos++%k]);
            }
        }
        Vector vec = new Vector(k+1);
        vec.set(k, 1);
        out.println(Vector.mul(vec, result).sum());

    }

    static int MOD = (int) (1e9+7);

    static public class Matrix {
        int[][] data;

        public Matrix(int size) {
            this.data = new int[size][size];
        }

        Matrix(Matrix other) {
            int size = other.data.length;
            this.data = new int[size][];
            for(int i = 0; i < size; ++i){
                this.data[i] = Arrays.copyOf(other.data[i], size);
            }
        }
        public void set(int row, int column, int value){
            data[row][column] = value;
        }

        public static Matrix oneMatrix(int size){
            Matrix result = new Matrix(size);
            for(int i = 0; i < size; ++i){
                result.data[i][i] = 1;
            }
            return result;
        }

        public static Matrix mul(Matrix left, Matrix right){
            int size = left.data.length;
            assert size == right.data.length;
            Matrix result = new Matrix(size);
            for(int i = 0; i < size; ++i){
                for(int j = 0; j < size; ++j){
                    int val = 0;
                    for(int k = 0; k < size; ++k){
                        val += 1l * left.data[i][k] * right.data[k][j] % MOD;
                        val += MOD;
                        val %= MOD;
                    }
                    result.data[i][j] = val;
                }
            }
            return result;
        }

        static Matrix degree(Matrix matrix, long degree){
            Matrix result = Matrix.oneMatrix(matrix.data.length);
            while(degree > 0){
                if((degree & 1) == 1){
                    result = Matrix.mul(result, matrix);
                }
                result = Matrix.mul(result, result);
                degree >>= 1;
            }
            return result;
        }
    }

    static public class Vector{
        int[] data;

        public Vector(int size) {
            this.data = new int[size];
        }

        Vector(Vector other) {
            this.data = Arrays.copyOf(other.data, other.data.length);
        }

        public void set(int pos, int val){
            data[pos] = val;
        }

        int get(int pos){
            return data[pos];
        }

        public int sum(){
            long sum = 0;
            for(int i : data){
                sum += i;
            }
            sum %= MOD;
            sum += MOD;
            sum %= MOD;
            return (int) sum;
        }

        public static Vector mul(Vector vec, Matrix matrix){
            int size = vec.data.length;
            assert size == matrix.data.length;
            Vector result = new Vector(size);
            for(int i = 0; i < size; ++i){
                int val = 0;
                for(int j = 0; j < size; ++j){
                    val += 1l * vec.data[j] * matrix.data[j][i] % MOD;
                    val += MOD;
                    val %= MOD;
                }
                result.data[i] = val;
            }
            return result;
        }
    }

    static public class Parser{
        Scanner scanner;

        public Parser() {
            scanner = new Scanner(System.in).useLocale(Locale.ENGLISH);
        }

        public Parser(String str) {
            scanner = new Scanner(str).useLocale(Locale.ENGLISH);
        }

        long nextLong(){
            return scanner.nextLong();
        }

        int nextInteger(){
            return scanner.nextInt();
        }

        double nextDouble(){
            return scanner.nextDouble();
        }

        String nextLine(){
            return scanner.nextLine();
        }

        String next(){
            return scanner.next();
        }

        int[] nextIntegers(int count){
            int[] result = new int[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextInteger();
            }
            return result;
        }

        long[] nextLongs(int count){
            long[] result = new long[count];
            for(int i = 0; i < count; ++i){
                result[i] = nextLong();
            }
            return result;
        }

        int[][] nextIntegers(int fields, int count){
            int[][] result = new int[fields][count];
            for(int c = 0; c < count; ++c){
                for(int i = 0; i < fields; ++i){
                    result[i][c] = nextInteger();
                }
            }
            return result;
        }
    }

    void noResult(){
        throw new NoResultException();
    }

    void noResult(String str){
        throw new NoResultException(str);
    }

    void run(){
        try{
            ByteArrayOutputStream outStream = new ByteArrayOutputStream();
            out = new PrintWriter(outStream);
            solve();
            out.close();
            System.out.print(outStream.toString());
        } catch (NoResultException exc){
            System.out.print(null == exc.response ? noResultMessage : exc.response);
        }
    }

    public static void main(String[] args) {
        new EMain().run();
    }

    public static class NoResultException extends RuntimeException{
        private String response;

        public NoResultException(String response) {
            this.response = response;
        }

        public NoResultException() {
        }
    }
}

import java.util.*;
import static java.lang.Math.*;

public class E {
    static void p(Object ...args) {System.out.println(Arrays.deepToString(args));}
    static long MOD = 1_000_000_007;

    /*static int score(int a, int k) {
        int ans = 0;
        while( a > 0) {
            ans += a % k;
            a /= k;
        }
        return ans % k;
    }

    public static long slow(int N, int K) {
        long[] V = new long[N+1];
        for (int i = 0; i <= N; i++)
            V[i] = score(i, K);
        long[] dp = new long[N+1];
        for (int i = 0; i <= N; i++) {
            for (int j = 0; j < K; j++) {
                for (int a = i - 1; a >= 0; a--) {
                    if (V[a] == j) {
                        dp[i] += dp[a];
                        break;
                    }
                }
            }
            dp[i] += 1;
            dp[i] %= MOD;
        }
        return dp[N];
    }*/
    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        long N = in.nextLong();
        int K = in.nextInt();

        long[][][] M = new long[100][][];
        for (int i = 2; i < M.length; i++)
            M[i] = makeMatrix(K, i);

        /*p("M[2]");
        for (int i = 0; i < M[2].length; i++)
            p(M[2][i]);
        p("M[3]");
        for (int i = 0; i < M[3].length; i++)
            p(M[3][i]);*/

        long[][][] moveBy = new long[100][][];
        long[][][] moveByK = new long[100][][];
        for (int i = 1; i < moveBy.length - 1; i++) {
            long[][] ans = new long[K+1][K+1];
            for (int j = 0; j < ans.length; j++)
                ans[j][j] = 1;
            for (int j = i - 1; j >= 1; j--)
                ans = multiply(ans, moveByK[j]);

            ans = multiply(ans, M[i+1]);
            moveBy[i] = ans;
            moveByK[i] = new long[K+1][K+1];
            for (int j = 0; j <= K; j++)
                moveByK[i][j][j] = 1;
            for (int j = 0; j < K-1; j++)
                moveByK[i] = multiply(moveByK[i], moveBy[i]);
        }
        /*p("moveBy[2]");
        for (int i = 0; i <= K; i++)
            p(moveBy[2][i]);*/

        long at = 0;
        long[][] f = new long[K+1][K+1];
        for (int i = 0; i < f.length; i++)
            f[i][i] = 1;
        //f = multiply(f, M[2]);
        //f = multiply(f, M[3]);
        long temp = N / K;
        for (int i = 1; temp > 0; i++) {
            for (int j = 0; j < temp % K; j++) {
                //p("mult by", i);
                f = multiply(moveBy[i], f);
            }
            temp /= K;
        }
        /*p("f");
        for (int i = 0; i < K+1; i++)
            p(f[i]);*/
        long[] start = new long[K+1];
        for (int i = 0; i < start.length; i++)
            start[i] = (1L<<(i)) % MOD;
        start[K] = 1;

        int position = (int)(N % K);
        p("taking: ", position);
        long ans = 0;
        for (int i = 0; i < start.length; i++)
            ans += (start[i] * f[i][position]) % MOD;
        ans %= MOD;

        /*long a2 = slow((int)N, K);
        if (ans != a2) {
            p(ans, a2);
            throw new RuntimeException();
        }*/
        System.out.println(ans);
    }
    static long[][] makeMatrix(int K, int a) {
        long[][] res = new long[K+1][K+1];

        int[] v = new int[2*K];
        v[2*K-1] = 0;
        for (int i = 2*K-2; i >= 0; i--) {
            if (i == K-1) {
                v[i] = (K + (K-a + v[i+1]) % K) % K;
            } else {
                v[i] = (K + (K-1 + v[i+1]) % K) % K;
            }
        }
        /*if (a == 2 || a == 3) {
            p(a, v);
        }*/
        for (int i = 0; i <= K; i++)
            res[K][i]++;
        for (int c = 0; c < K; c++) {
            for (int i = 0; i < K; i++) {
                boolean found = false;
                for (int j = c - 1 + K; j >= 0; j--) {
                    if (v[j] == i) {
                        found = true;
                        if (j < K) {
                            res[j][c] += 1;
                        } else {
                            for (int b = 0; b <= K; b++)
                                res[b][c] += res[b][j-K];
                        }
                        break;
                    }
                }
                if (!found) {
                    p(c, i, v);
                    throw new RuntimeException();
                }
            }
        }
        return res;
    }
    static long[][] multiply(long[][] A, long[][] B) {
        long[][] res = new long[A.length][A.length];
        for (int r = 0; r < A.length; r++)
            for (int c = 0; c < A.length; c++) {
                for (int i = 0; i < A.length; i++)
                    res[r][c] += (A[r][i] * B[i][c]) % MOD;
                res[r][c] %= MOD;
            }
        return res;
    }
 }

import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.BufferedReader;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.StringTokenizer;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		TaskE solver = new TaskE();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskE {
    static final long MODULO = (long) (1e9 + 7);
    static final long BIG = Long.MAX_VALUE - Long.MAX_VALUE % MODULO;

    public void solve(int testNumber, InputReader in, PrintWriter out) {
        long n = in.nextLong();
        int k = in.nextInt();
        long pk = 1;
        int pow = 0;
        while (pk <= n / k) {
            pk *= k;
            ++pow;
        }
        matrCache = new long[pow + 1][][];
        long at = 0;
        long[] ways = new long[k + 1];
        ways[k] = 1;
        while (at < n) {
            while (at + pk <= n) {
                long[][] matr = getMatr(digitSum(at, k) % k, k, pow);
                ways = mul(matr, ways);
                at += pk;
            }
            pk /= k;
            --pow;
        }
        long res = 0;
        for (long x : ways) res += x;
        res %= MODULO;
        out.println(res);
    }

    long[][][] matrCache;

    private long[][] getMatr(int pre, int k, int pow) {
        long[][] res = matrCache[pow];
        if (res == null) {
            if (pow == 0) {
                res = new long[k + 1][k + 1];
                for (int i = 0; i < k + 1; ++i) ++res[i][i];
                for (int i = 0; i < k + 1; ++i) {
                    ++res[pre][i];
                }
                --res[pre][pre];
            } else {
                res = new long[k + 1][k + 1];
                for (int i = 0; i < k + 1; ++i) ++res[i][i];
                for (int i = 0; i < k; ++i) {
                    res = mul(res, getMatr(i, k, pow - 1));
                }
            }
            matrCache[pow] = res;
        }
        long[][] rotated = new long[k + 1][k + 1];
        for (int i = 0; i <= k; ++i)
            for (int j = 0; j <= k; ++j) {
                int ii = (i == k) ? k : (pre + i) % k;
                int jj = (j == k) ? k : (pre + j) % k;
                rotated[ii][jj] = res[i][j];
            }
        return rotated;
    }

    private long[] mul(long[][] a, long[] b) {
        long[] c = new long[b.length];
        for (int i = 0; i < c.length; ++i) {
            long s = 0;
            for (int j = 0; j < c.length; ++j) {
                s += a[i][j] * b[j];
                if (s < 0) s -= BIG;
            }
            c[i] = s % MODULO;
        }
        return c;
    }

    private long[][] mul(long[][] a, long[][] b) {
        long[][] c = new long[b.length][b.length];
        for (int i = 0; i < c.length; ++i) {
            for (int k = 0; k < c.length; ++k) {
                long s = 0;
                for (int j = 0; j < c.length; ++j) {
                    s += a[i][j] * b[j][k];
                    if (s < 0) s -= BIG;
                }
                c[i][k] = s % MODULO;
            }
        }
        return c;
    }

    private int digitSum(long at, int k) {
        int res = 0;
        while (at > 0) {
            res += at % k;
            at /= k;
        }
        return res;
    }
}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

    public InputReader(InputStream stream) {
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }

    public String next() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            try {
                tokenizer = new StringTokenizer(reader.readLine());
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }

    public int nextInt() {
        return Integer.parseInt(next());
    }

    public long nextLong() {
        return Long.parseLong(next());
    }

}


import java.io.*;
import java.util.*;
import java.math.*;

public class cfD implements Runnable {
	private final boolean useStandardIO = true;
	private final String inFile = "segments.in";
	private final String outFile = "segments.out";

	int n, m, k;
	int[][] c, aa;

	int dp[][][];
	boolean[][][] was;

	int go(int m1, int m2, int need) {
		if (was[need][m1][m2])
			return dp[need][m1][m2];
		int res = 0;
		int have = Integer.bitCount(m1);
		int cur = Integer.bitCount(m2);
		if (m2 == 0) {
			if (have == need)
				res = 1;
		} else {
			int[] a1 = new int[have], a2 = new int[cur];
			int j = 0;
			for (int i = 0; i < n; ++i)
				if ((m1 & (1 << i)) != 0)
					a1[j++] = i;
			j = 0;
			for (int i = 0; i < n; ++i)
				if ((m2 & (1 << i)) != 0)
					a2[j++] = i;
			int tot = 1;
			for (int i = 0; i < cur; ++i)
				tot *= (have + 1);
			for (int mask = 1; mask < tot; ++mask) {
				int x = mask;
				int taken = 0, takenMask = 0, newLeaves = 0, newMask = 0;
				boolean ok = true;
				for (j = 0; j < cur; ++j) {
					int y = x % (have + 1);
					x /= (have + 1);
					if (y == 0)
						continue;
					--y;
					if (c[a1[y]][a2[j]] == 0) {
						ok = false;
						break;
					}
					if ((takenMask & (1 << y)) == 0) {
						++taken;
						takenMask |= (1 << y);
					}
					++newLeaves;
					newMask |= (1 << a2[j]);
				}
				if (!ok || newMask == 0)
					continue;
				int old = have - taken;
				if (m1 == 1 && newLeaves < 2)
					++old;
				if (need - old >= 0)
					res += go(newMask, m2 ^ newMask, need - old);
			}
		}

		was[need][m1][m2] = true;
		return dp[need][m1][m2] = res;
	}

	private void solve() throws IOException {
		n = nextInt();
		m = nextInt();
		k = nextInt();
		c = new int[n][n];
		for (int i = 0; i < m; ++i) {
			int x = nextInt() - 1, y = nextInt() - 1;
			c[x][y] = c[y][x] = 1;
		}

		dp = new int[k + 1][1 << n][1 << n];
		was = new boolean[k + 1][1 << n][1 << n];
		writer.print(go(1, (1 << n) - 2, k));
	}

	public static void main(String[] args) {
		new cfD().run();
	}

	BufferedReader reader;
	StringTokenizer tokenizer;
	PrintWriter writer;

	public void run() {
		try {
			Locale.setDefault(Locale.US);
			if (useStandardIO)
				reader = new BufferedReader(new InputStreamReader(System.in));
			else
				reader = new BufferedReader(new FileReader(inFile));
			tokenizer = null;
			if (useStandardIO)
				writer = new PrintWriter(System.out);
			else
				writer = new PrintWriter(new FileWriter(outFile));
			solve();
			reader.close();
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	BigInteger nextBigInteger() throws IOException {
		return new BigInteger(nextToken());
	}

	String nextToken() throws IOException {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
}

import java.util.*;

public class E {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		int n = s.nextInt(), m = s.nextInt(), k = s.nextInt();
		int[][] a = new int[m][];
		int[][] count = new int[1 << n][1 << n];
		for (int i = 0; i < m; ++i) {
			int u = s.nextInt() - 1, v = s.nextInt() - 1;
			a[i] = new int[] { u, v };
			count[bit(u) | bit(v)][bit(u) | bit(v)] = 1;
		}
		int result = 0;
		for (int used = 0; used < bit(n); ++used) {
			for (int deadends = 0; deadends < bit(n); ++deadends) {
				int c = Integer.bitCount(deadends);
				if (c > 1 && count[used][deadends] > 1) {
					count[used][deadends] /= c;
				}
				if (used == bit(n) - 1 && c == k) {
					result += count[used][deadends];
				}
				for (int i = 0; i < m; ++i) {
					int u = a[i][0], v = a[i][1];
					int ut = used, dt = deadends;
					if (isUsed(u, used) ^ isUsed(v, used)) {
						if (isUsed(u, used)) {
							ut = add(v, ut);
							if (isUsed(u, dt)) {
								dt = remove(u, dt);
							}
							dt = add(v, dt);
						} else {
							ut = add(u, ut);
							if (isUsed(v, dt)) {
								dt = remove(v, dt);
							}
							dt = add(u, dt);
						}
						count[ut][dt] += count[used][deadends];
					}
				}
			}
		}
		System.out.println(result);
	}

	private static int remove(int v, int dt) {
		return dt ^ bit(v);
	}

	private static int add(int u, int dt) {
		return dt | bit(u);
	}

	private static boolean isUsed(int u, int dt) {
		return (dt & bit(u)) > 0;
	}

	private static int bit(int v) {
		return 1 << v;
	}

}

import java.util.Scanner;

public class E {

	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int[][]a = new int[n][n];
		int[][]dp = new int[1 << n][1 << n];
		for (int i = 1; i <= m; i++) {
			int v1 = sc.nextInt();
			int v2 = sc.nextInt();
			v1--;
			v2--;
			a[v1][v2] = a[v2][v1] = 1;
			dp[(1 << v1) | (1 << v2)][(1 << v1) | (1 << v2)] = 1;
		}
		for (int mask = 0; mask < (1 << n); mask++) {
			for (int subm = mask; subm != 0; subm = ((subm-1) & mask)) {
				if (dp[mask][subm]==0)
					continue;
				for (int i = 0; i < n; i++) {
					if ((mask & (1 << i)) != 0) {
						for (int j = 0; j < n; j++) {
							if ((mask & (1 << j))==0 && a[i][j]==1) {
								int new_subm = (subm | (1 << j));
								if ((subm & (1 << i)) != 0)
									new_subm ^= (1 << i);
								int q = (1 << n)-(1 << (j+1));
								if ((new_subm & q) != 0)
										continue;
								dp[mask | (1 << j)][new_subm] += dp[mask][subm];
							}
						}
					}
				}
			}
		}
		int ans = 0;
		for (int mask = 0; mask < (1 << n); mask++) {
			if (Integer.bitCount(mask)==k)
				ans += dp[(1 << n)-1][mask];
		}
		System.out.println(ans);
	}

}

/**
 * Created by IntelliJ IDEA.
 * User: Taras_Brzezinsky
 * Date: 9/13/11
 * Time: 5:34 PM
 * To change this template use File | Settings | File Templates.
 */

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.StringTokenizer;

public class TaskE extends Thread {
    public TaskE() {
        this.input = new BufferedReader(new InputStreamReader(System.in));
        this.output = new PrintWriter(System.out);
        this.setPriority(Thread.MAX_PRIORITY);
    }

    static final long doit(int mask, int dead, int n) {
        if ((mask & dead) == 0) {
            cache[mask][dead] = 0;
            return 0;
        }
        if (cache[mask][dead] != -1) {
            return cache[mask][dead];
        }
        long result = 0;
        for (int a = 0; a < n; ++a) {
            if (((mask & (1 << a)) != 0) && ((dead & (1 << a)) != 0)) {
                for (int b = 0; b < n; ++b) {
                    if (g[a][b] && (mask & (1 << b)) != 0) {
                        if (mask == ((1 << a) | (1 << b))) {
                            cache[mask][dead] = ((dead & mask) == mask) ? 1 : 0;
                            return cache[mask][dead];
                        }
                        if ((dead & (1 << b)) == 0) {
                            result += doit(mask ^ (1 << a), dead, n) + doit(mask ^ (1 << a), dead ^ (1 << b), n);
                        }
                    }
                }
                break;
            }
        }
        cache[mask][dead] = result;
        return result;
    }

    private void solve() throws Throwable {
        int n = nextInt(), m = nextInt(), k = nextInt();
        g = new boolean[n][n];
        cache = new long[1 << n][1 << n];
        for (long[] current : cache) {
            Arrays.fill(current, -1);
        }
        Arrays.fill(cache[0], 1);
        for (int i = 0; i < m; ++i) {
            int a = nextInt() - 1, b = nextInt() - 1;
            g[a][b] = g[b][a] = true;
        }
        long ans = 0;
        for (int dead = 0; dead < (1 << n); ++dead) {
            if (Integer.bitCount(dead) == k) {
                ans += doit((1 << n) - 1, dead, n);
            }
        }
        output.println(ans);

    }

    public void run() {
        try {
            solve();
        } catch (Throwable e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
            System.exit(666);
        } finally {
            output.flush();
            output.close();
        }
    }

    public static void main(String[] args) {
        new TaskE().start();
    }

    private int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    private long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    private double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    private String nextToken() throws IOException {
        while (tokens == null || !tokens.hasMoreTokens()) {
            tokens = new StringTokenizer(input.readLine());
        }
        return tokens.nextToken();
    }

    static long[][] cache;
    static boolean[][] g;
    private BufferedReader input;
    private PrintWriter output;
    private StringTokenizer tokens = null;
}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.Arrays;
import java.util.StringTokenizer;

public class Main {

	/**
	 * @param args
	 */
	static int N, M, K;
	static int[] G, log;
	static long[][] DP;
	public static void main(String[] args) {
		DP = new long[1 << 17][13];

		log = new int[1 << 15];
		for(int i = 0; i < 15; i++)
			log[1 << i] = i;

		InputReader r = new InputReader(System.in);

		N = r.nextInt();
		M = r.nextInt();
		K = r.nextInt();

		G = new int[N];

		int id = 1;
		for(int k = 0; k < M; k++){
			int i = r.nextInt() - 1;
			int j = r.nextInt() - 1;

//			G[Math.min(i, j)] |= 1 << Math.max(i, j);
			G[i] |= 1 << j;
			G[j] |= 1 << i;
		}

		for(long[] i : DP)
			Arrays.fill(i, -1);

		long ret = 0;
		for(int next = G[0]; next > 0; next = (next - 1) & G[0]){
//			System.out.println(Integer.toBinaryString(next));
			ret += go(1, next | 1, Integer.bitCount(next) == 1 ? 1 : 0);
		}

		System.out.println(ret);
	}

	private static long go(int done, int reached, int c) {
		if(done == (1 << N) - 1){
			return c == K ? 1 : 0;
		}else{
			if(DP[gen(done, reached)][c] != -1)return DP[gen(done, reached)][c];

			int can = reached & ~done;
			int curr = can & -can;

//			System.out.println(curr + ", " + currI);
			if(curr == 0)return DP[gen(done, reached)][c] = 0;

			int currI = log[curr];

			long ret = 0;

			ret += go(done | 1 << currI, reached, c + 1);
			for(int next = G[currI] & ~reached; next > 0; next = (next - 1) & G[currI] & ~reached){
//				System.out.println(currI + ", " + next);
				ret += go(done | 1 << currI, reached | next, c);
			}

			return DP[gen(done, reached)][c] = ret;
		}
	}

	private static int gen(int done, int reached) {
		int ret = 0;
		for(int itr = 0; itr < N; itr++){
			ret *= 3;
			if((reached & 1) == 0){
//				if((done & 1) == 1)System.out.println("error");
				ret += 0;
			}else{
				if((done & 1) == 0)ret += 1;
				else ret += 2;
			}

			done /= 2;
			reached /= 2;
		}

		return ret;
	}

	private static String print(int m) {
		String ret = Integer.toBinaryString(m);
		while(ret.length() < N)ret = "0" + ret;
		return ret;
	}

	static class InputReader {
		private BufferedReader reader;
		private StringTokenizer tokenizer;

		public InputReader(InputStream stream) {
			reader = new BufferedReader(new InputStreamReader(stream));
			tokenizer = null;
		}

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
				return null;
			}
		}

		public String next() {
			while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {
					tokenizer = new StringTokenizer(reader.readLine());
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
			}
			return tokenizer.nextToken();
		}

		public int nextInt() {
			return Integer.parseInt(next());
		}

		public long nextLong() {
			return Long.parseLong(next());
		}

		public double nextDouble() {
			return Double.parseDouble(next());
		}
	}
}

import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class P053E{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int n, m, k;
	int[] u, v;

	void run(){
		n=sc.nextInt();
		m=sc.nextInt();
		k=sc.nextInt();
		u=new int[m];
		v=new int[m];
		for(int i=0; i<m; i++){
			u[i]=sc.nextInt()-1;
			v[i]=sc.nextInt()-1;
		}
		solve();
	}

	void solve(){
		long[][] dp=new long[1<<n][1<<n];
		// dp[s][t]:=「sが連結かつtが葉」の個数

		for(int i=0; i<m; i++){
			dp[(1<<u[i])|(1<<v[i])][(1<<u[i])|(1<<v[i])]=2;
		}
		for(int s=0; s<1<<n; s++){
			int t=s;
			do{
				if(Integer.bitCount(t)>0){
					dp[s][t]/=Integer.bitCount(t);
				}
				for(int i=0; i<m; i++){
					boolean ub=(s>>u[i]&1)==1;
					boolean vb=(s>>v[i]&1)==1;
					if(ub&!vb){
						dp[s|(1<<v[i])][t&~(1<<u[i])|(1<<v[i])]+=dp[s][t];
					}
					if(!ub&vb){
						dp[s|(1<<u[i])][t&~(1<<v[i])|(1<<u[i])]+=dp[s][t];
					}
				}
				t=(t-1)&s;
			}while(t!=s);
		}

		long ans=0;
		int comb=(1<<k)-1;
		for(; comb<1<<n;){
			ans+=dp[(1<<n)-1][comb];
			int x=comb&-comb, y=comb+x;
			comb=((comb&~y)/x>>>1)|y;
		}
		println(ans+"");
	}

	void println(String s){
		System.out.println(s);
	}

	void print(String s){
		System.out.print(s);
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P053E().run();
	}
}

import java.util.*;
import java.lang.*;
import java.math.*;
import java.io.*;
import static java.lang.Math.*;
import static java.util.Arrays.*;
import static java.util.Collections.*;

public class P053E{
	Scanner sc=new Scanner(System.in);

	int INF=1<<28;
	double EPS=1e-9;

	int n, m, k;
	int[] u, v;

	void run(){

		// test();
		n=sc.nextInt();
		m=sc.nextInt();
		k=sc.nextInt();
		// k個が葉になる全域木の個数
		// n<=10
		// m<=50
		u=new int[m];
		v=new int[m];
		for(int i=0; i<m; i++){
			u[i]=sc.nextInt()-1;
			v[i]=sc.nextInt()-1;
		}
		solve();
	}

	void test(){
		n=10;
		m=50;
		m=40;
		k=5;
		u=new int[m];
		v=new int[m];
		for(int i=0; i<m; i++){
			u[i]=(int)(random()*n);
			v[i]=(int)(random()*n);
			for(; v[i]==u[i];){
				v[i]=(int)(random()*n);
			}
			boolean ok=true;
			for(int j=0; j<i; j++){
				ok&=u[i]!=u[j]||v[i]!=v[j];
				ok&=u[i]!=v[j]||v[i]!=u[j];
			}
			if(!ok){
				i--;
				continue;
			}
		}
		solve();
	}

	void solve(){
		long[][] dp=new long[1<<n][1<<n];
		// [s][t]:=sが連結，tが葉，の個数

		for(int i=0; i<n; i++){
			// dp[1<<i][1<<i]=1;
		}
		for(int i=0; i<m; i++){
			dp[(1<<u[i])|(1<<v[i])][(1<<u[i])|(1<<v[i])]=2;
		}
		// dp[1][1]=1;
		for(int s=1; s<1<<n; s++){
			int t=s;
			do{
				if(Integer.bitCount(t)>0){
					dp[s][t]/=Integer.bitCount(t);
				}
				for(int i=0; i<m; i++){
					boolean ub=(s>>u[i]&1)==1;
					boolean vb=(s>>v[i]&1)==1;
					if(ub&!vb){
						dp[s|(1<<v[i])][t&~(1<<u[i])|(1<<v[i])]+=dp[s][t];
					}
					if(!ub&vb){
						dp[s|(1<<u[i])][t&~(1<<v[i])|(1<<u[i])]+=dp[s][t];
					}
				}
				t=(t-1)&s;
			}while(t!=s);
		}
		long ans=0;
		int comb=(1<<k)-1;
		for(; comb<1<<n;){
			ans+=dp[(1<<n)-1][comb];
			int x=comb&-comb, y=comb+x;
			comb=((comb&~y)/x>>>1)|y;
		}
		println(ans+"");
	}

	void println(String s){
		System.out.println(s);
	}

	void print(String s){
		System.out.print(s);
	}

	void debug(Object... os){
		System.err.println(Arrays.deepToString(os));
	}

	public static void main(String[] args){
		Locale.setDefault(Locale.US);
		new P053E().run();
	}
}

import java.io.*;
import java.util.*;

public class E implements Runnable {

	private void solve() throws IOException {
		int n = nextInt();
		int[][] m = new int[n][n];
		int edges = nextInt();
		int k = nextInt();
		for (int i = 0; i < edges; i++) {
			int u = nextInt() - 1, v = nextInt() - 1;
			m[u][v]++;
			m[v][u]++;
		}
		int[][] d = new int[1 << n][1 << n];
		for (int i = 0; i < n; i++) {
			for (int j = 0; j < n; j++) {
				int mask = (1 << i) | (1 << j);
				d[mask][mask] = m[i][j];
			}
		}
		for (int mask = 1; mask < 1 << n; mask++) {
			if (Integer.bitCount(mask) <= 2)
				continue;
			for (int sub = mask; sub > 0; sub = (sub - 1) & mask) {
				int bit = Integer.numberOfTrailingZeros(sub);
				int mask1 = mask ^ (1 << bit);
				int sub1 = sub ^ (1 << bit);
				for (int i = 0; i < n; i++) {
					if ((mask1 & (1 << i)) != 0 && (sub1 & (1 << i)) == 0) {
						d[mask][sub] += m[bit][i] * d[mask1][sub1 | (1 << i)];
						d[mask][sub] += m[bit][i] * d[mask1][sub1];
					}
				}
			}
		}

		int ans = 0;
		for (int mask = 0; mask < 1 << n; mask++) {
			if (Integer.bitCount(mask) == k) {
				ans += d[(1 << n) - 1][mask];
			}
		}
		out.println(ans);
	}

	public static void main(String[] args) {
		new Thread(new E()).start();
	}

	BufferedReader br;
	StringTokenizer st;
	PrintWriter out;
	boolean eof = false;

	public void run() {
		Locale.setDefault(Locale.US);
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(239);
		}
	}

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return "0";
			}
		}
		return st.nextToken();
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}
}

//package round49;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.Arrays;

public class E5 {
	InputStream is;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni(), m = ni(), K = ni();
		boolean[][] g = new boolean[n][n];
		for(int i = 0;i < m;i++){
			int f = ni()-1, t = ni()-1;
			g[f][t] = g[t][f] = true;
		}
		int[][] dp = new int[1<<n][1<<n];
		for(int i = 0;i < n;i++){
			for(int j = i+1;j < n;j++){
				if(g[i][j]){
					dp[1<<i|1<<j][1<<i|1<<j] = 1;
				}
			}
		}
		for(int i = 0;i < 1<<n;i++){
			if(Integer.bitCount(i) <= 1)continue;
			for(int j = 0;j <= i;j++){
				if((i&j)==j){
					if(Integer.bitCount(i) >= 3 && j > 0)dp[i][j] /= Integer.bitCount(j);
					for(int k = 0;k < n;k++){
						if(i<<31-k>=0){
							for(int l = 0;l < n;l++){
								if(i<<31-l<0 && g[l][k]){
									dp[i|1<<k][j&~(1<<l)|1<<k] += dp[i][j];
								}
							}
						}
					}
				}
			}
		}

		long S = 0;
		for(int j = 0;j < 1<<n;j++){
			if(Integer.bitCount(j) == K){
				S += dp[(1<<n)-1][j];
			}
		}
		out.println(S);
	}

	void run() throws Exception
	{
		is = oj ? System.in : new ByteArrayInputStream(INPUT.getBytes());
		out = new PrintWriter(System.out);

		long s = System.currentTimeMillis();
		solve();
		out.flush();
		tr(System.currentTimeMillis()-s+"ms");
	}

	public static void main(String[] args) throws Exception
	{
		new E5().run();
	}

	public int ni()
	{
		try {
			int num = 0;
			boolean minus = false;
			while((num = is.read()) != -1 && !((num >= '0' && num <= '9') || num == '-'));
			if(num == '-'){
				num = 0;
				minus = true;
			}else{
				num -= '0';
			}

			while(true){
				int b = is.read();
				if(b >= '0' && b <= '9'){
					num = num * 10 + (b - '0');
				}else{
					return minus ? -num : num;
				}
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public long nl()
	{
		try {
			long num = 0;
			boolean minus = false;
			while((num = is.read()) != -1 && !((num >= '0' && num <= '9') || num == '-'));
			if(num == '-'){
				num = 0;
				minus = true;
			}else{
				num -= '0';
			}

			while(true){
				int b = is.read();
				if(b >= '0' && b <= '9'){
					num = num * 10 + (b - '0');
				}else{
					return minus ? -num : num;
				}
			}
		} catch (IOException e) {
		}
		return -1;
	}

	public String ns()
	{
		try{
			int b = 0;
			StringBuilder sb = new StringBuilder();
			while((b = is.read()) != -1 && (b == '\r' || b == '\n' || b == ' '));
			if(b == -1)return "";
			sb.append((char)b);
			while(true){
				b = is.read();
				if(b == -1)return sb.toString();
				if(b == '\r' || b == '\n' || b == ' ')return sb.toString();
				sb.append((char)b);
			}
		} catch (IOException e) {
		}
		return "";
	}

	public char[] ns(int n)
	{
		char[] buf = new char[n];
		try{
			int b = 0, p = 0;
			while((b = is.read()) != -1 && (b == ' ' || b == '\r' || b == '\n'));
			if(b == -1)return null;
			buf[p++] = (char)b;
			while(p < n){
				b = is.read();
				if(b == -1 || b == ' ' || b == '\r' || b == '\n')break;
				buf[p++] = (char)b;
			}
			return Arrays.copyOf(buf, p);
		} catch (IOException e) {
		}
		return null;
	}

	double nd() { return Double.parseDouble(ns()); }
	boolean oj = System.getProperty("ONLINE_JUDGE") != null;
	void tr(Object... o) { if(!oj)System.out.println(Arrays.deepToString(o)); }
}

import java.lang.reflect.Array;
import java.util.ArrayList;
import java.util.Arrays;

/**
 * Created by IntelliJ IDEA.
 * User: piyushd
 * Date: 1/7/11
 * Time: 12:04 AM
 * To change this template use File | Settings | File Templates.
 */
public class DeadEnds {

	int N, M, K;
	int[][] graph;
	long[][] res;

	long solve(int mask, int leaf, int n, int k){
		if(k < 2) return 0;
		if(res[mask][leaf] != -1) return res[mask][leaf];

		if(n == 2){

			int x = -1, y = -1;
			for(int i = 0; i < N; i++) if((mask & (1<<i)) > 0){
				if(x == -1) x = i; else y = i;
			}

			return res[mask][leaf] = graph[x][y];
		}

		long ans = 0;
		for(int i = 0; i < N; i++){
			if((leaf & (1<<i)) > 0){
				for(int j = 0; j < N; j++){
					if((mask & (1<<j)) > 0 && (leaf & (1<<j)) == 0 && graph[i][j] == 1){
						ans += solve(mask - (1<<i), leaf - (1<<i), n - 1, k - 1);
						ans += solve(mask - (1<<i), leaf - (1<<i) + (1<<j), n - 1, k);
				   	}
			   	}
				break;
			}
		}

		return res[mask][leaf] = ans;
	}

    void run(){
		N = nextInt(); M = nextInt(); K = nextInt();
		graph = new int[N][N];

		int x, y;
		for(int i = 0; i < M; i++){
			x = nextInt() - 1; y = nextInt() - 1;
			graph[x][y] = graph[y][x] = 1;
		}

		int[] bitCount = new int[1<<N];
		for(int i = 0; i < bitCount.length; i++){
			bitCount[i] = bitCount[i>>1];
			if(i % 2 == 1) bitCount[i]++;
		}

		long ret = 0;
		res = new long[1<<N][1<<N];
		for(long[] f : res) Arrays.fill(f, -1);
		for(int i = 0; i < (1<<N); i++){
			if(bitCount[i] == K){
				ret += solve((1<<N) - 1, i, N, K);
			}
		}

		System.out.println(ret);
    }

    int nextInt(){
        try{
            int c = System.in.read();
            if(c == -1) return c;
            while(c != '-' && (c < '0' || '9' < c)){
                c = System.in.read();
                if(c == -1) return c;
            }
            if(c == '-') return -nextInt();
            int res = 0;
            do{
                res *= 10;
                res += c - '0';
                c = System.in.read();
            }while('0' <= c && c <= '9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    long nextLong(){
        try{
            int c = System.in.read();
            if(c == -1) return -1;
            while(c != '-' && (c < '0' || '9' < c)){
                c = System.in.read();
                if(c == -1) return -1;
            }
            if(c == '-') return -nextLong();
            long res = 0;
            do{
                res *= 10;
                res += c-'0';
                c = System.in.read();
            }while('0' <= c && c <= '9');
            return res;
        }catch(Exception e){
            return -1;
        }
    }

    double nextDouble(){
        return Double.parseDouble(next());
    }

    String next(){
        try{
            StringBuilder res = new StringBuilder("");
            int c = System.in.read();
            while(Character.isWhitespace(c))
                c = System.in.read();
            do{
                res.append((char)c);
            }while(!Character.isWhitespace(c=System.in.read()));
            return res.toString();
        }catch(Exception e){
            return null;
        }
    }

    String nextLine(){
        try{
            StringBuilder res = new StringBuilder("");
            int c = System.in.read();
            while(c == '\r' || c == '\n')
                c = System.in.read();
            do{
                res.append((char)c);
                c = System.in.read();
            }while(c != '\r' && c != '\n');
            return res.toString();
        }catch(Exception e){
            return null;
        }
    }

    public static void main(String[] args){
        new DeadEnds().run();
    }
}

import java.util.*;
//4 6 2
//1 2
//2 3
//3 4
//4 1
//1 3
//2 4

public class E {
	public static void main(String[] args) {
		Scanner s = new Scanner(System.in);
		n = s.nextInt();
		m = s.nextInt();
		k = s.nextInt();
		a = new int[m][];
		for (int i = 0; i < m; ++i) {
			int u = s.nextInt() - 1, v = s.nextInt() - 1;
			a[i] = new int[] { u, v };
		}
		b = new boolean[m];
		System.out.println(f(-1, m));
	}

	static int n, m, k;
	static int[][] a;
	static boolean[] b;

	static int f(int x, int en) {
		if (en == n - 1) {
			int[] cs = new int[n];
			for (int i = 0; i < m; ++i) {
				if (!b[i]) {
					++cs[a[i][0]];
					++cs[a[i][1]];
				}
			}
			int cnt = 0;
			for (int c : cs) {
				if (c == 1) {
					++cnt;
				}
			}
			return cnt == k ? 1 : 0;
		}
		int result = 0;
		for (int i = x + 1; i < m; ++i) {
			if (!b[i]) {
				b[i] = true;
				result += f(i, en - 1);
				b[i] = false;
			}
		}
		return result;
	}

	static int max(int... is) {
		int r = 0;
		for (int i : is)
			r = Math.max(r, i);
		return r;
	}
}

/**
 * Created by IntelliJ IDEA.
 * User: Taras_Brzezinsky
 * Date: 9/13/11
 * Time: 5:34 PM
 * To change this template use File | Settings | File Templates.
 */

import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.StringTokenizer;

public class TaskE extends Thread {
    public TaskE() {
        this.input = new BufferedReader(new InputStreamReader(System.in));
        this.output = new PrintWriter(System.out);
        this.setPriority(Thread.MAX_PRIORITY);
    }

    static final long doit(int mask, int dead, int n) {
        if ((mask & dead) == 0) {
            return cache[mask][dead] = 0;
        }
        if (cache[mask][dead] != -1) {
            return cache[mask][dead];
        }
        long result = 0;
        for (int a = 0; a < n; ++a) {
            if ((mask & (1 << a)) == 1 && (dead & (1 << a)) == 1) {
                for (int b = 0; b < n; ++b) {
                    if (g[a][b] && (mask & (1 << b)) != 0) {
                        if (mask == ((1 << a) | (1 << b))) {
                            return cache[mask][dead] = ((dead & mask) == mask) ? 1 : 0;
                        }
                        if ((dead & (1 << b)) == 0) {
                            result += doit(mask ^ (1 << a), dead, n) + doit(mask ^ (1 << a), dead ^ (1 << b), n);
                        }
                    }
                }
            }
        }
        return cache[mask][dead] = result;
    }

    private void solve() throws Throwable {
        int n = nextInt(), m = nextInt(), k = nextInt();
        g = new boolean[n][n];
        cache = new long[1 << n][1 << n];
        for (long[] current : cache) {
            Arrays.fill(current, -1);
        }
        Arrays.fill(cache[0], 1);
        for (int i = 0; i < m; ++i) {
            int a = nextInt() - 1, b = nextInt() - 1;
            g[a][b] = g[b][a] = true;
        }
        long ans = 0;
        for (int dead = 0; dead < (1 << n); ++dead) {
            if (Integer.bitCount(dead) == k) {
                ans += doit((1 << n) - 1, dead, n);
            }
        }
        output.println(ans);

    }

    public void run() {
        try {
            solve();
        } catch (Throwable e) {
            System.err.println(e.getMessage());
            e.printStackTrace();
            System.exit(666);
        } finally {
            output.flush();
            output.close();
        }
    }

    public static void main(String[] args) {
        new TaskE().start();
    }

    private int nextInt() throws IOException {
        return Integer.parseInt(nextToken());
    }

    private long nextLong() throws IOException {
        return Long.parseLong(nextToken());
    }

    private double nextDouble() throws IOException {
        return Double.parseDouble(nextToken());
    }

    private String nextToken() throws IOException {
        while (tokens == null || !tokens.hasMoreTokens()) {
            tokens = new StringTokenizer(input.readLine());
        }
        return tokens.nextToken();
    }

    static long[][] cache;
    static boolean[][] g;
    private BufferedReader input;
    private PrintWriter output;
    private StringTokenizer tokens = null;
}

import java.io.*;
import java.util.*;
import java.math.*;

public class cfE implements Runnable {
	private final boolean useStandardIO = true;
	private final String inFile = "segments.in";
	private final String outFile = "segments.out";

	private void solve() throws IOException {
		int n=nextInt();
		int[] a = new int[n], b=new int[n];
		for (int i=0; i<n; ++i){
			a[i]=nextInt();
		}
		for (int i=0; i<n; ++i){
			b[i]=nextInt();
		}
		List<Integer> res=new ArrayList<Integer>();
		for (int i=0; i<n; ++i)
			if (a[i] != b[i]){
				for (int j=i+1; j<n; ++j) if (a[i] == b[j]){
					for (int t=j-1; t>=i; --t) {
						int tmp=b[t]; b[t]=b[t+1]; b[t+1]=tmp;
						res.add(t+1);
					}
					break;
				}
			}
		writer.println(res.size());
		for (int x : res) writer.printf("%d %d\n", x, x+1);
	}

	public static void main(String[] args) {
		new cfE().run();
	}

	BufferedReader reader;
	StringTokenizer tokenizer;
	PrintWriter writer;

	public void run() {
		try {
			Locale.setDefault(Locale.US);
			if (useStandardIO)
				reader = new BufferedReader(new InputStreamReader(System.in));
			else
				reader = new BufferedReader(new FileReader(inFile));
			tokenizer = null;
			if (useStandardIO)
				writer = new PrintWriter(System.out);
			else
				writer = new PrintWriter(new FileWriter(outFile));
			solve();
			reader.close();
			writer.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

	int nextInt() throws IOException {
		return Integer.parseInt(nextToken());
	}

	long nextLong() throws IOException {
		return Long.parseLong(nextToken());
	}

	double nextDouble() throws IOException {
		return Double.parseDouble(nextToken());
	}

	BigInteger nextBigInteger() throws IOException {
		return new BigInteger(nextToken());
	}

	String nextToken() throws IOException {
		while (tokenizer == null || !tokenizer.hasMoreTokens()) {
			tokenizer = new StringTokenizer(reader.readLine());
		}
		return tokenizer.nextToken();
	}
}

import java.io.*;
import java.util.*;

public class E implements Runnable {

	private void solve() throws IOException {
		int n = nextInt();
		int[][] m = new int[n][n];
		int edges = nextInt();
		int k = nextInt();
		for (int i = 0; i < edges; i++) {
			int u = nextInt() - 1, v = nextInt() - 1;
			m[u][v]++;
			m[v][u]++;
		}

		int[][] d = new int[1 << n][1 << n];
		for (int mask = 1; mask < 1 << n; mask++) {
			if (Integer.bitCount(mask) == 1)
				continue;
			if (Integer.bitCount(mask) == 2) {
				d[mask][mask] = 1;
				continue;
			}
			for (int sub = mask; sub > 0; sub = (sub - 1) & mask) {
				int bit = Integer.numberOfTrailingZeros(sub);
				int mask1 = mask ^ (1 << bit);
				int sub1 = sub ^ (1 << bit);
				for (int i = 0; i < n; i++) {
					if ((mask1 & (1 << i)) != 0 && (sub1 & (1 << i)) == 0) {
						d[mask][sub] += m[bit][i] * d[mask1][sub1 ^ (1 << i)];
						d[mask][sub] += m[bit][i] * d[mask1][sub1];
					}
				}
			}
		}

		int ans = 0;
		for (int mask = 0; mask < 1 << n; mask++) {
			if (Integer.bitCount(mask) == k)
				ans += d[(1 << n) - 1][mask];
		}
		out.println(ans);
	}

	public static void main(String[] args) {
		new Thread(new E()).start();
	}

	BufferedReader br;
	StringTokenizer st;
	PrintWriter out;
	boolean eof = false;

	public void run() {
		Locale.setDefault(Locale.US);
		try {
			br = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			solve();
			out.close();
		} catch (Throwable e) {
			e.printStackTrace();
			System.exit(239);
		}
	}

	String nextToken() {
		while (st == null || !st.hasMoreTokens()) {
			try {
				st = new StringTokenizer(br.readLine());
			} catch (Exception e) {
				eof = true;
				return "0";
			}
		}
		return st.nextToken();
	}

	int nextInt() {
		return Integer.parseInt(nextToken());
	}
}

//package round49;

import java.io.PrintWriter;
import java.util.Arrays;
import java.util.Scanner;

public class E {
	Scanner in;
	PrintWriter out;
	String INPUT = "";

	void solve()
	{
		int n = ni();
		int m = ni();
		int k = ni();
		long[][] dp = new long[1<<n][1<<n]; // 2 1
		dp[0][0] = 1;
		for(int i = 0;i < m;i++){
			int f = ni() - 1;
			int t = ni() - 1;
			if(f > t){
				int d = f; f = t; t = d;
			}
			for(int j = (1<<n)-1;j >= 0;j--){
				for(int l = (1<<n)-1;l >= j;l--){
					if((l&j) == j){
						int nj = j;
						int nl = l;
						if((l>>f)%2 == 1){
							nj |= 1<<f;
						}else{
							nl |= 1<<f;
						}
						if((l>>t)%2 == 1){
							nj |= 1<<t;
						}else{
							nl |= 1<<t;
						}
						dp[nj][nl] += dp[j][l];
					}
				}
			}
		}

		long sum = 0;
		for(int i = 0;i < 1<<n;i++){
			if(n - Integer.bitCount(i) == k){
				sum += dp[i][(1<<n)-1];
			}
		}
		out.println(sum);
	}

	void run() throws Exception
	{
//		StringBuilder sb = new StringBuilder("10 45 5 ");
//		for(int i = 1;i <= 10;i++){
//			for(int j = i + 1;j <= 10;j++){
//				sb.append(i + " " + j + " ");
//			}
//		}
//		INPUT = sb.toString();

		in = INPUT.isEmpty() ? new Scanner(System.in) : new Scanner(INPUT);
		out = new PrintWriter(System.out);

		solve();
		out.flush();
	}

	public static void main(String[] args) throws Exception
	{
		new E().run();
	}

	int ni() { return Integer.parseInt(in.next()); }
	void tr(Object... o) { if(INPUT.length() != 0)System.out.println(Arrays.deepToString(o)); }
}