//package com.prituladima.codeforce;

import java.io.*;
import java.util.ArrayList;
import java.util.List;
import java.util.StringTokenizer;

import static java.lang.Double.parseDouble;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.util.Arrays.stream;
import static java.util.stream.IntStream.range;

public final class Main {

    private static final long MODULO = (int) 1e9 + 7;

    private void solve() {

        long x = nextLong();
        long n = nextLong();

        long ans = 1;

        List<LongIntPair> primeFactors = factorize(x);
        for (LongIntPair primeFactor : primeFactors) {
            long pow = 0;
            long p = primeFactor.first;
            long prime = primeFactor.first;
            for (int i = 0; i <= 63; i++) {
                long d = n / p;
                if(d <= 0) break;
                pow += d;

                long overflowCheck = p;
                p*=prime;//check for overflow
                if(p / overflowCheck != prime){
                    break;
                }
            }

            ans *= power_mod(prime, pow, MODULO);
            ans %= MODULO;

        }

        println(ans);

    }

    public static List<LongIntPair> factorize(long number) {
        List<LongIntPair> result = new ArrayList<>();
        for (long i = 2; i * i <= number; i++) {
            if (number % i == 0) {
                int power = 0;
                do {
                    power++;
                    number /= i;
                } while (number % i == 0);
                result.add(LongIntPair.makePair(i, power));
            }
        }
        if (number != 1) {
            result.add(LongIntPair.makePair(number, 1));
        }
        return result;
    }

    public static class LongIntPair implements Comparable<com.prituladima.yaal.generated.collections.pair.LongIntPair> {
        public final long first;
        public final int second;

        public static LongIntPair makePair(long first, int second) {
            return new LongIntPair(first, second);
        }

        public LongIntPair(long first, int second) {
            this.first = first;
            this.second = second;
        }

        @Override
        public boolean equals(Object o) {
            if (this == o) {
                return true;
            }
            if (o == null || getClass() != o.getClass()) {
                return false;
            }

            LongIntPair pair = (LongIntPair) o;

            return first == pair.first && second == pair.second;
        }

        @Override
        public int hashCode() {
            int result = Long.hashCode(first);
            result = 31 * result + Integer.hashCode(second);
            return result;
        }

        @Override
        public String toString() {
            return "(" + first + "," + second + ")";
        }

        @SuppressWarnings({"unchecked"})
        public int compareTo(com.prituladima.yaal.generated.collections.pair.LongIntPair o) {
            int value = Long.compare(first, o.first);
            if (value != 0) {
                return value;
            }
            return Integer.compare(second, o.second);
        }
    }

    static long power_mod(long a, long pow, long mod) {
        long res = 1;
        a = a % mod;
        while (pow > 0) {
            if ((pow & 1) == 1)
                res = (res * a) % mod;
            pow = pow >> 1;
            a = (a * a) % mod;
        }
        return res;
    }

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

    private BufferedReader reader;
    private StringTokenizer tokenizer;
    private PrintWriter writer;

    private void run() {
        try (BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
             PrintWriter writer = new PrintWriter(new OutputStreamWriter(System.out))) {
            this.reader = reader;
            this.writer = writer;
            this.tokenizer = null;
            solve();
        } catch (Exception e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

    private int nextInt(int radix) {
        return parseInt(nextToken(), radix);
    }

    private int nextInt() {
        return parseInt(nextToken());
    }

    private long nextLong(int radix) {
        return parseLong(nextToken(), radix);
    }

    private long nextLong() {
        return parseLong(nextToken());
    }

    private double nextDouble() {
        return parseDouble(nextToken());
    }

    private int[] nextArr(int size) {
        return stream(new int[size]).map(c -> nextInt()).toArray();
    }

    private long[] nextArrL(int size) {
        return stream(new long[size]).map(c -> nextLong()).toArray();
    }

    private double[] nextArrD(int size) {
        return stream(new double[size]).map(c -> nextDouble()).toArray();
    }

    private char[][] nextCharMatrix(int n) {
        return range(0, n).mapToObj(i -> nextToken().toCharArray()).toArray(char[][]::new);
    }

    private int[][] nextIntMatrix(final int n, final int m) {
        return range(0, n).mapToObj(i -> nextArr(m)).toArray(int[][]::new);
    }

    private double[][] nextDoubleMatrix(final int n, final int m) {
        return range(0, n).mapToObj(i -> nextArrD(m)).toArray(double[][]::new);
    }

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

    private void printf(String format, Object... args) {
        writer.printf(format, args);
    }

    private void print(Object o) {
        writer.print(o);
    }

    private void println() {
        writer.println();
    }

    private void println(Object o) {
        print(o);
        println();
    }

    private void flush() {
        writer.flush();
    }

}


mport java.util.*;
import java.lang.*;
// StringBuilder uses java.lang

public class mainClass {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        ArrayList<ArrayList<Integer>> listOfPrimes = new ArrayList<>();
        int r = n*1;
        for (int i=2;i<=sqrt(n);i++) {
            if (r == 1) {
                break
            }
            if (r % i == 0) {
                ArrayList<Integer> primeFact = new ArrayList<>();
                primeFact.add(i);
            }
            int t = 0;
            while(r % i == 0) {
                t+=1;
                r/=i;
            }
            primeFact.add(t);
            listOfPrimes.add(primeFact);
        }
        int g = sc.nextInt();
        int ans = 1;
        for (int i=0;i<listOfPrimes.size();i++) {
            if (g>listOfPrimes.get(i).get(0)) {
                break;
            } else {
                 int ok = ((listOfPrimes.get(i).get(1))*(g-listOfPrimes.get(i).get(0)+1) % 10**9+6);
                 ans*=fastPow(listOfPrimes.get(i).get(0),ok,10**9+7);
                 ans%=(10**9+7);
            }
        }
        System.out.println(ans);
    }
    public static int fastPow(base,exp,mod) {
        ans=1;
        if (exp==0) {
            return 1;
        } else {
            if (exp % 2 == 1) {
                int z = fastPow(base,exp/2,mod);
                return ((((z*base) % mod) * z) % mod);
            } else {
                int z = fastPow(base,exp/2,mod);
                return ((z*z) % mod);
            }
        }
    }
}


import java.util.Scanner;
public class A{
     public static void main(String args[])  {
       Scanner in = new Scanner(System.in);
       int n = in.nextInt();
       int m = in.nextInt();
       int r = in.nextInt();
       int min;
       int a;
       for (int i =0; i<n;i++){
              a = in.nextInt();
              if (i==0) min=a;
              else if (a<min) min = a;
       }
       int max;
       for (int i=0; i<m;i++){
              a=in.nextInt();
              if (i==0)max =a;
              else if (a>max)max =a;
       }
       int ko=r/min;
       int r1=ko*max + r%min;
       if (r>= r1) System.out.println(r);
       else System.out.println(r1);
       }
}


import javax.annotation.processing.SupportedSourceVersion;
import java.io.BufferedReader;
import java.io.InputStreamReader;
import java.lang.management.BufferPoolMXBean;
import java.nio.Buffer;
import java.util.Arrays;
import java.util.Scanner;
public class Chess {
    public static void main(String[] args)
    {
        Scanner input = new Scanner(System.in);
        int[] k = new int[3];
        for(int i = 0; i < 3; i++)
        {
            k[i] = input.nextInt();
        }
        int[] m = new int[k[0]];
        for(int i = 0; i<k[0]; i++)
        {
            m[i] = input.nextInt();
        }
        int[] n = new int[k[1]];
        for(int i = 0; i<k[1]; i++)
        {
            n[i] = input.nextInt();
        }
        Arrays.sort(m);
        Arrays.sort(n);
        if(m[0] > n[k[1] -1])
        {
            System.out.println(k[2]);
        }
        else
        {
            int l;
            l = (int) Math.floor(k[2] / m[0]);
            l = l * n[k[1] - 1] + (k[2] - l * m[0]);
            System.out.println(l);
        }
    }


import java.util.*;
public class Main{
  public static void main(String[]args){
  Scanner sc=new Scanner(System.in);
  int n=sc.nextInt();
  int m=sc.nextInt();
  int r=sc.nextInt();

  int min=0;
  for (int i=1;i<=n;i++){
  int s=sc.nextInt();
  if(s<min){
    min=s;

  }
  }
  for

  }
}


import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigDecimal;
import java.util.*;

public class ForcesC {

	public static class FastReader {
		BufferedReader br;
		StringTokenizer st;
		//it reads the data about the specified point and divide the data about it ,it is quite fast
		//than using direct

		public FastReader() {
			br = new BufferedReader(new InputStreamReader(System.in));
		}

		String next() {
			while (st == null || !st.hasMoreTokens()) {
				try {
					st = new StringTokenizer(br.readLine());
				} catch (Exception r) {
					r.printStackTrace();
				}
			}
			return st.nextToken();
		}

		int nextInt() {
			return Integer.parseInt(next());//converts string to integer
		}

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

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

		String nextLine() {
			String str = "";
			try {
				str = br.readLine();
			} catch (Exception r) {
				r.printStackTrace();
			}
			return str;
		}
	}

	public static PrintWriter out = new PrintWriter (new BufferedOutputStream(System.out));
	static long mod = (long)(1e9+7);
	static FastReader sc = new FastReader();
    static List<Integer>[] edge ;
	public static void main(String[] args) {

		 int n = sc.nextInt();
	     int m = sc.nextInt();
	     int r = sc.nextInt();
	     int minn = Integer.MAX_VALUE,maxm = Integer.MIN_VALUE;
	     for(int i=0;i<n;++i) {
	    	 int temp = sc.nextInt();
	    	 minn = Math.min(minn, temp);
	     }
	     int buy = r/minn;
	     for(int i=0;i<n;++i) {
	    	 int temp = sc.nextInt();
	    	 maxm = Math.max(maxm, temp);
	     }
	     int sell = maxm*buy+r%minn;
	     out.println(Math.max(sell, r));
	      out.close();
	    }

	private static void add(TreeMap<Integer, Integer> map, int i) {
		// TODO Auto-generated method stub
		if(map.containsKey(i)) map.put(i, map.get(i)+1);
		else map.put(i, 1);

	}
	private static void delete(TreeMap<Integer, Integer> map, int i) {
		if(map.containsKey(i)) {
			if(map.get(i) == 1) map.remove(i);
			else map.put(i, map.get(i)-1);
		}

	}
	}


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

import rounds.q1.Scanner;

public class q4 {
  public static void main(String[] args) throws IOException {
	  Scanner sc = new Scanner(System.in);

}
  static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;

		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}

		public String next() throws IOException
		{
			while (st == null || !st.hasMoreTokens())
				st = new StringTokenizer(br.readLine());
			return st.nextToken();
		}

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

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

		public String nextLine() throws IOException {return br.readLine();}

		public long nextlong() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			long res = 0, f = 1;
			boolean dec = false, neg = false;
			int start = 0;
			if(x.charAt(0) == '-')
			{
				neg = true;
				start++;
			}
			for(int i = start; i < x.length(); i++)
				if(x.charAt(i) == '.')
				{
					res = Long.parseLong(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Long.parseLong(sb.toString()) / f;
			return res * (neg?-1:1);
		}

		public boolean ready() throws IOException {return br.ready();}

	}
}


/*
 * To change this license header, choose License Headers in Project Properties.
 * To change this template file, choose Tools | Templates
 * and open the template in the editor.
 */

import java.util.Arrays;
import java.util.Scanner;
import java.util.Vector;

/**
 *
 * @author user
 */
public class NewMain3 {

    /**
     * @param args the command line arguments
     */
    public static void main(String[] args) {
       Scanner sc = new Scanner (System.in);
       int n = sc.nextInt();
       int b = sc.nextInt();
       int s[] = new int[n];
       for(int i = 0 ; i < n ; i++){
           s[i] = sc.nextInt();
       }

       int even = 0 , odd = 0 ;
       Vector v = new Vector<>();

       for(int i = 0 ; i < n ; i++)
       {
          if(odd==even && i!=0){
          v.add(Math.abs(s[i] - s[i-1]));
          }
          if(s[i]%2==0)even++;
          else odd++;

       }

       int w []  = new int[v.size()];
       for(int i = 0 ; i < v.size() ; i++)
       {
           w[i] = (int)(v.get(i)) ;
       }

       Arrays.sort(w);
       int  counter =0 ;
       for(int i = 0 ; i < w.length ; i++)
       {
             if(w[i] =< b){b-=w[i]; counter++;}
             else{break;}
       }
        System.out.println(counter);
    }

}


public class pdd {
     public static void main(String[] args) {
        // TODO code application logic here
       Vector<Integer> v =new Vector<Integer>();
       v.add(Integer.SIZE);
       Scanner in=new Scanner(System.in);
       int n=in.nextInt();
       int c=in.nextInt();
        int a[][]=new int[n][2];
         int arr[]=new int[n];
         for(int i=0;i<n;i++)
         {arr[i]=in.nextInt();

         }

       for(int i=0;i<n-1;i++)
       a[i][arr[i]%2]++;
       for(int i=0;i<n-1;i++)
       {
       if(a[i][0]==a[i][1]&&a[n-1][0]==a[n-1][1])
       {
       v.add(Math.abs(arr[i]-arr[i+1]));
       }
       }
       Object b[]=new Object[v.size()];
     b=  v.toArray();
    Arrays.sort(b);
    int count=0;
      for(int i=0;i<n;i++)
      {if(c-(int)b[i]>0)
      count++;
      }

         System.out.println(count);
    }
}


package cut;

import java.io.*; import java.math.*; import java.text.*; import java.util.*; import java.util.regex.*; public class Solution { static class InputReader 	{ 	 private final InputStream stream; 	 private final byte[] buf = new byte[8192]; 	 private int curChar, snumChars; 	 public InputReader(InputStream st) { 	 this.stream = st; 	 } 	 public int read() { 	 if (snumChars == -1) 	 throw new InputMismatchException(); 	 if (curChar >= snumChars) { 	 curChar = 0; 	 try { 	 snumChars = stream.read(buf); 	 } catch (IOException e) { 	 throw new InputMismatchException(); 	 } 	 if (snumChars <= 0) 	 return -1; 	 } 	 return buf[curChar++]; 	 } 	 public int nextInt() { 	 int c = read(); 	 while (isSpaceChar(c)) { 	 c = read(); 	 } 	 int sgn = 1; 	 if (c == '-') { 	 sgn = -1; 	 c = read(); 	 } 	 int res = 0; 	 do { 	 res *= 10; 	 res += c - '0'; 	 c = read(); 	 } while (!isSpaceChar(c)); 	 return res * sgn; 	 } 	 public long nextLong() { 	 int c = read(); 	 while (isSpaceChar(c)) { 	 c = read(); 	 } 	 int sgn = 1; 	 if (c == '-') { 	 sgn = -1; 	 c = read(); 	 } 	 long res = 0; 	 do { 	 res *= 10; 	 res += c - '0'; 	 c = read(); 	 } while (!isSpaceChar(c)); 	 return res * sgn; 	 } 	 public int[] nextIntArray(int n) { 	 int a[] = new int[n]; 	 for (int i = 0; i < n; i++) { 	 a[i] = nextInt(); 	 } 	 return a; 	 } 	 public String readString() { 	 int c = read(); 	 while (isSpaceChar(c)) { 	 c = read(); 	 } 	 StringBuilder res = new StringBuilder(); 	 do { 	 res.appendCodePoint(c); 	 c = read(); 	 } while (!isSpaceChar(c)); 	 return res.toString(); 	 } 	 public String nextLine() { 	 int c = read(); 	 while (isSpaceChar(c)) 	 c = read(); 	 StringBuilder res = new StringBuilder(); 	 do { 	 res.appendCodePoint(c); 	 c = read(); 	 } while (!isEndOfLine(c)); 	 return res.toString(); 	 } 	 public boolean isSpaceChar(int c) { 	 return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1; 	 } 	 private boolean isEndOfLine(int c) { 	 return c == '\n' || c == '\r' || c == -1; 	 } 	} /*static class node implements Comparable<node> { int index; int val; node(int a1,int a2) { index=a1; val=a2; } public int compareTo(node n1) { return(this.val-n1.val); } }*/ public static void main(String[] args) throws IOException { InputReader in=new InputReader(System.in); int n=in.nextInt(); int b=in.nextInt(); int [] a=new int[n]; a=in.nextIntArray(n); int[] odd=new int[n+1]; int[] even=new int[n+1]; odd[0]=0; even[0]=0; for(int i=1;i<=n;i++) { if(a[i-1]%2==1) { odd[i]=odd[i-1]+1; even[i]=even[i-1]; } else { odd[i]=odd[i-1]; even[i]=even[i-1]+1; } } int prev=0; PriorityQueue<Integer> cost=new PriorityQueue<Integer>(); for(int i=1;i<=n-1;i++) { int oc=odd[i]-odd[prev]; int ec=even[i]-even[prev]; if(oc==ec) { cost.add((int)Math.abs(a[i]-a[i-1])); //System.out.println((int)Math.abs(a[i]-a[i-1])); prev=i; } } int sum=0; int count=0; while(!cost.isEmpty() && sum<=b) { sum+=cost.peek().intValue(); cost.poll(); count++; } if(count==0) { System.out.println("0"); } else { if(cost.isEmpty() && sum<=b) { System.out.println(count); } else { System.out.println(count-1); } } } }


public class A {
    public void run() {
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        int n = s.length();
        String[] ss = new String[n];
        for (int i = 0; i < n; i++)
            ss[i] = s.substring(i);
        sort(ss);
        int res = 0;
        for (int i = 1; i < n; i++)
            res = max(res, count(ss[i - 1], ss[i]));
        System.out.println(res);
    }

    int count(String s, String t) {
        int ret = 0;
        for (int i = 0; i < min(s.length(), t.length()); i++)
            if (s.charAt(i) != t.charAt(i))
                return ret;
            else
                ret++;
        return ret;
    }

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

    public static void main(String... args) {
        new A().run();
    }
}


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

public class Main {
    public static void main(String ...args) throws Throwable {
        Scanner in = new Scanner(System.in);
        String init = in.nextLine();
        HashSet<String> h = new HashSet<String>();
        for (int len = init.length() - 1; len >= 1; --len)  {
            h.clear();
            for (int pos = 0; pos + len <= init.length(); ++pos) {
                String now = init.substring(pos, pos + len);
                if (h.contains(now)) {
                    System.out.println(len);
                    return;
                }
                h.put(now);
            }

        }

        System.out.println(0);
    }
}


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

public class String {
        public static void main(String[] args) {
                Scanner sc = new Scanner(new BufferedReader(new InputStreamReader(System.in)));
                String s = sc.next();
                int[] alphabet = new int[26];

                for(int i = 0; i < s.length(); i++) {
                        alphabet[s.charAt(i)-97]++;
                }

                int max = alphabet[0];
                for(int i = 0; i < alphabet.length; i++)
                        if(alphabet[i] > max) max = alphabet[i];
                System.out.println(max);
        }
}


public class OverlapedString {
	public static void main(String args[]) {
		OverlapedString os = new OverlapedString();
		System.out.println(os.handleOverlap(args[0]));
	}
	private int handleOverlap(String str) {
		int len = str.length();
		int count = 0;
		for(int i=0;i<len;i++)
			for(int j=i+1;j<len;j++) {
				String _tmp = str.substring(i,j);
				if(_tmp!=null&&_tmp.length()>0) {
					if(getOverlapCount(str,_tmp)>1)
					{
						if(_tmp.length()>count)
							count = _tmp.length();
					}
				}
			}
		return count;
	}
	private int getOverlapCount(String str,String sub) {
		int start = 0;
		int count = 0;
		while(start<str.length()) {
			start = str.indexOf(sub,start);
			if(start==-1)
				break;
			else {
				start++;
				count++;
			}
		}
		return count;
	}
}


import java.io.BufferedInputStream;
import java.util.Scanner;

public class Train { //Round #68 - Train
	public static void main(String[] args) {
		Scanner sc = new Scanner(new BufferedInputStream(System.in));

		int numWagons = sc.nextInt();
		int stowAwayPos = sc.nextInt();
		int controllerPos = sc.nextInt();

		sc.skip("\n");
		String initialDirection = sc.nextLine();
		boolean toHead = initialDirection.contains("head");

		String trainStates = sc.next();

		boolean controllerWon = false;

		for(int i = 0; i < trainStates.length() - 1; i++) {
			if(trainStates.charAt(i) == '0') { //Moving
				if(stowAwayPos > controllerPos) {
					if(stowAwayPos < numWagons) {
						stowAwayPos++;
					}
				} else {
					if(stowAwayPos > 1) {
						stowAwayPos--;
					}
				}

				if(toHead) {
					controllerPos--;
				} else {
					controllerPos++;
				}
			} else { //Standing still
				//Stowaway leaves the train

				if(toHead) {
					controllerPos--;
				} else {
					controllerPos++;
				}

				if(!toHead) {
					if(controllerPos > 1) {
						stowAwayPos = 1;
					} else {
						stowAwayPos = numWagons;
					}
				} else {
					if(controllerPos < numWagons) {
						stowAwayPos = numWagons;
					} else {
						stowAwayPos = 1;
					}
				}
			}

			if(toHead && controllerPos == 1) {
				toHead = !toHead;
			} else if(!toHead && controllerPos == numWagons) {
				toHead = !toHead;
			}

			//System.out.println(stowAwayPos + " " + controllerPos);

			if(stowAwayPos == controllerPos) {
				System.out.println("Controller " + (i+1));
				controllerWon = true;
				break;
			}
		}

		if(!controllerWon) {
			System.out.println("Stowaway");
		}
	}
}


import java.io.*;
import java.util.*;
public class train
{
	public static void main(String[] Args)
	{
		Scanner p = new Scanner(System.in);
		int n=p.nextInt();
		int me=p.nextInt();
		int tt=p.nextInt();
		Scanner pp=new Scanner(System.in);
		String move=pp.nextLine();
		String Schedule= pp.nextLine();
		char minute[]= new char[Schedule.length()];
		int ttmove=0;
		if(move.charAt(3)=='h')
		{
			ttmove=-1;
		}
		else
		{
			ttmove=1;
		}
		int c=0;
		while((c<Schedule.length())&&(me!=tt))
		{
			if(Schedule.charAt(c)=='0')
			{
				if(me>tt)
				{
					if(me!=n)
					{
						me++;
					}
					else
					{
						if((me-1)!=tt)
						{
							;
						}
					}
				}
				else
				{
					if(me!=1)
					{
						me--;
					}
					else
					{
						;
					}
				}
			}
			else
			{
				if((ttmove==1)&&(tt!=1))
				{
					me=tt-1;
				}
				else if((ttmove==-1)&&(tt!=n))
				{
					me=tt+1;
				}
				else
				{
					me+=ttmove;
				}
			}
			c++;
			tt+=ttmove;
			if(tt==n)
			{
				ttmove=-1;
			}
			else if(tt==1)
			{
				ttmove=1;
			}
		}
		if(c==Schedule.length())
		{
			System.out.println("Stowaway");
		}
		else
		{
			System.out.println("Controller "+c);
		}
	}
}


/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package srm68;

import java.util.Scanner;

/**
 *
 * @author dody
 */
public class ProbB {
    int n,c,s;
    String dir;

    public void moveC(){
        if(dir.equals("to head") && n !=1)
                c--;
            else if(n != 1)
                c++;

            if(c == 0){
                c = 2;
                dir = "to tail";
            }
            if(c == n + 1){
                c = n-1;
                dir = "to head";
            }
    }

    public void moveS(){
        int r = Math.abs(c-(s+1));
        int l = Math.abs(c-(s-1));
        if(r > l){
            if(s+1 <= n )
                s++;
        }else{
            if(s-1 > 0)
                s--;
        }
    }

    public void enterTrain(){
        if(dir.equals("to head")){
            if(c != n)
                s = n;
            else
                s = 1;
        }else{
            if(c != 1)
                s = 1;
            else
                s = n;
        }
    }
    public void run(){
        Scanner scanner = new Scanner(System.in);
        n = scanner.nextInt();
        s = scanner.nextInt();
        c = scanner.nextInt();
        scanner.nextLine();
        dir = scanner.nextLine();
        String timeLine = scanner.nextLine();

        for (int i = 0; i < timeLine.length(); i++) {
            if(timeLine.charAt(i) == '0'){
                moveS();
                moveC();
                if(c == s){
                    System.out.println("Controller "+(i+1));
                    return;
                }

            }else{
                s = -1;
                moveC();
                enterTrain();
                if(c == s){
                    System.out.println("Controller "+(i+1));
                    return;
                }
            }
        }
        System.out.println("Stowaway");
    }
    public static void main(String[] args){
        new ProbB().run();
    }
}


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

public class Main {

    public static void main(String args[]){
        Scanner in = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        StringTokenizer s = new StringTokenizer(in.nextLine());
        int n = Integer.parseInt(s.nextToken()), passenger=Integer.parseInt(s.nextToken()),
                controller=Integer.parseInt(s.nextToken());

        boolean napravl = in.nextLine().equals("to tail");
        char[] sost = in.nextLine().toCharArray();
        int ans=-1;

        for(int i=1; i<=sost.length; i++){
            boolean que=(sost[i-1] == '0');
            if(que){
                if(controller>passenger){
                    if(passenger!=1)
                        passenger--;
                    if(napravl){
                        if(controller==n){
                            napravl=!napravl;
                            controller--;
                        }
                        else controller++;
                        if(passenger==controller){
                            ans=i;
                            break;
                        }
                    }
                    else{
                        if(controller==1){
                            napravl=!napravl;
                            controller++;
                        }
                        else controller--;
                        if(passenger==controller){
                            ans=i;
                            break;
                        }
                    }
                }
                else{
                    if(passenger!=n)
                        passenger++;
                    if(napravl){
                        if(controller==n){
                            napravl=!napravl;
                            controller--;
                        }
                        else controller++;
                        if(passenger==controller){
                            ans=i;
                            break;
                        }
                    }
                    else{
                        if(controller==1){
                            napravl=!napravl;
                            controller++;
                        }
                        else controller--;
                        if(passenger==controller){
                            ans=i;
                            break;
                        }
                    }
                }
            }
            else{
                if(napravl){
                    if(controller==n){
                        controller--;
                        napravl=!napravl;
                    }
                    else{
                        controller++;
                    }
                    if(napravl) passenger=1;
                    else passenger=n;
                }
                else{
                    if(controller==1){
                        controller++;
                        napravl=!napravl;
                    }
                    else{
                        controller--;
                    }
                    if(!napravl) passenger=1;
                    else passenger=n;
                }
            }
        }
        if(ans==-1&&n!=2)
            out.print("Stowaway");
        else{
            out.print("Controller ");
            if(n==2){
                int j=0;
                while(sost[j]!='0')
                    j++;
                out.print(j+1);
            }
            else
            out.print(ans);
        }

        out.close();
    }
}


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

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);
		Solver solver = new Solver();
		solver.solve(in, out);
		out.close();
	}
}

class Solver {
	int mn = Integer.MAX_VALUE;
	int MAX = 105;
	public void solve(InputReader in, PrintWriter out) {
		int hy = in.nextInt();
		int ay = in.nextInt();
		int dy = in.nextInt();
		int hm = in.nextInt();
		int am = in.nextInt();
		int dm = in.nextInt();
		int hc = in.nextInt();
		int ac = in.nextInt();
		int dc = in.nextInt();
		for (int dh = 0; dh < MAX; dh++) {
			for (int da = 0; da < MAX; da++) {
				for (int dd = 0; dd < MAX; dd++) {
					int hn = hy + dh;
					int an = ay + da;
					int dn = dy + dd;
					int damy = Math.max(an - dm, 0);
					int damm = Math.max(am - dn, 0);
					if (damy == 0)
						continue;
					int num = (hm + damy - 1)/ damy;
					if (hn - damm * num > 0) {
						mn = Math.min(mn, dh * hc + da * ac + dd * dc);
					}
				}
			}
		}
		out.println(mn);

	}
}

class InputReader {
	private BufferedReader reader;
	private StringTokenizer tokenizer;

	public InputReader(InputStream stream) {
		reader = new BufferedReader(new InputStreamReader(stream));
		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 long nextLong() {
		return Long.parseLong(next());
	}

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

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


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

public class A {

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

    void solve() throws IOException {
        int h1 = nextInt();
        int atk1 = nextInt();
        int def1 = nextInt();
        int h2 = nextInt();
        int atk2 = nextInt();
        int def2 = nextInt();
        int ch = nextInt();
        int cAtk = nextInt();
        int cDef = nextInt();

        int ans = Integer.MAX_VALUE / 2;

        for (int bH = 0; bH < 200; bH++) {
            for (int bAtk = 0; bAtk < 200; bAtk++) {
                for (int bDef = 0; bDef < 200; bDef++) {
                    if (win(h1 + bH, atk1 + bAtk, def1 + bDef, h2, atk2, def2)) {
                        ans = Math
                                .min(ans, bH * ch + bAtk * cAtk + bDef * cDef);
                        break;
                    }
                }
            }
        }
        out.println(ans);
    }

    boolean win(int h1, int atk1, int def1, int h2, int atk2, int def2) {
        int dmg1 = Math.max(atk1 - def2, 0);
        int dmg2 = Math.max(atk2 - def1, 0);
        if (dmg1 == 0) {
            return false;
        }
        if (dmg2 == 0) {
            return true;
        }
        int need = (h2 + dmg1 - 1) / dmg1;
        return h1 - need * dmg2 > 0;
    }

    A() throws IOException {
        br = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(System.out);
        solve();
        out.close();
    }

    public static void main(String[] args) throws IOException {
        new A();
    }

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

    String nextString() {
        try {
            return br.readLine();
        } catch (IOException e) {
            eof = true;
            return null;
        }
    }

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

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

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


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

public class Main
{
    public static void main(String[] args) throws IOException
    {
        Scanner scan = new Scanner(System.in);

        int hp = scan.nextInt();
        int atk = scan.nextInt();
        int def = scan.nextInt();

        int hpE = scan.nextInt();
        int atkE = scan.nextInt();
        int defE = scan.nextInt();

        int perHp = scan.nextInt();
        int perAtk = scan.nextInt();
        int perDef = scan.nextInt();

        int res = Integer.MAX_VALUE/2;

        for(int i = 0;i <= 200;i++)
        {
            hp += i;
            for(int j = 0;j <= 200;j++)
            {
                atk += j;
                for(int k = 0;k <= 200;k++)
                {
                    def += k;

                    int monsterDec = Math.max(0, atk-defE);
                    int myDec = Math.max(0, atkE-def);

                    int t1 = monsterDec == 0 ? Integer.MAX_VALUE/2 : (hpE/monsterDec);
                    if(monsterDec != 0 && hpE%monsterDec != 0)
                        t1++;

                    int t2 = myDec == 0 ? Integer.MAX_VALUE/2-1 : (hp/myDec);
                    if(myDec != 0 && hp%myDec == 0)
                        t2--;

                    if(t2 >= t1)
                        if(res > i*perHp + j*perAtk + k*perDef)
                            res = i*perHp + j*perAtk + k*perDef;

                    def -= k;
                }
                atk -= j;
            }
            hp -= i;
        }

        System.out.println(res);
    }
}


import java.awt.*;
import java.io.*;
import java.math.*;
import java.util.*;
import java.util.Map.Entry;

import static java.lang.Math.*;

public class solver implements Runnable {
	final boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;
	BufferedReader in;
	PrintWriter out;
	StringTokenizer tok = new StringTokenizer("");

	boolean HasTokens() {
		while (!tok.hasMoreTokens()) {
			try {
				tok = new StringTokenizer(in.readLine());
			} catch (Exception e) {
				return false;
			}
		}
		return true;
	}

	String readString() throws IOException {
		return HasTokens() ? tok.nextToken() : null;
	}

	String readString(String delim) throws IOException {
		return HasTokens() ? tok.nextToken(delim) : null;
	}

	int readInt() throws IOException {
		return Integer.parseInt(readString());
	}

	long readLong() throws IOException {
		return Long.parseLong(readString());
	}

	double readDouble() throws IOException {
		return Double.parseDouble(readString());
	}

	char readChar() throws IOException {
		char val = 0;
		do {
			val = (char) in.read();
		} while (val == '\n' || val == '\r');
		return val;
	}

	// ----------------------------------
	int gcd(int x, int y) {
		while (y != 0) {
			int temp = x % y;
			x = y;
			y = temp;
		}
		return x;
	}

	// ----------------------------------

	public class Pair<T1, T2> {
		public T1 x1;
		public T2 x2;

		public Pair() {
		};

		public Pair(T1 x1, T2 x2) {
			this.x1 = x1;
			this.x2 = x2;
		}

		public String toString() {
			return x1 + ":" + x2;
		}
	}

	public class Three implements Comparable<Three> {
		public int x1, x2, x3;

		public Three() {
		}

		public Three(int a, int b, int c) {
			x1 = a;
			x2 = b;
			x3 = c;
		}

		public int compareTo(Three o) {//
			if (x1 == o.x1 && x2 == o.x2)
				return x3 - o.x3;
			if (x1 == o.x1)
				return x2 - o.x2;
			return (x1 - o.x1);
			// (x1-o.x1) - increase; -(x1-o.x1) - decrease
		}

		public String toString() {
			return x1 + ":" + x2 + ":" + x3;
		}
	}

	// ----------------------------------------

	boolean win(int h, int a,int d,int hm,int am,int dm){
		int cnt = 0;
		int delta1 = Math.max(0, am - d);
		int delta2 = Math.max(0, a - dm);
		while (h > 0 || hm > 0){
			if (cnt == 110) return false;
			if (h - delta1*10 > 0){
				cnt+=10;
				h-= delta1*10;
				hm -= delta2*10;
			}else{
				cnt++;
				h -= delta1;
				hm -= delta2;
			}
			if (h <= 0) return false;
			if (hm <= 0  && h > 0 ) return true;
		}
		return false;
	}

	void solve() throws NumberFormatException, IOException {
		int hpy = readInt();
		int atky = readInt();
		int defy = readInt();

		int hpm = readInt();
		int atkm = readInt();
		int defm = readInt();

		int x = readInt();
		int y = readInt();
		int z = readInt();

		int cost = Integer.MAX_VALUE;

		for (int i=0;i<=100;i++){
			for (int j=0;j<=100;j++){
				for (int k=0;k<=100;k++){
					if (win(hpy+i,atky+j,defy+k,hpm,atkm,defm)){
						cost = Math.min(cost, i*x+j*y+k*z);
					}
				}
			}
		}

		out.println(cost);

	}

	// ----------------------------------------
	public static void main(String[] args) {
		new Thread(null, new solver(), "", 256 * (1L << 20)).start();
	}

	public void run() {
		try {
			timeBegin = System.currentTimeMillis();
			try {
				if (ONLINE_JUDGE) {
					in = new BufferedReader(new InputStreamReader(System.in));
					out = new PrintWriter(System.out);
					//in = new BufferedReader(new FileReader("exam.in"));
					//out = new PrintWriter("exam.out");
				} else {
					in = new BufferedReader(new FileReader("input.txt"));
					out = new PrintWriter("output.txt");
				}
			} catch (Throwable e) {
				in = new BufferedReader(new InputStreamReader(System.in));
				out = new PrintWriter(System.out);
			}
			solve();
			out.close();

			timeEnd = System.currentTimeMillis();
			if (!ONLINE_JUDGE)System.err.println("Time = " + (timeEnd - timeBegin));
		} catch (Exception e) {
			e.printStackTrace(System.err);
			System.exit(-1);
		}
	}

	Random r = new Random();

	long timeBegin, timeEnd;

	// ----------
}


package B;
import java.io.*;
import java.util.*;
public class Main {

	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String s=sc.next();
		int flag1=0;
		int flag2=0;
		int flag3=0;
		int max=-1;
		int cur=0;
		int cur2=0;
		int number=0;
		boolean start=false;
		for(int i=0;i<n;i++){

			if(flag2==0){
				if(isAlpha(s.charAt(i))){
					cur++;
					//System.out.println(cur);
				}
				if(cur>0&&s.charAt(i)=='_'){
					max=Math.max(max, cur);
					cur=0;
				}
				if(cur>0&&s.charAt(i)=='('){
					max=Math.max(max, cur);
					cur=0;
				}

				}
		    if(flag2==1){
		    	if(isAlpha(s.charAt(i))){
		    		cur2++;
		    	}
		    	if(s.charAt(i)=='_'||s.charAt(i)==')'){
		    		if(cur2>0){
		    			number++;
		    			cur2=0;
		    		}
		    	if(s.charAt(i)==')'){
		    		flag2=0;
		    	}
		    	}
		    }
		    if(s.charAt(i)=='('){
				flag2=1;
			}

		}
		if(cur>0){
			max=Math.max(max, cur);
			cur=0;
		}
		if(max==-1){
			System.out.print(0+" ");
		}
		else
		System.out.print(max+" ");
		System.out.println(number);
	}
static boolean isAlpha(char a){
	if((a>='A'&&a<='Z')||(a>='a'&&a<='z')){
		return true;
	}
	else
		return false;
}
}package B;
import java.io.*;
import java.util.*;
public class Main {

	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		int n=sc.nextInt();
		String s=sc.next();
		int flag1=0;
		int flag2=0;
		int flag3=0;
		int max=-1;
		int cur=0;
		int cur2=0;
		int number=0;
		boolean start=false;
		for(int i=0;i<n;i++){

			if(flag2==0){
				if(isAlpha(s.charAt(i))){
					cur++;
					//System.out.println(cur);
				}
				if(cur>0&&s.charAt(i)=='_'){
					max=Math.max(max, cur);
					cur=0;
				}
				if(cur>0&&s.charAt(i)=='('){
					max=Math.max(max, cur);
					cur=0;
				}

				}
		    if(flag2==1){
		    	if(isAlpha(s.charAt(i))){
		    		cur2++;
		    	}
		    	if(s.charAt(i)=='_'||s.charAt(i)==')'){
		    		if(cur2>0){
		    			number++;
		    			cur2=0;
		    		}
		    	if(s.charAt(i)==')'){
		    		flag2=0;
		    	}
		    	}
		    }
		    if(s.charAt(i)=='('){
				flag2=1;
			}

		}
		if(cur>0){
			max=Math.max(max, cur);
			cur=0;
		}
		if(max==-1){
			System.out.print(0+" ");
		}
		else
		System.out.print(max+" ");
		System.out.println(number);
	}
static boolean isAlpha(char a){
	if((a>='A'&&a<='Z')||(a>='a'&&a<='z')){
		return true;
	}
	else
		return false;
}
}


//Thanks to Valeh :D

public class TextDocumentAnalysis {
    public static void main(String[] args){
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        String s = sc.next();
        s.toLowerCase();
        int maxL = -1;
        int nwi = 0;
        int fp = 0;
        int fw = 0;
        for(int i=0;i<n;i++){
            char c = s.charAt(i);
            if(c == '(') {fp++;fw=0;}
            else if(c == ')') {
                if(fp == 1 && fw != 0) nwi++;
                fp--;fw=0;
            }
            else if(c == '_') {
                if(fp == 1 && fw != 0) nwi++;
                fw=0;
            }
            else {
                fw++;
            }
            if(fp==0) maxL = Math.max(fw, maxL);
        }
        System.out.println(maxL + " " + nwi);
    }
}


import java.io.*;
public class test
{

	public static void main(String args[])throws IOException
	{
		int len,cin=0,cout=0,j=0,i=0,c=0,n;
		char ch,ch1;
		DataInputStream d =new DataInputStream(System.in);
		n=Integer.parseInt(d.readLine());
		String str=d.readLine();
		len=n;
		str=str+"  ";
		while(i<len)
		{
			ch=str.charAt(i);
			if(ch=='(')
			{
				j=i+1;
				while((ch1=str.charAt(j)) !=')')
				{
					if(ch1 != '_')
						c++;
					else
					{
						if(c!=0)
							cin++;
						c=0;
					}
					j++;
				}
				i=j+1;
				if(c!=0)
				{
					cin++;
					c=0;
				}
			}
			else
			{
			if((ch!='_' ) )
				c++;
			if((ch=='_') ||(ch1=str.charAt(i+1))!='('))
			{
				if(c>=cout)
					cout=c;
				c=0;
			}
			i++;
			}

			}
		if(c>cout)
		{
			cout=c;
			c=0;
		}
		System.out.print(cout+" "+cin);
	}

}


import java.util.Scanner;

public class B375 {

    public static void main(String[] args){

        Scanner sc = new Scanner(System.in);
        String count = sc.nextLine();
        String str = sc.nextLine();
        char prev ='.';
        boolean openParenth = false;
        int maxSize = 0;
        int wordCount = 0;
        int iter=0;
        while(iter <str.length() ){
            if(str.charAt(iter) =='(') {
                openParenth = true;
            }
            else if(str.charAt(iter) == ')'){
                openParenth = false;
            }
            else if(!openParenth && Character.isAlphabetic(str.charAt(iter))){
                int tempLength = 0;
                while(Character.isAlphabetic(str.charAt(iter))) {
                    tempLength++;
                    iter++;
                }
                iter--;
                maxSize = Math.max(maxSize,tempLength);
            }
            else if( openParenth && Character.isAlphabetic(str.charAt(iter))
                && !Character.isAlphabetic(str.charAt(iter-1)) ){
                wordCount++;
            }

            iter++;
        }
        System.out.print(maxSize+" "+wordCount);

    }


import java.io.BufferedReader;

public class Main {

    public static void main(String args[]){
        Scanner sc = new Scanner(System.in);
        String s = sc.next();
        int x = sc.nextInt();
        int algarisms[] = new int[s.length()];
        int nAlgarisms=s.length();

        for(int i=0; i<s.length(); i++){
            algarisms[i] = Character.digit(s.charAt(i), 10);
        }

        //System.out.println(Arrays.toString(algarisms));

        int i=0;
        int subArray[] = new int[x+1];

        while(x>0 && i<algarisms.length-1){
            subArray = getSubArray(algarisms, i, x);

            int maxIndex = getMaxIndexArray(subArray);
            x -= maxIndex;
            for(int j=maxIndex; j>0; j--){
                int temp=algarisms[i+j];
                algarisms[i+j]=algarisms[i+j-1];
                algarisms[i+j-1]=temp;
            }
            i++;
            subArray = new int[x+1];

        }

        double result=0;
        for(int j=nAlgarisms-1; j>=0; j--){
            result+=Math.pow(10,j)*(double)(algarisms[nAlgarisms-1-j]);
        }
        System.out.println(String.format("%.0f",result));
        //System.out.println(result);
        //System.out.println(Arrays.toString(algarisms));

    }

    public static int getMaxIndexArray(int array[]){
        int max = 0;
        int index = 0;
        for(int i=0; i<array.length; i++){
            //In case of draw, will return the first index
            if(array[i]>max){
                max=array[i];
                index=i;
            }
        }

        return index;
    }

    public static int[] getSubArray(int array[], int startIndex, int plus){
        int newArray[] = new int[plus+1];
        int endIndex = startIndex+plus<array.length? startIndex+plus:array.length-1;

        for(int i=startIndex; i<=endIndex; i++){
            newArray[i-startIndex] = array[i];
        }

        return newArray;
    }
}


/**
 * Ashesh Vidyut (Drift King) *
 */
public class B {
    public static void main(String[] args) {
        try {
            BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
            String ak[] = (in.readLine()).split(" ");
            int num[] = new int[ak[0].length()];
            int k = Integer.parseInt(ak[1]);
            for (int i = 0; i < num.length; i++) {
                num[i] = Integer.parseInt(Character.toString(ak[0].charAt(i)));
            }
            for (int i = 0; i < num.length; i++) {
                if(num[i] == 9){
                    continue;
                }
                int maxv = num[i];
                int maxind = i;
                if(k <=0 ){
                    break;
                }
                if(i+1 < num.length){
                    for (int j = i+1; j < Math.min(num.length, i+k+1); j++) {
                        if(maxv < num[j]){
                            maxv = num[j];
                            maxind = j;
                        }
                    }
                    if(maxv == num[i]){
                        continue;
                    }
                    int noswap = maxind - i;
                    if(k >= noswap){
                        k -= noswap;
                        int tmp = num[i];
                        num[i] = maxv;
                        for (int j = i+1; j <= maxind; j++) {
                            int tmp2 = tmp;
                            tmp = num[j];
                            num[j] = tmp2;
                        }
                    }
                }
            }
            StringBuilder res = new StringBuilder("");
            for (int i = 0; i < num.length; i++) {
                res.append(num[i]);
            }
            System.out.println(res);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
    }
}


import com.sun.tools.javac.resources.legacy;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;

/**
 * @author arshsab
 * @since 05 2014
 */

public class PashaMaximizes {
    public static void main(String... args) throws IOException {
        BufferedReader br = new BufferedReader(new InputStreamReader(System.in));

        String[] log = br.readLine().split(" ");

        final char[] A = log[0].toCharArray();
        int K = Integer.parseInt(log[1]);

        for (int i = 0; i < A.length && K > 0; i++) {
            int max = Integer.MIN_VALUE;
            int maxPos = -1;

            for (int j = i; j < A.length && j <= K + i; j++) {
                int fixed = A[j] - '0';

                if (fixed > max) {
                    max = fixed;
                    maxPos = j;
                }
            }

            if (max > A[i] - '0') {
                for (int j = maxPos - 1; j >= i; j--) {
                    A[j + 1] = A[j];
                }

                A[i] = (char) (max + '0');
                K -= maxPos - i;
            }
        }

        System.out.println(new String(A));
    }
}


//package contest;

import java.util.*;

public class test {
    public static String num;

    public static void main(String[] args) {
        // Scanner sc = new Scanner(System.in);
        // String line = sc.nextLine();
        // String[] str = line.split(" ");
        // num = str[0];
        // int []sorted = new int[num.length()];
        // Arrays.sort(sorted);
        // int swaps = Integer.parseInt(str[1]);

        // int nextMax;
        // while (swaps != 0) {
        // int max =0;
        // int maxPos=0;
        // int start=0;
        // for (int i = start; i < num.length() && i < swaps; i++) {
        // int current = Integer.parseInt(num.charAt(i) + "");
        // if(current > max){
        // max = current;
        // maxPos=i;
        // }
        // }//end for.
        // int newSwaps = swap(maxPos,swaps);
        // int diff= swaps -newSwaps;
        // swaps = newSwaps;
        // start = maxPos-diff+1;
        // System.out.println(start);
        // }//end while.
        // System.out.println(num);

        // num ="12345678";
        // swap(7,8);
        // System.out.println(num);

        Scanner sc = new Scanner(System.in);
        String line = sc.nextLine();
        String[] str = line.split(" ");
        num = str[0];
        // int []sorted = new int[num.length()];
        // Arrays.sort(sorted);
        int swaps = Integer.parseInt(str[1]);
        Queue<Integer> pq = new LinkedList<Integer>();

        // int loopNum=9;
        // while(loopNum>0){
        // for(int i=0;i<num.length();i++){
        // int number = Integer.parseInt(num.charAt(i)+"");
        // if(number==loopNum){
        // System.out.println(num.charAt(i)+" , "+i);
        // pq.add(i);
        // }
        // }
        // loopNum--;
        // }
        if (num.length() == 1) {
            System.out.println(nums);
        } else {
            int start = 0;
            while (swaps > 0) {
                // System.out.println("swaps = "+swaps);
                int loopNum = 9;
                pq = new LinkedList<Integer>();
                while (loopNum >= 0) {
                    for (int i = start; i < num.length()
                            && i <= (swaps + start); i++) {
                        // System.out.println(i+"    /////////////////////");
                        int number = Integer.parseInt(num.charAt(i) + "");
                        if (number == loopNum) {
                            // System.out.println(num.charAt(i)+" , "+i);
                            pq.add(i);
                        }
                    }
                    loopNum--;
                    // System.out.println(loopNum+"--------------------------");
                }// end while

                int next = pq.poll();
                // System.out.println(next);
                int newSwaps = swap(next, swaps);
                int diff = swaps - newSwaps;
                swaps = newSwaps;
                start = next - diff + 1;
                // System.out.println("start = "+start);
            }
            System.out.println(num);
        }
    }// end main

    public static int swap(int pos, int swaps) {
        // System.out.println(pos +" , "+swaps );
        int number = Integer.parseInt(num.charAt(pos) + "");
        int newPos = pos - 1;
        while ((newPos >= 0)
                && Integer.parseInt(num.charAt(newPos) + "") < number
                && swaps > 0) {
            swaps--;
            newPos--;

        }
        String newNum = "";
        for (int j = 0; j <= newPos; j++) {
            newNum += num.charAt(j);
        }
        newNum += number;
        for (int j = newPos + 1; j < pos; j++) {
            newNum += num.charAt(j);
        }
        for (int j = pos + 1; j < num.length(); j++) {
            newNum += num.charAt(j);
        }
        num = newNum;
        return swaps;
    }
}// end class
// 9090000078001234 6


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

public class icpc
{
    public static void main(String[] args) throws IOException
    {
        Reader in = new Reader();
//        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));

        long M = 1000000009;
        long n = in.nextLong();
        long m = in.nextLong();
        long k = in.nextLong();
        long score = 0L;
        long threshold1 = (long)Math.floor((double)n / k) * (k - 1) + (n % k);
        if (m <= threshold1)
            System.out.println(m % M);
        else
        {
            long cutPoint = binarySearch(n, k, m);
            BigInteger b1 = BigInteger.TWO.pow((int)cutPoint + 1).subtract(BigInteger.TWO).multiply(BigInteger.valueOf(k));
            BigInteger b2 = BigInteger.valueOf(m).subtract(BigInteger.valueOf(k).multiply(BigInteger.valueOf(cutPoint)));
            b1 = b1.add(b2);
            b1 = b1.mod(BigInteger.valueOf(M));
            System.out.println(b1.intValue());
        }

    }
    public static long getValue(long n, long k)
    {
        return (long)Math.floor((double)n / k) * (k - 1) + (n % k);
    }
    public static long binarySearch(long n, long k, long m)
    {
        long l = 0;
        long ans = Long.MAX_VALUE;
        long r = (long)Math.floor((double)n / k);
        while (l <= r)
        {
            long mid = (l + r) / 2;
            if (check(n, mid, m, k))
            {
                ans = Math.min(ans, mid);
                r = mid - 1;
            }
            else
                l = mid + 1;
        }
        return ans;
    }
    public static boolean check(long n, long i, long m, long k)
    {
        if(i * k + getValue(n - i * k, k) >= m)
            return true;
        return false;
    }
}
class NumberTheory
{
    public boolean isPrime(long n)
    {
        if(n < 2)
            return false;
        for(long x = 2;x * x <= n;x++)
        {
            if(n % x == 0)
                return false;
        }
        return true;
    }
    public ArrayList<Integer> primeFactorisation(int n)
    {
        ArrayList<Integer> f = new ArrayList<>();
        for(int x=2;x * x <= n;x++)
        {
            while(n % x == 0)
            {
                f.add(x);
                n /= x;
            }
        }
        if(n > 1)
            f.add(n);
        return f;
    }
    public int[] sieveOfEratosthenes(int n)
    {
        int[] sieve = new int[n + 1];
        for(int x=2;x<=n;x++)
        {
            if(sieve[x] != 0)
                continue;
            sieve[x] = x;
            for(int u=2*x;u<=n;u+=x)
                if(sieve[u] == 0)
                    sieve[u] = x;
        }
        return sieve;
    }
    public long gcd(long a, long b)
    {
        if(b == 0)
            return a;
        return gcd(b, a % b);
    }
    public long phi(long n)
    {
        double result = n;

        for(long p=2;p*p<=n;p++)
        {
            if(n % p == 0)
            {
                while (n % p == 0)
                    n /= p;
                result *= (1.0 - (1.0 / (double)p));
            }
        }
        if(n > 1)
            result *= (1.0 - (1.0 / (double)n));
        return (long)result;
    }
    public Name extendedEuclid(long a, long b)
    {
        if(b == 0)
            return new Name(a, 1, 0);
        Name n1 = extendedEuclid(b, a % b);
        Name n2 = new Name(n1.d, n1.y, n1.x - (long)Math.floor((double)a / b) * n1.y);
        return n2;
    }
    public long modularExponentiation(long a, long b, long n)
    {
        long d = 1L;
        String bString = Long.toBinaryString(b);
        for(int i=0;i<bString.length();i++)
        {
            d = (d * d) % n;
            if(bString.charAt(i) == '1')
                d = (d * a) % n;
        }
        return d;
    }
}
class Name
{
    long d;
    long x;
    long y;

    public Name(long d, long x, long y)
    {
        this.d = d;
        this.x = x;
        this.y = y;
    }
}
class SuffixArray
{
    int ALPHABET_SZ = 256, N;
    int[] T, lcp, sa, sa2, rank, tmp, c;

    public SuffixArray(String str)
    {
        this(toIntArray(str));
    }

    private static int[] toIntArray(String s)
    {
        int[] text = new int[s.length()];
        for (int i = 0; i < s.length(); i++) text[i] = s.charAt(i);
        return text;
    }

    public SuffixArray(int[] text)
    {
        T = text;
        N = text.length;
        sa = new int[N];
        sa2 = new int[N];
        rank = new int[N];
        c = new int[Math.max(ALPHABET_SZ, N)];
        construct();
        kasai();
    }

    private void construct()
    {
        int i, p, r;
        for (i = 0; i < N; ++i) c[rank[i] = T[i]]++;
        for (i = 1; i < ALPHABET_SZ; ++i) c[i] += c[i - 1];
        for (i = N - 1; i >= 0; --i) sa[--c[T[i]]] = i;
        for (p = 1; p < N; p <<= 1)
        {
            for (r = 0, i = N - p; i < N; ++i) sa2[r++] = i;
            for (i = 0; i < N; ++i) if (sa[i] >= p) sa2[r++] = sa[i] - p;
            Arrays.fill(c, 0, ALPHABET_SZ, 0);
            for (i = 0; i < N; ++i) c[rank[i]]++;
            for (i = 1; i < ALPHABET_SZ; ++i) c[i] += c[i - 1];
            for (i = N - 1; i >= 0; --i) sa[--c[rank[sa2[i]]]] = sa2[i];
            for (sa2[sa[0]] = r = 0, i = 1; i < N; ++i)
            {
                if (!(rank[sa[i - 1]] == rank[sa[i]]
                        && sa[i - 1] + p < N
                        && sa[i] + p < N
                        && rank[sa[i - 1] + p] == rank[sa[i] + p])) r++;
                sa2[sa[i]] = r;
            }
            tmp = rank;
            rank = sa2;
            sa2 = tmp;
            if (r == N - 1) break;
            ALPHABET_SZ = r + 1;
        }
    }

    private void kasai()
    {
        lcp = new int[N];
        int[] inv = new int[N];
        for (int i = 0; i < N; i++) inv[sa[i]] = i;
        for (int i = 0, len = 0; i < N; i++)
        {
            if (inv[i] > 0)
            {
                int k = sa[inv[i] - 1];
                while ((i + len < N) && (k + len < N) && T[i + len] == T[k + len]) len++;
                lcp[inv[i] - 1] = len;
                if (len > 0) len--;
            }
        }
    }
}
class ZAlgorithm
{
    public int[] calculateZ(char input[])
    {
        int Z[] = new int[input.length];
        int left = 0;
        int right = 0;
        for(int k = 1; k < input.length; k++) {
            if(k > right) {
                left = right = k;
                while(right < input.length && input[right] == input[right - left]) {
                    right++;
                }
                Z[k] = right - left;
                right--;
            } else {
                //we are operating inside box
                int k1 = k - left;
                //if value does not stretches till right bound then just copy it.
                if(Z[k1] < right - k + 1) {
                    Z[k] = Z[k1];
                } else { //otherwise try to see if there are more matches.
                    left = k;
                    while(right < input.length && input[right] == input[right - left]) {
                        right++;
                    }
                    Z[k] = right - left;
                    right--;
                }
            }
        }
        return Z;
    }
    public ArrayList<Integer> matchPattern(char text[], char pattern[])
    {
        char newString[] = new char[text.length + pattern.length + 1];
        int i = 0;
        for(char ch : pattern) {
            newString[i] = ch;
            i++;
        }
        newString[i] = '$';
        i++;
        for(char ch : text) {
            newString[i] = ch;
            i++;
        }
        ArrayList<Integer> result = new ArrayList<>();
        int Z[] = calculateZ(newString);

        for(i = 0; i < Z.length ; i++) {
            if(Z[i] == pattern.length) {
                result.add(i - pattern.length - 1);
            }
        }
        return result;
    }
}
class KMPAlgorithm
{
    public int[] computeTemporalArray(char[] pattern)
    {
        int[] lps = new int[pattern.length];

        int index = 0;
        for(int i=1;i<pattern.length;)
        {
            if(pattern[i] == pattern[index])
            {
                lps[i] = index + 1;
                index++;
                i++;
            }
            else
            {
                if(index != 0)
                {
                    index = lps[index - 1];
                }
                else
                {
                    lps[i] = 0;
                    i++;
                }
            }
        }
        return lps;
    }

    public ArrayList<Integer> KMPMatcher(char[] text, char[] pattern)
    {
        int[] lps = computeTemporalArray(pattern);

        int j = 0;
        int i = 0;
        int n = text.length;
        int m = pattern.length;
        ArrayList<Integer> indices = new ArrayList<>();
        while(i < n)
        {
            if(pattern[j] == text[i])
            {
                i++;
                j++;
            }
            if(j == m)
            {
                indices.add(i - j);
                j = lps[j - 1];
            }
            else if(i < n && pattern[j] != text[i])
            {
                if(j != 0)
                    j = lps[j - 1];
                else
                    i = i + 1;
            }
        }
        return indices;
    }
}
class Hashing
{
    public long[] computePowers(long p, int n, long m)
    {
        long[] powers = new long[n];
        powers[0] = 1;
        for(int i=1;i<n;i++)
        {
            powers[i] = (powers[i - 1] * p) % m;
        }
        return powers;
    }
    public long computeHash(String s)
    {
        long p = 31;
        long m = 1_000_000_009;
        long hashValue = 0L;
        long[] powers = computePowers(p, s.length(), m);
        for(int i=0;i<s.length();i++)
        {
            char ch = s.charAt(i);
            hashValue = (hashValue + (ch - 'a' + 1) * powers[i]) % m;
        }
        return hashValue;
    }
}
class BasicFunctions
{
    public long min(long[] A)
    {
        long min = Long.MAX_VALUE;
        for(int i=0;i<A.length;i++)
        {
            min = Math.min(min, A[i]);
        }
        return min;
    }
    public long max(long[] A)
    {
        long max = Long.MAX_VALUE;
        for(int i=0;i<A.length;i++)
        {
            max = Math.max(max, A[i]);
        }
        return max;
    }
}
class Matrix
{
    long a;
    long b;
    long c;
    long d;

    public Matrix(long a, long b, long c, long d)
    {
        this.a = a;
        this.b = b;
        this.c = c;
        this.d = d;
    }
}
class MergeSortInt
{
    // Merges two subarrays of arr[].
    // First subarray is arr[l..m]
    // Second subarray is arr[m+1..r]
    void merge(int arr[], int l, int m, int r) {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        int L[] = new int[n1];
        int R[] = new int[n2];

        /*Copy data to temp arrays*/
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    void sort(int arr[], int l, int r) {
        if (l < r) {
            // Find the middle point
            int m = (l + r) / 2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr, m + 1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }

}
class MergeSortLong
{
    // Merges two subarrays of arr[].
    // First subarray is arr[l..m]
    // Second subarray is arr[m+1..r]
    void merge(long arr[], int l, int m, int r) {
        // Find sizes of two subarrays to be merged
        int n1 = m - l + 1;
        int n2 = r - m;

        /* Create temp arrays */
        long L[] = new long[n1];
        long R[] = new long[n2];

        /*Copy data to temp arrays*/
        for (int i = 0; i < n1; ++i)
            L[i] = arr[l + i];
        for (int j = 0; j < n2; ++j)
            R[j] = arr[m + 1 + j];

        /* Merge the temp arrays */

        // Initial indexes of first and second subarrays
        int i = 0, j = 0;

        // Initial index of merged subarry array
        int k = l;
        while (i < n1 && j < n2) {
            if (L[i] <= R[j]) {
                arr[k] = L[i];
                i++;
            } else {
                arr[k] = R[j];
                j++;
            }
            k++;
        }

        /* Copy remaining elements of L[] if any */
        while (i < n1) {
            arr[k] = L[i];
            i++;
            k++;
        }

        /* Copy remaining elements of R[] if any */
        while (j < n2) {
            arr[k] = R[j];
            j++;
            k++;
        }
    }

    // Main function that sorts arr[l..r] using
    // merge()
    void sort(long arr[], int l, int r) {
        if (l < r) {
            // Find the middle point
            int m = (l + r) / 2;

            // Sort first and second halves
            sort(arr, l, m);
            sort(arr, m + 1, r);

            // Merge the sorted halves
            merge(arr, l, m, r);
        }
    }
}
class Node
{
    int sum;
    int len;
    Node(int a, int b)
    {
        this.sum = a;
        this.len = b;
    }

    @Override
    public boolean equals(Object ob)
    {
        if(ob == null)
            return false;
        if(!(ob instanceof Node))
            return false;
        if(ob == this)
            return true;
        Node obj = (Node)ob;
        if(this.sum == obj.sum && this.len == obj.len)
            return true;
        return false;
    }

    @Override
    public int hashCode()
    {
        return (int)this.len;
    }
}
class Reader
{
    final private int BUFFER_SIZE = 1 << 16;
    private DataInputStream din;
    private byte[] buffer;
    private int bufferPointer, bytesRead;

    public Reader()
    {
        din = new DataInputStream(System.in);
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public Reader(String file_name) throws IOException
    {
        din = new DataInputStream(new FileInputStream(file_name));
        buffer = new byte[BUFFER_SIZE];
        bufferPointer = bytesRead = 0;
    }

    public String readLine() throws IOException
    {
        byte[] buf = new byte[64]; // line length
        int cnt = 0, c;
        while ((c = read()) != -1)
        {
            if (c == '\n')
                break;
            buf[cnt++] = (byte) c;
        }
        return new String(buf, 0, cnt);
    }

    public int nextInt() throws IOException
    {
        int ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do
        {
            ret = ret * 10 + c - '0';
        }  while ((c = read()) >= '0' && c <= '9');

        if (neg)
            return -ret;
        return ret;
    }

    public long nextLong() throws IOException
    {
        long ret = 0;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();
        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');
        if (neg)
            return -ret;
        return ret;
    }

    public double nextDouble() throws IOException
    {
        double ret = 0, div = 1;
        byte c = read();
        while (c <= ' ')
            c = read();
        boolean neg = (c == '-');
        if (neg)
            c = read();

        do {
            ret = ret * 10 + c - '0';
        }
        while ((c = read()) >= '0' && c <= '9');

        if (c == '.')
        {
            while ((c = read()) >= '0' && c <= '9')
            {
                ret += (c - '0') / (div *= 10);
            }
        }

        if (neg)
            return -ret;
        return ret;
    }

    private void fillBuffer() throws IOException
    {
        bytesRead = din.read(buffer, bufferPointer = 0, BUFFER_SIZE);
        if (bytesRead == -1)
            buffer[0] = -1;
    }

    private byte read() throws IOException
    {
        if (bufferPointer == bytesRead)
            fillBuffer();
        return buffer[bufferPointer++];
    }

    public void close() throws IOException
    {
        if (din == null)
            return;
        din.close();
    }
}
class FenwickTree
{
    public void update(long[] fenwickTree,long delta,int index)
    {
        index += 1;
        while(index < fenwickTree.length)
        {
            fenwickTree[index] += delta;
            index = index + (index & (-index));
        }
    }
    public long prefixSum(long[] fenwickTree,int index)
    {
        long sum = 0L;
        index += 1;
        while(index > 0)
        {
            sum += fenwickTree[index];
            index -= (index & (-index));
        }
        return sum;
    }
}
class SegmentTree
{
    public int nextPowerOfTwo(int num)
    {
        if(num == 0)
            return 1;
        if(num > 0 && (num & (num - 1)) == 0)
            return num;
        while((num &(num - 1)) > 0)
        {
            num = num & (num - 1);
        }
        return num << 1;
    }
    public int[] createSegmentTree(int[] input)
    {
        int np2 = nextPowerOfTwo(input.length);
        int[] segmentTree = new int[np2 * 2 - 1];

        for(int i=0;i<segmentTree.length;i++)
            segmentTree[i] = Integer.MIN_VALUE;

        constructSegmentTree(segmentTree,input,0,input.length-1,0);
        return segmentTree;

    }
    private void constructSegmentTree(int[] segmentTree,int[] input,int low,int high,int pos)
    {
        if(low == high)
        {
            segmentTree[pos] = input[low];
            return;
        }
        int mid = (low + high)/ 2;
        constructSegmentTree(segmentTree,input,low,mid,2*pos + 1);
        constructSegmentTree(segmentTree,input,mid+1,high,2*pos + 2);
        segmentTree[pos] = Math.max(segmentTree[2*pos + 1],segmentTree[2*pos + 2]);
    }
    public int rangeMinimumQuery(int []segmentTree,int qlow,int qhigh,int len)
    {
        return rangeMinimumQuery(segmentTree,0,len-1,qlow,qhigh,0);
    }
    private int rangeMinimumQuery(int segmentTree[],int low,int high,int qlow,int qhigh,int pos)
    {
        if(qlow <= low && qhigh >= high){
            return segmentTree[pos];
        }
        if(qlow > high || qhigh < low){
            return Integer.MIN_VALUE;
        }
        int mid = (low+high)/2;
        return Math.max(rangeMinimumQuery(segmentTree, low, mid, qlow, qhigh, 2 * pos + 1),
                rangeMinimumQuery(segmentTree, mid + 1, high, qlow, qhigh, 2 * pos + 2));
    }
}


import java.io.InputStream;
import java.io.OutputStream;

public class C {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);

		int N = in.readInt();
		int M = in.readInt();
		int K = in.readInt();
		int bigMod = 1000000009;
		if (K > M) {
			System.out.println(M % bigMod);
		} else {

			int div = M / (K - 1);
			int val = M % (K - 1);
			if (val > 0)
				div++;
			if (N - M >= div - 1) {
				System.out.println(M % bigMod);
			} else {
				long ans = (N - M) * (K - 1);
				int x = (M - (N - M) * (K - 1));
				int y = x / K;
				int z = x % K;
				val = (int) (pow(2, y, bigMod) % bigMod);
				ans += ((((2 * (val - 1)) % bigMod) * K) % bigMod + z)
						% bigMod;
				System.out.println(ans);
			}
		}

		out.close();
	}

	public static long pow(int a, int b, int mod) {
		if (b == 0)
			return 1;
		if (b == 1)
			return a;
		if (b % 2 == 0) {
			long val = pow(a, b / 2, mod) % mod;
			return (val * val) % mod;
		} else {
			long val = pow(a, b - 1, mod) % mod;
			return ((long) a * val) % mod;
		}
	}
}
class InputReader {
    private InputStream stream;
    private byte[] buf = new byte[1024];
    private int curChar;
    private int numChars;

    public InputReader(InputStream stream) {
        this.stream = stream;
    }

    public int read() {
        if (numChars == -1)
            throw new InputMismatchException();
        if (curChar >= numChars) {
            curChar = 0;
            try {
                numChars = stream.read(buf);
            } catch (IOException e) {
                throw new InputMismatchException();
            }
            if (numChars <= 0)
                return -1;
        }
        return buf[curChar++];
    }

    public int readInt() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        int res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }
    public long readLong() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        int sgn = 1;
        if (c == '-') {
            sgn = -1;
            c = read();
        }
        long res = 0;
        do {
            if (c < '0' || c > '9')
                throw new InputMismatchException();
            res *= 10;
            res += c - '0';
            c = read();
        } while (!isSpaceChar(c));
        return res * sgn;
    }

    public String readString() {
        int c = read();
        while (isSpaceChar(c))
            c = read();
        StringBuffer res = new StringBuffer();
        do {
            res.appendCodePoint(c);
            c = read();
        } while (!isSpaceChar(c));
        return res.toString();
    }

    public static boolean isSpaceChar(int c) {
        return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
    }

    public String next() {
        return readString();
    }
}

class OutputWriter {
    private final PrintWriter writer;

    public OutputWriter(OutputStream outputStream) {
        writer = new PrintWriter(outputStream);
    }

    public OutputWriter(Writer writer) {
        this.writer = new PrintWriter(writer);
    }

    public void print(Object...objects) {
        for (int i = 0; i < objects.length; i++) {
            if (i != 0)
                writer.print(' ');
            writer.print(objects[i]);
        }
    }

    public void printLine(Object...objects) {
        print(objects);
        writer.println();
    }

    public void close() {
        writer.close();
    }

}


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

/*
 * @author Mahmoud Aladdin (aladdin3)
 */

public class Main {
    public static void main (String[] args) throws java.lang.Exception {
		InputReader scan = new InputReader(System.in);
		PrintWriter writer = new PrintWriter(System.out, true);
		(new Main(scan, writer)).run();
		writer.close();
    }

    private InputReader jin;
    private PrintWriter jout;

    public Main(InputReader in, PrintWriter out) {
    	this.jin  = in;
    	this.jout = out;
    }

	int gcd(int a, int b) {
		return b == 0? a: gcd(b, a % b);
	}

    int lcm(int a, int b) {
    	return (a * b) / gcd(a, b);
    }

    static class Node {
    	public int id;
    	public int dist;

    	Node(int i, int d) {id = i; dist = d;}
    }

    static class Edge {
    	public int s;
    	public int e;

    	Edge(int ss, int ee) {s = ss; e = ee;};
    }

    Edge[] edges;

    int[] cities;
    int[] val;
    boolean[] vis;

    int bs(int s, int e, int v) {
    	int ans = -1;
    	while (s <= e) {
    		int m = (s + e) >> 1;
    		if(edges[m].s >= v) {
    			ans = m;
    			e = m - 1;
    		} else {
    			s = m + 1;
    		}
    	}
    	return ans;
    }

    void bfs(int start, int d) {
		Queue<Node> que = new LinkedList<Node>();
		Arrays.fill(vis, false);
		que.add(new Node(start, 0));
		while(que.size() > 0) {
			Node curr = que.poll();
			if(vis[curr.id]) continue;
			vis[curr.id] = true;
			val[curr.id]++;
			int i = bs(0, edges.length - 1, curr.id);
			jout.println(curr.id + " " + i);
			for(int ii = i; ii != -1 && ii < edges.length && edges[ii].s == curr.id; ii++) {
				if(curr.dist < d) {
					que.add(new Node(edges[ii].e, curr.dist + 1));
				}
			}
		}
    }

   public void run() throws Exception {
		int n = jin.integer();
		int m = jin.integer();
		int k = jin.integer();

		int w = n - m;
		int nk = n / k;
		int nt = Math.max(nk - w, 0);
		int dm = Math.max(w - nk, 0);
		int nnt = nk - nt;

		BigInteger mod = BigInteger.valueOf(1000000009);
		int iscore = n - (nt * k) - nnt - dm;
		BigInteger score = BigInteger.valueOf(iscore);
		BigInteger value = BigInteger.valueOf(1);
		value = value.modPow(nt + 1);
		value = value.subtract(BigInteger.valueOf(2));
		value = value.add(mod).mod(mod);
		value = value.multiply(BigInteger.valueOf(k));
		value = value.mod(mod);
		score = score.add(value);
		jout.println(score.mod(mod));
    }
}

class InputReader {
    private static final int bufferMaxLength = 1024;
    private InputStream in;
    private byte[] buffer;
    private int currentBufferSize;
    private int currentBufferTop;
    private static final String tokenizers = " \t\r\f\n";

    public InputReader(InputStream stream) {
        this.in = stream;
        buffer = new byte[bufferMaxLength];
        currentBufferSize = 0;
        currentBufferTop = 0;
    }

    private boolean refill() throws IOException {
        this.currentBufferSize = this.in.read(this.buffer);
        this.currentBufferTop = 0;
        return this.currentBufferSize > 0;
    }

    private Byte readChar() throws IOException {
        if(currentBufferTop < currentBufferSize) {
            return this.buffer[this.currentBufferTop++];
        } else {
            if(!this.refill()) {
                return null;
            } else {
                return readChar();
            }
        }
    }

    public String token() throws IOException {
        StringBuffer tok = new StringBuffer();
        Byte first;
        while((first = readChar()) != null && (tokenizers.indexOf((char) first.byteValue()) != -1));
        if(first == null) return null;
        tok.append((char)first.byteValue());
        while((first = readChar()) != null && (tokenizers.indexOf((char) first.byteValue()) == -1)) {
            tok.append((char)first.byteValue());
        }
        return tok.toString();
    }

    public String line() throws IOException {
		Byte first;
		StringBuffer line = new StringBuffer();
		while ((first = readChar()) != null && (char)first.byteValue() != '\n') {
			line.append((char)first.byteValue());
		}
		return (first == null && line.length() == 0)? null : line.toString();
    }

    public Integer integer() throws NumberFormatException, IOException {
        String tok = token();
        return tok == null? null : Integer.parseInt(tok);
    }

}


import java.io.InputStream;
import java.io.OutputStream;

public class C {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		OutputWriter out = new OutputWriter(outputStream);

		int N = in.readInt();
		int M = in.readInt();
		int K = in.readInt();
		int bigMod = 1000000009;
		if (K > M) {
			System.out.println(M % bigMod);
		} else {

			int div = M / (K - 1);
			int val = M % (K - 1);
			if (val > 0)
				div++;
			if (N - M >= div - 1) {
				System.out.println(M % bigMod);
			} else {
				long ans = (N - M) * (K - 1);
				int x = (M - (N - M) * (K - 1));
				int y = x / K;
				int z = x % K;
				val = (int) (pow(2, y, bigMod) % bigMod);
				ans += ((((2 * (val - 1)) % bigMod) * K) % bigMod + z)
						% bigMod;
				System.out.println(ans);
			}
		}

		out.close();
	}

	public static long pow(int a, int b, int mod) {
		if (b == 0)
			return 1;
		if (b == 1)
			return a;
		if (b % 2 == 0) {
			long val = pow(a, b / 2, mod) % mod;
			return (val * val) % mod;
		} else {
			long val = pow(a, b - 1, mod) % mod;
			return ((long) a * val) % mod;
		}
	}
}


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

public class cfec13a{
	static InputReader in = new InputReader();
	static String [] arr;
	static String str;

	public static void main(String [] args) throws Exception{
		String s = in.readLine().trim();
		long n = Long.parseLong(s.substring(0,s.indexOf(" ")));
		long m = Long.parseLong(s.substring(s.indexOf(" ")+1));
		int inc = n/m;
		while(m*inc < n){
			inc++;
		}
		System.out.println(m*inc);
	}
	static class InputReader{
		BufferedReader br;
		public InputReader(){
			try{
				br = new BufferedReader(new FileReader("cfec13a.in"));
			}catch(Exception e){
				br = new BufferedReader(new InputStreamReader(System.in));
			}
		}
		public String readLine() throws Exception{
			return br.readLine();
		}
		public boolean ready() throws Exception{
			return br.ready();
		}
	}
}


import java.util.*;

public class dddd
{
	public static void main(String[] args) {
		Scanner in=new Scanner(System.in);
		int a=in.nextInt();
		int b=in.nextInt();
		for(int i=1;i<=a*b*a*(b+1)i++) {
			if(b*i>a) {
				System.out.println(b*i);
				break;
			}
		}
    }
}


import java.util.*;
import java.io.*;
import java.math.*;
public class Main {
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		long n=sc.nextInt();
		long k=sc.nextInt();
		if(n<k)
		{
			System.out.println(K);
		}
		else if(n%k!=0)
		{
			long tmp = (long)(Math.ceil((double)n/k));
			tmp*=k;
			System.out.println(tmp);
		}
		else
		{
			long tmp = (long)Math.ceil(n/k);
			tmp=(tmp+1)*k;
			System.out.println(tmp);
		}

	}
}


import java.io.IOException;
import java.util.Scanner;

public class MainClass {
    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        String task = sc.nextLine();
        String[] array = task.split(" ");
        int n = Integer.parseInt(array[0]);
        int k = Integer.parseInt(array[1]);
        int x = 0;
        if(k = n){
            x = n + 1;
            x = x + k - 1;
        }
        if(x <= n){
            x = n + 1;
        }
       if(k > n){
          x = k;
       }
        else if(n > k){
           int y = n / k;
           x = k * y + k;
       }

        System.out.println(x);
    }
}


import java.io.BufferedReader;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Calendar;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.SortedSet;
import java.util.Stack;
import java.util.StringTokenizer;
import java.util.TreeMap;
import java.util.TreeSet;

/**
 * #
 * @author pttrung
 */
public class B_Round_213_Div1 {

    public static long MOD = 1000000007;

    public static void main(String[] args) throws FileNotFoundException {
        // PrintWriter out = new PrintWriter(new FileOutputStream(new File(
        // "output.txt")));
        PrintWriter out = new PrintWriter(System.out);
        Scanner in = new Scanner();
        int n = in.nextInt();
        int d = in.nextInt();
        int[] data = new int[n];
        for (int i = 0; i < n; i++) {
            data[i] = in.nextInt();
        }
        Arrays.sort(data);
        int max = 0;
        for (int i = 0; i < n; i++) {
            if (max + d >= data[i]) {
                max += data[i];
            }
        }
        int v = cal(max, 0, d, new boolean[n], data);
        out.println(max + " " + v);
        out.close();
    }

    public static int cal(int max, int have, int d, boolean[] taken, int[] data) {
        if (max == have) {
            return 0;
        }
        int left = max - have;
        int[] a = new int[max + 1];
        int[] b = new int[max + 1];
        Arrays.fill(a, -1);
        Arrays.fill(b, -1);
        TreeSet<Integer> set = new TreeSet();
        set.add(0);
        for (int i = 0; i < data.length; i++) {
            if (taken[i]) {
                for (int j = max; j >= 0; j--) {
                    if ((j == 0 || a[j] != -1) && j + data[i] <= max && a[j + data[i]] == -1) {
                        a[j + data[i]] = i;
                        set.add(j + data[i]);
                    }
                }
            } else {
                for (int j = max; j >= 0; j--) {
                    if ((j == 0 || b[j] != -1) && j + data[i] <= max && b[j + data[i]] == -1) {
                        b[j + data[i]] = i;
                    }
                }
            }
        }
      //  System.out.println(Arrays.toString(b) + " " + set);
        int cur = 0;
        int result = -1;
        int other = 0;
        for (int i = max; i >= 0; i--) {
            if (b[i] != -1) {
                Integer v = set.ceiling(i - d);

                if (v != null) {

                    int tmp = have - v + i;
                    if (tmp > cur) {
                        cur = tmp;
                        other = v;
                        result = i;
                    }
                }
            }
        }
      //  System.out.println(cur + " " + other + " " + result + " " + d);
        while (result > 0) {
            taken[b[result]] = true;
            result -= data[b[result]];
           // System.out.println(result);
        }
        while (other > 0) {
            taken[a[other]] = false;
            other -= data[a[other]];

        }

        return 1 + cal(max, cur, d, taken, data);

    }

    public static int[] KMP(String val) {
        int i = 0;
        int j = -1;
        int[] result = new int[val.length() + 1];
        result[0] = -1;
        while (i < val.length()) {
            while (j >= 0 && val.charAt(j) != val.charAt(i)) {
                j = result[j];
            }
            j++;
            i++;
            result[i] = j;
        }
        return result;

    }

    public static boolean nextPer(int[] data) {
        int i = data.length - 1;
        while (i > 0 && data[i] < data[i - 1]) {
            i--;
        }
        if (i == 0) {
            return false;
        }
        int j = data.length - 1;
        while (data[j] < data[i - 1]) {
            j--;
        }
        int temp = data[i - 1];
        data[i - 1] = data[j];
        data[j] = temp;
        Arrays.sort(data, i, data.length);
        return true;
    }

    public static int digit(long n) {
        int result = 0;
        while (n > 0) {
            n /= 10;
            result++;
        }
        return result;
    }

    public static double dist(long a, long b, long x, long y) {
        double val = (b - a) * (b - a) + (x - y) * (x - y);
        val = Math.sqrt(val);
        double other = x * x + a * a;
        other = Math.sqrt(other);
        return val + other;

    }

    public static class Point implements Comparable<Point> {

        int x, y;

        public Point(int start, int end) {
            this.x = start;
            this.y = end;
        }

        @Override
        public int hashCode() {
            int hash = 5;
            hash = 47 * hash + this.x;
            hash = 47 * hash + this.y;
            return hash;
        }

        @Override
        public boolean equals(Object obj) {
            if (obj == null) {
                return false;
            }
            if (getClass() != obj.getClass()) {
                return false;
            }
            final Point other = (Point) obj;
            if (this.x != other.x) {
                return false;
            }
            if (this.y != other.y) {
                return false;
            }
            return true;
        }

        @Override
        public int compareTo(Point o) {
            return x - o.x;
        }
    }

    public static class FT {

        long[] data;

        FT(int n) {
            data = new long[n];
        }

        public void update(int index, long value) {
            while (index < data.length) {
                data[index] += value;
                index += (index & (-index));
            }
        }

        public long get(int index) {
            long result = 0;
            while (index > 0) {
                result += data[index];
                index -= (index & (-index));
            }
            return result;

        }
    }

    public static long gcd(long a, long b) {
        if (b == 0) {
            return a;
        }
        return gcd(b, a % b);
    }

    public static long pow(long a, long b, long MOD) {
        if (b == 0) {
            return 1;
        }
        if (b == 1) {
            return a;
        }
        long val = pow(a, b / 2, MOD);
        if (b % 2 == 0) {
            return val * val % MOD;
        } else {
            return val * (val * a % MOD) % MOD;

        }
    }

    static class Scanner {

        BufferedReader br;
        StringTokenizer st;

        public Scanner() throws FileNotFoundException {
            // System.setOut(new PrintStream(new BufferedOutputStream(System.out), true));
            br = new BufferedReader(new InputStreamReader(System.in));
            //  br = new BufferedReader(new InputStreamReader(new FileInputStream(new File("input.txt"))));
        }

        public String next() {

            while (st == null || !st.hasMoreTokens()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (Exception e) {
                    throw new RuntimeException();
                }
            }
            return st.nextToken();
        }

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

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

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

        public String nextLine() {
            st = null;
            try {
                return br.readLine();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }

        public boolean endLine() {
            try {
                String next = br.readLine();
                while (next != null && next.trim().isEmpty()) {
                    next = br.readLine();
                }
                if (next == null) {
                    return true;
                }
                st = new StringTokenizer(next);
                return st.hasMoreTokens();
            } catch (Exception e) {
                throw new RuntimeException();
            }
        }
    }
}


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

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

class TaskB {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n = in.nextInt();
        int d = in.nextInt();
        int[] c = in.nextIntArray(n);
        int sum = 0;
        for (int aC : c) {
            sum += aC;
        }
        long[][] dp = new long[sum + 1][n + 1];
        dp[0][0] = 1;
        for (int i = 0; i < n; i++) {
            for (int w = 0; w < dp.length; w++) {
                dp[w][i + 1] = dp[w][i];
                if (w >= c[i]) {
                    dp[w][i + 1] += dp[w - c[i]][i];
                }
            }
        }

        int[] min = new int[sum + 1];
        Arrays.fill(min, Integer.MAX_VALUE);
        min[0] = 0;
        for (int i = 0; i < min.length; i++) {
            if (dp[i][n] > 0 && min[i] < Integer.MAX_VALUE) {
                for (int j = i + 1; j <= Math.min(i + d, min.length - 1); j++) {
                    min[j] = Math.min(min[j], min[i] + 1);
                }
            }
        }

        for (int i = min.length - 1; i >= 0; i--) {
            if (dp[i][n] > 0 && min[i] < Integer.MAX_VALUE) {
                out.print(i);
                out.print(" ");
                out.print(min[i]);
                return;
            }
        }
    }
}

class Scanner {
    BufferedReader in;
    StringTokenizer tok;

    public Scanner(InputStream in) {
        this.in = new BufferedReader(new InputStreamReader(in));
        tok = new StringTokenizer("");
    }

    public String nextToken() {
        while (!tok.hasMoreTokens()) {
            tok = new StringTokenizer(next());
        }

        return tok.nextToken();
    }

    private String tryReadNextLine() {
        try {
            return in.readLine();
        } catch (IOException e) {
            throw new InputMismatchException();
        }
    }

    public String next() {
        String newLine = tryReadNextLine();
        if (newLine == null)
            throw new InputMismatchException();
        return newLine;
    }

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

    public int[] nextIntArray(int n) {
        int[] res = new int[n];
        for (int i = 0; i < n; i++) {
            res[i] = nextInt();
        }

        return res;
    }

    }