This problem is same as the previous one, but has larger constraints.

Aki is playing a new video game. In the video game, he will control Neko, the giant cat, to fly between planets in the Catniverse.

There are n planets in the Catniverse, numbered from 1 to n. At the beginning of the game, Aki chooses the planet where Neko is initially located. Then Aki performs k - 1 moves, where in each move Neko is moved from the current planet x to some other planet y such that:

  * Planet y is not visited yet. 
  * 1 ≤ y ≤ x + m (where m is a fixed constant given in the input) 



This way, Neko will visit exactly k different planets. Two ways of visiting planets are called different if there is some index i such that, the i-th planet visited in the first way is different from the i-th planet visited in the second way.

What is the total number of ways to visit k planets this way? Since the answer can be quite large, print it modulo 10^9 + 7.

Input

The only line contains three integers n, k and m (1 ≤ n ≤ 10^9, 1 ≤ k ≤ min(n, 12), 1 ≤ m ≤ 4) — the number of planets in the Catniverse, the number of planets Neko needs to visit and the said constant m.

Output

Print exactly one integer — the number of different ways Neko can visit exactly k planets. Since the answer can be quite large, print it modulo 10^9 + 7.

Examples

Input


3 3 1


Output


4


Input


4 2 1


Output


9


Input


5 5 4


Output


120


Input


100 1 2


Output


100

Note

In the first example, there are 4 ways Neko can visit all the planets:

  * 1 → 2 → 3 
  * 2 → 3 → 1 
  * 3 → 1 → 2 
  * 3 → 2 → 1 



In the second example, there are 9 ways Neko can visit exactly 2 planets:

  * 1 → 2 
  * 2 → 1 
  * 2 → 3 
  * 3 → 1 
  * 3 → 2 
  * 3 → 4 
  * 4 → 1 
  * 4 → 2 
  * 4 → 3 



In the third example, with m = 4, Neko can visit all the planets in any order, so there are 5! = 120 ways Neko can visit all the planets.

In the fourth example, Neko only visit exactly 1 planet (which is also the planet he initially located), and there are 100 ways to choose the starting planet for Neko.
import java.io.*;
import java.util.*;

public class Main implements Runnable{
    public static void main(String[] args){
        //new Thread(null,new Main(),"Thread-1",1024*1024*10).start();
        new Main().run();
    }
    int mod=1000000007;
    int n,k,m;
    private void solve() throws Exception {
        InputReader in = new InputReader(System.in);
        PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        n=in.nextInt();k=in.nextInt();m=in.nextInt();
        int[][]ma=new int[(k+1)*(1<<m)][(k+1)*(1<<m)];
        for(int i=0;i<=k;i++) {
            for (int j = 0; j < (1 << m); j++) {
                ma[trans(i,j>>1)][trans(i,j)]=1;
                if(i<k)ma[trans(i+1,j>>1|(1<<m-1))][trans(i,j)]=Integer.bitCount(j)+1;
            }
        }
        ma=FastPowMod(ma,n);
        long ans=0;
        for(int i=trans(k,0);i<ma.length;i++)ans+=ma[i][0];
        out.println(ans%mod);
        out.flush();
    }
    public int[][] FastPowMod(int[][] a,int b){
        int[][] ans=new int[a.length][a.length];
        for(int i=0;i<a.length;i++)ans[i][i]=1;
        while(b>0){
            if((b&1)==1)
                ans=modMul(ans,a);
            a=modMul(a,a);
            b>>=1;
        }
        return ans;
    }
    public int[][] modMul(int[][]a,int[][]b){
        int row=a.length,column=b[0].length;
        int len=b.length;
        int[][] ans=new int[row][column];
        for(int i=0;i<row;i++){
            for(int j=0;j<len;j++){
                if(a[i][j]==0)continue;//稀疏矩阵优化
                for(int k=0;k<column;k++){
                    ans[i][k]+=(long)a[i][j]*b[j][k]%mod;
                    ans[i][k]%=mod;
                }
            }
        }
        return ans;
    }

    int trans(int x,int y){
        return x*(1<<m)+y;
    }
    @Override
    public void run() {
        try {
            solve();
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    void shuffle(int[]a,int l,int r){
        Random rnd=new Random();
        for (int i=r; i>l+1; i--) {
            int j=rnd.nextInt(i),tmp=a[j];
            a[j]=a[i-1];
            a[i-1]=tmp;
        }
    }
    void shuffle(Object[]a,int l,int r){
        Random rnd=new Random();
        for (int i=r; i>l+1; i--) {
            int j=rnd.nextInt(i);
            Object tmp=a[j];
            a[j]=a[i-1];
            a[i-1]=tmp;
        }
    }
    void shuffle(long[]a,int l,int r){
        Random rnd=new Random();
        for (int i=r; i>l+1; i--) {
            int j=rnd.nextInt(i);
            long tmp=a[j];
            a[j]=a[i-1];
            a[i-1]=tmp;
        }
    }
    class InputReader{
        StreamTokenizer tokenizer;
        public InputReader(InputStream stream){
            tokenizer=new StreamTokenizer(new BufferedReader(new InputStreamReader(stream)));
            tokenizer.ordinaryChars(33,126);
            tokenizer.wordChars(33,126);
        }
        public String next() throws IOException {
            tokenizer.nextToken();
            return tokenizer.sval;
        }
        public int nextInt() throws IOException {
            return Integer.parseInt(next());
        }
        public long nextLong() throws IOException {
            return Long.parseLong(next());
        }
        public boolean hasNext() throws IOException {
            int res=tokenizer.nextToken();
            tokenizer.pushBack();
            return res!=tokenizer.TT_EOF;
        }
    }
}