Manao is taking part in a quiz. The quiz consists of n consecutive questions. A correct answer gives one point to the player. The game also has a counter of consecutive correct answers. When the player answers a question correctly, the number on this counter increases by 1. If the player answers a question incorrectly, the counter is reset, that is, the number on it reduces to 0. If after an answer the counter reaches the number k, then it is reset, and the player's score is doubled. Note that in this case, first 1 point is added to the player's score, and then the total score is doubled. At the beginning of the game, both the player's score and the counter of consecutive correct answers are set to zero.Manao remembers that he has answered exactly m questions correctly. But he does not remember the order in which the questions came. He's trying to figure out what his minimum score may be. Help him and compute the remainder of the corresponding number after division by 1000000009 (109 + 9).

The single line contains three space-separated integers n, m and k (2 ≤ k ≤ n ≤ 109; 0 ≤ m ≤ n).

Print a single integer — the remainder from division of Manao's minimum possible score in the quiz by 1000000009 (109 + 9).

NoteSample 1. Manao answered 3 questions out of 5, and his score would double for each two consecutive correct answers. If Manao had answered the first, third and fifth questions, he would have scored as much as 3 points.Sample 2. Now Manao answered 4 questions. The minimum possible score is obtained when the only wrong answer is to the question 4.Also note that you are asked to minimize the score and not the remainder of the score modulo 1000000009. For example, if Manao could obtain either 2000000000 or 2000000020 points, the answer is 2000000000 mod 1000000009, even though 2000000020 mod 1000000009 is a smaller number.

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

public class code
{
	static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

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

    public static void main(String args[])throws IOException
	{
        FastReader scn = new FastReader();
        long P = 1000000009L;

        long n = scn.nextLong();
        long m = scn.nextLong();
        long k = scn.nextLong();

        long complete = (n/k)*(k-1);
        long partial = n%k;
        if( complete + partial >= m )
        {
            System.out.println(m);
            return;
        }

        long ans_mid = -1;
        long l = k - 2;
        long r = m - 1;
        while(l <= r)
        {
            long mid = (l+r)/2;

            complete = ((n - 1 - mid)/k)*(k-1);
            partial = Math.max((n - 1 - mid)%k - 1, 0);

            long possible  = (mid + 1) + complete + partial;

            if(possible >= m)
            {
                r = mid - 1;
                ans_mid = mid;
            }
            else
            {
                l = mid + 1;
            }
        }

        long power = (ans_mid + 1)/k;
        long points = m - power*k;
        long points2 = getTwoPower(power + 1, P);

        points2 = (points2 - 2)%P;
        points2 = (points2 * k)%P;

        points += points2;
        points = points % P;
        if(points < 0)
            points = points + P;
        System.out.println(points);
	}

    public static long getTwoPower(long power, long P)
    {
        if(power == 0)
            return 1;
        if(power == 1)
            return 2;

        long ans = getTwoPower(power/2, P);
        ans = (ans * ans)%P;
        if(power % 2 == 1)
            ans = (ans * 2)%P;
        return ans;
    }

    public static int getIndex(int[] list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list[middle]==value)
                return middle;
            else if(list[middle] < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return -1;
    }

    public static int getLessThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return r;
    }

    public static int getMoreThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return l;
    }

    public static long inverseModulo(long a, long P)
    {
        return powerModulo(a, P-2, P);
    }

    public static long powerModulo(long a, long p, long m)
    {
        if(p==0)
            return 1;

        long temp = powerModulo(a, p/2, m);
        temp = (temp * temp)%m;
        if(p%2 == 0)
            return temp;
        else
            return (a * temp)%m;

    }
}

class Pair implements Comparable<Pair>
{
    int a, b;

    public Pair(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public int compareTo(Pair p)
    {
        return this.b - p.b;
    }
}

class Node
{
    int value;
    int req_value;
    ArrayList<Integer> neighbors;
    boolean visited;

    public Node()
    {
        neighbors = new ArrayList<>();
    }

}

class MutableInt
{
    int count;
    ArrayList<Integer> list;
    public MutableInt()
    {
        list = new ArrayList<>();
    }
}

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

public class Quiz implements Closeable {

    private InputReader in = new InputReader(System.in);
    private PrintWriter out = new PrintWriter(System.out);

    public void solve() {
        long n = in.ni(), correct = in.ni(), k = in.ni();
        long wrong = n - correct;
        long score = 0;
        if (correct < k) {
            score = correct;
        } else {
            long groups = correct / (k - 1), rem = correct % (k - 1);
            if (wrong >= groups + 1) {
                score += groups * (k - 1);
                score += rem;
                score %= MOD;
            } else {
                groups -= wrong;
                score += wrong * (k - 1);
                score %= MOD;
                rem = groups * (k - 1) + rem;
                long terms = rem / k, ones = rem % k;
                score += ones;
                score += (power(terms) - 1) * 2 * k;
            }
        }
        out.println(score % MOD);
    }

    private final long MOD = (long) 1e9 + 9;

    private long power(long p) {
        if (p == 0) return 1L;
        if (p % 2 == 1) {
            return 2L * power(p - 1) % MOD;
        }
        long x = power(p >> 1) % MOD;
        return (x * x) % MOD;
    }

    @Override
    public void close() throws IOException {
        in.close();
        out.close();
    }

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

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

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

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

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

        public void close() throws IOException {
            reader.close();
        }
    }

    public static void main(String[] args) throws IOException {
        try (Quiz instance = new Quiz()) {
            instance.solve();
        }
    }
}

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

public class P337C {

	public static final long MOD = 1000000009;

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] info = br.readLine().split(" ");
		long questions = Long.parseLong(info[0]);
		long correctQts = Long.parseLong(info[1]);
		long contCorrQts = Long.parseLong(info[2]);
		long minScore = getMinimumScore(questions, correctQts, contCorrQts);
		System.out.println(minScore);
	}

	private static long getMinimumScore(long questions, long correctQts,
			long contCorrQts) {
	long div = questions/contCorrQts;
	long blocks = questions - div;
	long missing = correctQts - blocks;
	if(missing>= 0){
			long dupliScore = duplicateScore(missing, contCorrQts);
			long normalScore = correctQts - (missing * contCorrQts);
			long minScore = add(dupliScore, normalScore);
			return minScore;
		}
		return correctQts;
	}

	private static long duplicateScore(long missing, long contCorrQts) {
		long exp = fastExp(2, missing);
		long duplicate = mult(mult(2, sub(exp, 1)), contCorrQts);
		return duplicate;
	}

	private static long add(long a, long b) {
		return (a + b) % MOD;
	}

	private static long mult(long a, long b) {
		return (a * b) % MOD;
	}

	private static long sub(long a, long b) {
		return (a - b + MOD) % MOD;
	}

	private static long fastExp(int b, long exp) {
		if (exp == 0)
			return 1;
		if (exp == 1)
			return b;
		long halfPower = fastExp(b, exp / 2);
		long fullPower = mult(halfPower, halfPower);
		if (exp % 2 == 0)
			return fullPower;
		return mult(b, fullPower);
	}

}

import java.io.IOException;

public class CFC {

	private static final int IN_BUFFER_SIZE = 1 << 16;
	private static final int OUT_BUFFER_SIZE = 1 << 16;
	private byte[] input = new byte[IN_BUFFER_SIZE];
	private int ix = IN_BUFFER_SIZE;
	private int bytesRead = ix;
	private byte[] output = new byte[OUT_BUFFER_SIZE];
	private int ox = 0;

	private void readMore() {
		try {
			bytesRead = System.in.read(input, 0, IN_BUFFER_SIZE);
			if (bytesRead <= 0)
				throw new RuntimeException();
			ix = 0;
		} catch (IOException e) {
			throw new RuntimeException();
		}
	}

	private void flushOut() {
		System.out.write(output, 0, ox);
		ox = 0;
	}

	private void append(char c) {
		if (ox == OUT_BUFFER_SIZE)
			flushOut();
		output[ox++] = (byte) c;
	}

	private int nextInt() {
		skipSpaces();
		int ret = 0;
		if (ix == bytesRead) {
			readMore();
		}
		int sign = 1;
		if (input[ix] == '-') {
			sign = -1;
			ix++;
		}
		while (true) {
			if (ix == bytesRead) {
				try {
					readMore();
				} catch (RuntimeException e) {
					return ret;
				}
			}
			if (input[ix] < '0') {
				break;
			}
			ret *= 10;
			ret += input[ix++] - '0';
		}
		return sign * ret;
	}

	int cntSize;

	private void skipSpaces() {
		while (true) {
			if (ix == bytesRead) {
				readMore();
			}
			if (input[ix] > ' ')
				break;
			ix++;
		}
	}

	private char[] nn = new char[32];

	private void printLong(long n) {
		if (n == 0) {
			append('0');
		} else {
			if (n < 0) {
				append('-');
				n = -n;
			}
			int kk = 0;
			while (n > 0) {
				nn[kk++] = (char) (n % 10 + '0');
				n /= 10;
			}
			for (int i = kk - 1; i >= 0; i--) {
				append(nn[i]);
			}
		}
	}

	private long powMod(long n, long k, long m) {
		if (k == 0)
			return 1;
		if ((k & 1) == 0) {
			long t = powMod(n, k / 2, m);
			return (t * t) % m;
		}
		return (n * powMod(n, k - 1, m)) % m;
	}

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

	private static final long MOD = 1000000009;

	private void work() {

		long n = nextInt();
		long m = nextInt();
		long k = nextInt();

		long w = n - m;
		if (w * k >= n || w * (k - 1) >= m) {
			printLong(m);
			append('\n');
		} else {
			long rem = m - w * (k - 1);
			long p = rem / k;
			long res = ((calc(p) * k) % MOD + rem % k + w * (k - 1)) % MOD;
			printLong(res);
			append('\n');
		}
		if (ox > 0)
			flushOut();
		System.out.close();
	}

	private long calc(long p) {
		if (p == 0)
			return 0;
		return (powMod(2, p + 1, MOD) - 2 + MOD) % MOD;
	}
}

import java.io.*;
import java.util.*;
public final class quiz
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static long mod=(long)(1e9+9);
	static long[][] base=new long[][]{{2,0},{2,1}},val;

	static long[][] matrix_pow(long[][] base,long b)
	{
		long[][] res=new long[][]{{1,0},{0,1}};
		while(b>0)
		{
			if(b%2==1)
			{
				res=matrix_mul(res,base,2,2,2,2);
			}
			base=matrix_mul(base,base,2,2,2,2);
			b=b/2;
		}
		return res;
	}

	static long[][] matrix_mul(long[][] a,long[][] b,int r1,int c1,int r2,int c2)
	{
		long[][] c=new long[r1][c2];
		for(int i=0;i<r1;i++)
		{
			for(int j=0;j<c2;j++)
			{
				for(int k=0;k<c1;k++)
				{
					c[i][j]=(c[i][j]+(a[i][k]*b[k][j]))%mod;
				}
			}
		}
		return c;
	}

	public static void main(String args[]) throws Exception
	{
		long n=sc.nextLong(),m=sc.nextLong(),k=sc.nextLong(),low=0,high=m/k;val=new long[][]{{0,k}};
		while(low<high)
		{
			long mid=(low+high)>>1,p_left=m-(k*mid),req=(p_left/(k-1))+(((p_left)%(k-1)==0)?0:1),curr=p_left+(req-1);
			if((k*mid)+curr<=n)
			{
				high=mid;
			}
			else
			{
				low=mid+1;
			}
		}
		base=matrix_pow(base,low);long[][] res=matrix_mul(val,base,1,2,2,2);long ans=(res[0][0]+(m-(k*low)))%mod;out.println(ans);out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

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

	public String next() throws Exception {
		return nextToken().toString();
	}

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

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

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

import java.util.*;
import java.io.*;
public class Main
{
	static BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
	static long MOD = (long) 1e9 + 9;
	public static void main(String[] args)
	{
		long n, m, k;
		int[] inp = readIntArray();
		n = inp[0]; m = inp[1]; k = inp[2];
		long A = m - ((n / k) * (k - 1) + (n % k));
		// System.out.println("the value of A is " + A);
		if (A <= 0)
		{
			System.out.println(m);
			return;
		}
		/*
		long score = 0;
		for (int i = 0; i < A; i++)
		{
			score += k;
			score %= MOD;

			score *= 2;
			score %= MOD;
		}
		*/

		long[][] original = {{2, 2}, {0, 1}};
		long[][] result = pow(original, (int) A);
		long score = (result[0][1] * k) % MOD;

		//long[][] original = {{2, 2}, {0, 1}};
		//long[][] result = pow(original, 3);
		//for (long[] row : result)
		//	System.out.println(Arrays.toString(row));

		score += ((n / k) - A) * (k - 1);
		score %= MOD;

		score += n % k;
		score %= MOD;
		System.out.println(score);
	}
	static long[][] pow(long[][] inp, int p)
	{
		if (p == 1)
			return inp;
		// ret = return value
		// inp = input value
		long[][] m = pow(inp, p / 2);
		long[][] ret = mul(m, m);
		if (p % 2 == 1)
		{
			ret = mul(ret, inp);
		}

		// ret = m * m
			// ret * inp
		/*
		// ret = m * m
		ret[0][0] = (m[0][0] * m[0][0]) % MOD;
		ret[0][1] = ((m[0][0] * m[0][1]) % MOD) +
					((m[0][1] * m[1][1]) % MOD);
		ret[1][1] = (m[1][1] * m[1][1]) % MOD;

		if (p % 2 == 1)
		{
			// ret * inp
			ret[0][0] = (ret[0][0] * inp[0][0]) % MOD;
			ret[0][1] = (ret[0][0] * inp[0][1]) % MOD + (ret[0][1] * inp[1][1]) % MOD;
			ret[0][1] %= MOD;
			ret[1][1] = (ret[1][1] * inp[1][1]) % MOD;
		}
		*/
		return ret;
	}
	static long[][] mul(long[][] a, long[][] b)
	{
		long[][] answer = new long[2][2];
		for (int i = 0; i < 2; i++)
			for (int j = 0; j < 2; j++)
				for (int k = 0; k < 2; k++)
				{
					answer[i][j] += (a[i][k] * b[k][j]);
					answer[i][j] %= MOD;
				}
		return answer;
	}
	static long[][] pow2(long[][] inp)
	{
		long[][] ret = new long[2][2];
		ret[0][0] = (inp[0][0] * inp[0][0]) % MOD;
		ret[0][1] = (inp[0][1] * (inp[0][0] + inp[1][1]))  % MOD;
		ret[1][1] = (inp[1][1] * inp[1][1]) % MOD;
		return ret;
	}
	static int[] readIntArray()
	{
		String[] inp = readLine().split("\\s+");
		int[] ret = new int[inp.length];
		for (int i = 0; i < inp.length; i++)
			ret[i] = Integer.parseInt(inp[i]);
		return ret;
	}
	static String readLine()
	{
		try
		{
			return reader.readLine();
		} catch (Exception e){}
		return null;
	}

}

import java.util.*;

public class practice1 {

	public static void main(String[] args) {
		Scanner scn=new Scanner(System.in);
		long mod=1000000009;
		long n=scn.nextLong();
		long m=scn.nextLong();
		long k=scn.nextLong();

		if(m<=(n-n/k)){
			System.out.println(m%mod);
			return;
		}
		long p=m-(n-n/k),to=2,ans=1;
		for(long t=p;t>0;to=to*to%mod,t>>=1){
			if((t&1)>0){
				ans=ans*to%mod;
			}
		}
		ans=((ans-1)*k*2+m-p*k)%mod;
		System.out.println(ans);

	}
}

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

public class Main implements Runnable {

	public void _main() throws IOException {
		long n = nextLong();
		long m = nextLong();
		long k = nextLong();
		long numBlocks = Math.min(Math.min(n / k, n - m), m / (k - 1));
		n -= numBlocks * k;
		m -= numBlocks * (k - 1);
		long numFullBlocks = m / k;
		long rem = m % k;
		long res = 0;
		res = (res + ((p2(numFullBlocks + 1) + MOD - 2) % MOD) * k) % MOD;
		res = (res + rem) % MOD;
		res = (res + numBlocks * (k - 1)) % MOD;
		out.println(res);
	}

	final int MOD = 1000000009;
	private long p2(long s) {
		long res = 1;
		long x = 2;
		while (s > 0) {
			if (s % 2 == 1) {
				res = res * x % MOD;
			}
			x = x * x % MOD;
			s /= 2;
		}
		return res;
	}

	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;

	private String next() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String rl = in.readLine();
			if (rl == null)
				return null;
			st = new StringTokenizer(rl);
		}
		return st.nextToken();
	}

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

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

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

	public static void main(String[] args) {
		Locale.setDefault(Locale.UK);
		new Thread(new Main()).start();
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			//in = new BufferedReader(new FileReader("a.in"));
			//out = new PrintWriter(new FileWriter("a.out"));

			_main();

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(202);
		}
	}

}

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.text.DecimalFormat;
import java.util.StringTokenizer;

public class C implements Runnable {
    private final static long START_TIME=System.currentTimeMillis();
    private final static boolean LOG_ENABLED=true;
    private final static boolean ONLINE_JUDGE = LOG_ENABLED && (System.getProperty("ONLINE_JUDGE") != null);
    private final static String SYSTEM_ENCODING="utf-8";
    private final static int DEFAULT_BUFFER_SIZE=100000;

    private static class Logger{
        private final PrintWriter logWriter=Util.newPrintWriter(System.err,true);
        private final DecimalFormat df=new DecimalFormat("0.000");
        private void message(String type, String message, Object ... params){
            if(ONLINE_JUDGE){
                return;
            }
            logWriter.printf("["+type+"] "+df.format((System.currentTimeMillis()-START_TIME)/1000.0)+": "+message+"\r\n", params);
        }
        public void debug(String message, Object ... params){
            message("DEBUG", message, params);
        }
    }

    public final static class Util{
        public final static String LINE_SEPARATOR=System.getProperty("line.separator");
        public static PrintWriter newPrintWriter(OutputStream out, boolean autoFlush){
            try {
                return new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(out), SYSTEM_ENCODING),autoFlush);
            } catch (UnsupportedEncodingException e) {
                throw new IllegalStateException(e);
            }
        }

        public static PrintWriter newPrintWriter(Writer writer, boolean autoFlush){
            return new PrintWriter(writer,autoFlush);
        }

        private static void flushStringBuilder(Writer writer, StringBuilder sb) throws IOException {
            if(sb.length()>DEFAULT_BUFFER_SIZE){
                writer.append(sb);
                sb.setLength(0);
            }
        }

        public static void printArray(Writer writer, Object ... elements) throws IOException{
            StringBuilder sb = new StringBuilder();
            boolean first=true;
            for(Object o:elements){
                if(first){
                    first=false;
                }else{
                    sb.append(" ");
                }
                sb.append(o);
                flushStringBuilder(writer, sb);
            }
            sb.append(LINE_SEPARATOR);
            writer.append(sb);
        }
        public static void printArray(Writer writer, int ... elements) throws IOException{
            StringBuilder sb = new StringBuilder();
            boolean first=true;
            for(Object o:elements){
                if(first){
                    first=false;
                }else{
                    sb.append(" ");
                }
                sb.append(o);
                flushStringBuilder(writer, sb);
            }
            sb.append(LINE_SEPARATOR);
            writer.append(sb);
        }

    }

    public final static class FastScanner{
        private BufferedReader reader;
        private StringTokenizer currentTokenizer;
        public FastScanner(Reader reader) {
            if(reader instanceof BufferedReader){
                this.reader=(BufferedReader) reader;
            }else{
                this.reader=new BufferedReader(reader);
            }
        }

        public String next(){
            if(currentTokenizer==null || !currentTokenizer.hasMoreTokens()){
                try {
                    currentTokenizer=new  StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new IllegalStateException(e);
                }
            }

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

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

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

    }

    private final static Logger log=new Logger();
    private final BufferedReader reader;
    private final FastScanner in;
    private final PrintWriter out;

    public C(Reader reader, Writer writer){
        this.reader=new BufferedReader(reader);
        this.out=new PrintWriter(writer,false);
        in=new FastScanner(this.reader);
    }

    public static void main(String[] args) throws IOException {
        new C(new InputStreamReader(System.in, SYSTEM_ENCODING),new OutputStreamWriter(new BufferedOutputStream(System.out), SYSTEM_ENCODING)).run();
    }

    public void run(){
        log.debug("Started");
        try{
            solve();
            out.flush();
        }finally{
            log.debug("Stopped");
        }
    }

    private void solve(){
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int endCount=(n-m)/(k-1);
        if((n-m)%(k-1)!=0){
            endCount++;
        }
        int beginCount=m-endCount;

        if(beginCount<0){
            beginCount=0;
        }
        int div=1000000009;
        long score=getScore2(k,div,beginCount);
        score+=endCount*(k-1);

        long x = Math.max(0, m - (n - n % k) / k * (k-1) - n % k);

        long result = ((exponentiationBySquaring(2, x+1, div)-2)*k + m-x*k)%div;
        if(result<0){
            result+=div;
        }
        out.println(result);
    }

    /**
     * @return
     */
    private long getScore(int k, int div, int beginCount) {
        long score=0;

        for(int i=0;i<beginCount/k;i++){
            score=(score+k)*2;
            if(score>div){
                score=score%div;
            }
        }
        return (score+beginCount%k)%div;
    }

    private long getScore2(int k, int div, int beginCount) {
        long result = (exponentiationBySquaring(2,(beginCount/k)+1,div)-2)*k+beginCount%k;
        return result;
    }
    long pow(long value, long pow, long div){
        long result=1;
        for(int i=0;i<pow;i++){
            result=(result*value)%div;
        }
        return result;
    }
    private static long exponentiationBySquaring(long number, long pow, long mod) {
        final int MAX_BIT=62;
        long mask=1l<<MAX_BIT;
        long result=1l;
        boolean modEnabled=mod>0;
        while(mask>0){
            result*=result;
            if(modEnabled){
                result%=mod;
            }
            if((mask&pow)!=0){
                result*=number;
            }
            if(modEnabled){
                result%=mod;
            }
            mask>>=1;
        }
        return result;
    }

}

/* package whatever; // don't place package name! */

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

/* Name of the class has to be "Main" only if the class is public. */
public class Main
{
    static int a;
    static int b;
    static int n;
    static List<Integer>goodNumbers=new ArrayList<>();
    static int maxNum;

	public static void main (String[] args) throws java.lang.Exception
	{
		// your code goes here
		MyScanner sc = new MyScanner();
	  out = new PrintWriter(new BufferedOutputStream(System.out));
	  long n=sc.nextLong();
	  long m=sc.nextLong();
	  long k=sc.nextLong();
	  long rem=n-n/k;
	  long mod=1000000009;
	  if(m>rem){
	     long d=m-rem;

	      long ans=2*(pow(2,d,mod)-1);

	      ans%=mod;
	      ans*=k;

	      ans%=mod;
	      ans+=(m-(k*d)%mod);
	      out.println(ans%mod);
	  }
	  else
	  out.println(m);

	  out.close();
	}
	public static long pow(long x,long y,long mod){
	    long res=1;
	    while(y>0){
	        if((y&1)==1)
	        {
	            res*=x;
	            res%=mod;
	        }
	        y>>=1;
	        x*=x;
	        x%=mod;
	    }
	    return res;
	}

public static PrintWriter out;
	   //-----------MyScanner class for faster input----------
   public static class MyScanner {
      BufferedReader br;
      StringTokenizer st;

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

      String next() {
          while (st == null || !st.hasMoreElements()) {
              try {
                  st = new StringTokenizer(br.readLine());
              } catch (IOException e) {
                  e.printStackTrace();
              }
          }
          return st.nextToken();
      }

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

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

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

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

   }
}

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
    public long MOD = (long)1e9 + 9;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long N = in.nextLong();
        long M = in.nextLong();
        long K = in.nextLong();

        long left = M - (N / K * (K - 1) + N % K);
        if (left <= 0) {
            out.println(M);
            return;
        }

        long single = M - left * K;
        long res = ((powMod(2, left + 1) - 2 + MOD) % MOD * K % MOD + single) % MOD;
        out.println(res);
    }

    private long powMod(long a, long b) {
        if(b == 0) return 1;
        long res = powMod(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1)
            res = res * a % MOD;
        return res;
    }
}

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

public class Main {

    public static void main(String arg[]) throws IOException {

        // BufferedReader r=new BufferedReader(new FileReader("testcase.txt"));
        BufferedReader r = new BufferedReader(new InputStreamReader(System.in));
        PrintWriter p = new PrintWriter(System.out, false);

        StringTokenizer str;

        str = new StringTokenizer(r.readLine());
       int n=Integer.parseInt(str.nextToken());
       int m=Integer.parseInt(str.nextToken());
       int k=Integer.parseInt(str.nextToken());

     int d=n/k;
     d=(d*(k-1))+(n%k);

     if(m<=d)
         p.println(m);
     else
     {
         long mod=1000000009;
          d=m-d;
         long b=0;
         BigInteger two=new BigInteger("2");
         two=two.modPow(BigInteger.valueOf(d),BigInteger.valueOf(mod));
         two=two.subtract(BigInteger.ONE);
        b=b+two.longValue();
        b=b%mod;
         b=(((b*k)%mod)*2)%mod;
         b=b+(m-(d*k));
         b=b%mod;
       p.println(b);
     }

       p.flush();
}

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

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

public class A2 {
/*

 */
    public static void main(String[] args) throws Exception {
        uu.s1();
        uu.out.close();
    }
    public static class uu {
        public static BR in = new BR();
        public static PrintWriter out = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
        public static boolean bg = true;
        public static MOD m1 = new MOD(1000000000+9);
        public static long mod = 1000000000+9;
        public static void s1() throws Exception {
            long n = in.ni();
            long m = in.ni();
            long k = in.ni();
            long lose = n - m;
            long aval = m / (k - 1l);
            long times1 = Math.min(lose, aval);
            long notused = times1 * (k - 1l);
            long used = m - notused;
            long blocks = used / k;
            long left = used % k;
            long k1 = 0;
            if (blocks != 0){
                k1 = m1.pow(2, blocks+1);
                k1 = m1.s(k1, 2);
            }
            long ans = (m1.t(k, k1)+left + notused)%mod;
            pn(ans);
        }
        public static void geom(long f1){
        }

        public static void s2() throws Exception {

        }
        public static void s3() throws Exception {

        }

        private static void pn(Object... o1) {
            for (int i = 0; i < o1.length; i++){
                if (i!= 0) out.print(" ");
                out.print(o1[i]);
            }
            out.println();
        }

        public static boolean allTrue(boolean ... l1){
            for (boolean e: l1) if (!e) return false;
            return true;
        }
        public static boolean allFalse(boolean ... l1){
            for (boolean e: l1) if (e) return false;
            return true;
        }
    }
    private static class MOD {
        public long mod = -1;

        public MOD(long k1) {
            mod = k1;
        }

        public long cl(long n1){
            long fin = n1%mod;
            if (fin<0) fin+= mod;
            return fin;
        }

        public long s(long n1, long n2) {
            long k1 = (n1 - n2) % mod;
            if (k1 < 0)
                k1 += mod;
            return k1;
        }

        public long t(long n1, long n2) {
            long k1 = (n1 * n2) % mod;
            if (k1 < 0)
                k1 += mod;
            return k1;
        }

        public static long xgcd(long n1, long n2) {
            long k1 = n1;
            long k2 = n2;
            long[] l1 = { 1, 0 };
            long[] l2 = { 0, 1 };
            for (;;) {
                long f1 = k1 / k2;
                long f2 = k1 % k2;
                if (f2 == 0)
                    break;

                long[] l3 = { 0, 0 };
                l3[0] = l1[0] - f1 * l2[0];
                l3[1] = l1[1] - f1 * l2[1];
                l1 = l2;
                l2 = l3;

                k1 = k2;
                k2 = f2;
            }
            long fin = l2[1] % n1;
            if (fin < 0) {
                fin += n1;
            }
            return fin;
        }

        public long pow(long n1, long pow) {
            if (pow == 0)
                return 1;
            else if (pow == 1)
                return t(1l, n1);
            else if ((pow & 1) == 0) {
                long half = pow(n1, pow >> 1);
                return t(half, half);
            } else {
                long half = pow(n1, pow >> 1);
                return t(half, t(half, n1));
            }
        }

        public long factorial(long k1, long n1) {
            long fin = 1;
            long q1 = k1;
            for (int i = 0; i < n1; i++) {
                fin = t(fin, q1);
                q1--;
                if (q1 <= 0)
                    break;
            }
            return cl(fin);
        }

    }

    private static class BR {
        BufferedReader k1 = null;
        StringTokenizer k2 = null;

        public BR() {
            k1 = new BufferedReader(new InputStreamReader(System.in));
        }
        public String nx() throws Exception {
            for (;;) {
                if (k2 == null || !k2.hasMoreTokens()) {
                    String temp = k1.readLine();
                    if (temp == null)
                        return null;
                    k2 = new StringTokenizer(temp);
                }
                else
                    break;
            }

            return k2.nextToken();
        }

        public int ni() throws Exception {
            return Integer.parseInt(nx());
        }
    }
}

import java.math.BigInteger;
import java.util.Scanner;

public class Problem337C {

    public static void main(String[] args) {
        Scanner in = new Scanner(System.in);
        final long MOD = 1000000009;
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();
        long max_m = n / k * (k - 1) + (n % k);
        long d = m - max_m;
        long res = 0;
        if (d > 0) {
            m -= d * k;
            res = 2;
            //d++;
            while (d>0){
                if (d>20){
                res <<= 20;
                d-=20;
                } else {
                    res <<=d;
                    d=0;
                }
                res%=MOD;
            }

            res+=(MOD - 2);
            res%=MOD;
            res*=k;
            res%=MOD;

        }
        res += m;
        res %= MOD;
        System.out.println(res);
    }
}

import java.util.Scanner;
import java.math.BigInteger;
public class Quiz337C {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int questions = input.nextInt();
        int correct = input.nextInt();
        int multiplier = input.nextInt();

        //long kMinusResult = kMinusOneAssembler(questions, correct, multiplier);
        //int bruteForceResult = bruteForce(questions, correct, multiplier);
        //System.out.printf("The k minus one result is: %d\n",kMinusResult);
        //System.out.printf("The brute force result is: %d\n",bruteForceResult);

        int noMults = (int) Math.floor(questions/multiplier) - (questions - correct);
        if(noMults <= 0)
        {
            System.out.print(correct);
            input.close();
            return;
        }
        int correctsRemaining = correct - (noMults * multiplier);
        BigInteger total = new BigInteger("2");
        BigInteger two = new BigInteger("2");
        BigInteger modulus = new BigInteger("1000000009");
        BigInteger exponent = BigInteger.valueOf(noMults + 1);
        BigInteger correctsBig = BigInteger.valueOf(correctsRemaining);
        BigInteger multiplierBig = BigInteger.valueOf(multiplier);
        //System.out.printf("Exponent: %d\n",exponent.longValue());
        //System.out.printf("Modulus: %d\n",modulus.longValue());
        total = total.modPow(exponent, modulus);
        total = total.subtract(two);

        //System.out.printf("Number of ks: %d\n",total.longValue());

        total = total.multiply(multiplierBig);

        //System.out.printf("Multiplier: %d\n", multiplierBig.longValue());

        //System.out.printf("Value from ks: %d\n",total.longValue());

        total = total.add(correctsBig);

        total = total.mod(modulus);

        input.close();

        System.out.print(total.longValue());

        return;

    }
    /*
    public static long kMinusOneAssembler(int questions, int correct, int multiplier)
    {
        boolean questionAnswers[] = new boolean[questions];
        int index = questions - 1;
        int remainingCorrects = correct;
        int remainingIncorrects = questions - correct;
        int untilMultiplier = multiplier;
        while(remainingCorrects != 0 || remainingIncorrects != 0)
        {
            if(untilMultiplier > 1)
            {
                if(remainingCorrects > 0)
                {
                    questionAnswers[index] = true;
                    untilMultiplier--;
                    remainingCorrects--;
                }
                else
                {
                    questionAnswers[index] = false;
                    untilMultiplier = multiplier;
                    remainingIncorrects--;
                }
            }
            else
            {
                if(remainingIncorrects > 0)
                {
                    questionAnswers[index] = false;
                    untilMultiplier = multiplier;
                    remainingIncorrects--;
                }
                else
                {
                    questionAnswers[index] = true;
                    untilMultiplier = multiplier;
                    remainingCorrects--;
                }
            }
            index--;
        }

        return arrayToScore(questionAnswers, questions, multiplier);
    }

    public static int bruteForce(int questions, int correct, int multiplier)
    {
        return 0;
    }

    public static long arrayToScore(boolean[] answers, int questions, int multiplier)
    {
        long total = 0;
        int index = 0;
        int untilMultiplier = multiplier;
        while(index < questions)
        {
            if(answers[index])
            {
                total++;
                untilMultiplier--;
                if(untilMultiplier == 0)
                {
                    total *= 2;
                    untilMultiplier = multiplier;
                }
            }
            else
            {
                untilMultiplier = multiplier;
            }
            total = total % 1000000009;
            index++;
        }
        return total;
    }
    */
}

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

public class Main {
	static int mod = 1000000009;
	public static void main(String [] args) throws IOException
	{
		BufferedReader br1 = new BufferedReader(new InputStreamReader(System.in));
		String [] data = br1.readLine().split(" ");
		int n = Integer.parseInt(data[0]);
		int m = Integer.parseInt(data[1]);
		int k = Integer.parseInt(data[2]);
		long max = (n/k)*(k-1);
		max = max+ n%k;
		//System.out.println(max);
		if(m<=max)
		{
			System.out.println(m);
			return;
		}
		long left = m - max;
		//System.out.println(left);
		long res;
		res =  ((pow(left+1) -2 + mod)*k)%mod;
		//System.out.println(res);
		res = (res + (m - left*k))%mod;
		System.out.println(res);

	}
	public static long pow(long num)
	{
		long ans=1;
		long p=2;
		while(num>0)
		{
			if((num&1)==1)
				ans=(ans*p)%mod;
			p=(p*p)%mod;
			num>>=1;

		}
		return ans;
	}

}

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

public class Quiz {

    final static int MOD = 1000000009;
    final static long[] pow2 = new long[60];
    static {
        pow2[0] = 2;
        for (int i = 1; i < pow2.length; i++) {
        	pow2[i] = (pow2[i - 1] * pow2[i - 1]) % MOD;
        }
    }

    public static void main(String[] args) {
        MyScanner sc = new MyScanner();

        long N = sc.nextLong();
        long M = sc.nextLong();
        long K = sc.nextLong();

        long W = N - M;
        if (W * K + K - 1 >= N) {
        	System.out.println(M);
        	return;
        }

        long R = N - W * K;
        long D = R / K;
        long L = R % K;
        long goodPart = (K - 1) * W;
        long dblPart = (K * (twoPow(D + 1) - 2 + MOD)) % MOD;
        System.out.println((goodPart + dblPart + L) % MOD);
    }

    public static long twoPow(long n) {
        long ans = 1;
        int idx = 0;
        while (n > 0) {
        	if (n % 2 == 1) {
        		ans = (ans * pow2[idx]) % MOD;
        	}
        	n /= 2;
        	idx++;
        }
        return ans;
    }

    public static class MyScanner {
        BufferedReader br;
        StringTokenizer st;

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

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

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

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

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

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                } catch (IOException e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

import java.util.*;
public class Quiz{
   public static int MOD = 1000000009;
   public static void main(String[] args){
      Scanner sc = new Scanner(System.in);
      long n = sc.nextInt();
      long m = sc.nextInt();
      long k = sc.nextInt();
      long wrong = n - m;
      long total = Math.min(m, (k-1)*wrong);
      m -= (k-1)*wrong;
      if(m>0){
         total += m%k;
         m/=k;
         long s = (k*(exp((m+1))-2))%MOD;
         total = ((total + s) % MOD + MOD) % MOD;
      }
      total %= MOD;
      System.out.println(total);
   }
   public static long exp(long p){
      if(p==0)
         return 1;
      long t = exp(p/2);
      t = (t*t)%MOD;
      if(p % 2 == 1)
         t = (2*t)%MOD;
      return t;
   }
}

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

public class Task implements Runnable {
    static FastReader in;
    static PrintWriter out;

    static final long  MOD = 1000000009;

    static long modpow(long a, long b) {
        long ret = 1;
        for (; b > 0; b >>= 1) {
            if ((b & 1) == 1) {
                ret = ret * a % MOD;
            }
            a = a * a % MOD;
        }
        return ret;
    }

    public void solve() throws IOException {
        long n = in.nextLong();
        long m = in.nextLong();
        long k = in.nextLong();
        long t = Math.max(0, m - n % k - n / k * (k - 1));
        long score = (modpow(2, t + 1) - 2 - t + MOD + MOD) % MOD;
        score = (score * k + m) % MOD;
        out.println(score);
    }

    public void run() {
        try {
            in = new FastReader();
            out = new PrintWriter(System.out);
            solve();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

class FastReader {
    BufferedReader br;
    StringTokenizer in;

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

    FastReader(String filename) {
        try {
            this.br = new BufferedReader(new FileReader(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

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

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

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

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

public class Main {

    FastScanner in;
    PrintWriter out;

    static class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream in) {
            br = new BufferedReader(new InputStreamReader(in));
            st = null;
        }

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

        String nextLine() throws IOException {
            if (st == null || !st.hasMoreTokens())
                return br.readLine();
            StringBuilder result = new StringBuilder(st.nextToken());
            while (st.hasMoreTokens()) {
                result.append(" ");
                result.append(st.nextToken());
            }
            return result.toString();
        }

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

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

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

    }

    void run() throws IOException {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out, false);
        solve();
        out.close();
    }

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

    public void printArr(int[] arr){
        for(int i = 0; i < arr.length; i++){
            out.print(arr[i] + " ");
        }
        out.println();
    }

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

    int mod = 1000000009;

    public long exp_by_square(long x, long e){
        if(e == 0) return 1;
        else if(e == 1) return x % mod;
        else if(e % 2 == 0) return exp_by_square((x * x) % mod, e / 2) % mod;
        else if(e % 2 == 1) return (x * exp_by_square((x * x) % mod, (e - 1) / 2)) % mod;

        return 1;
    }

    public void solve() throws IOException{

        int n = in.nextInt(), m = in.nextInt(), k = in.nextInt();
        int x = Math.max(0, m - n / k * (k - 1) - n % k);

        long ans = ((exp_by_square(2, x + 1) - 2) * k + mod) % mod;

        ans = ans + (m - x * k) % mod;
        out.println(ans % mod);

        return;
    }

}

import java.math.BigInteger;
import java.util.Scanner;

public class Quiz {
	static int x = 1000000009;
	static long ModExp(long base,long power)
	{
		if (power == 0)
			return 1;
		if (power == 1)
			return base%x;

		if (power%2==1) {
			return (base*ModExp(base, power-1))%x;
		}
		else
		{
			long intermediate = ModExp(base, power/2)%x;
			return (intermediate*intermediate)%x;
		}
	}
	public static void main(String args[])
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int rightSeq = k-1;
		int a = Math.min(m/rightSeq, n-m);
		int score = Math.min(m,a*(k-1));
		m -= score;
		if (m%k!=0)
		{
			score += m%k;
		}
		System.out.println((x+(ModExp(2, m/k+1)-2)*k+score)%x);
	}
}

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

public class Solver {

    StringTokenizer st;
    BufferedReader in;
    PrintWriter out;

    public static void main(String[] args) throws NumberFormatException,
            IOException {
        Solver solver = new Solver();
        long time = System.currentTimeMillis();
        solver.open();
        solver.solve();
        //System.out.println("Spend time:" + (System.currentTimeMillis() - time));
        solver.close();
    }

    public void open() throws IOException {
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(new OutputStreamWriter(System.out));
    }

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

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

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

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

    long MOD = 1000000009l;

    long pow(long a, long n) {
        if (n==0) return 1;
        if ((n&1)==1){
            return a*pow(a,n-1)%MOD;
        }else{
            long b = pow(a,n/2);
            return b*b%MOD;
        }
    }

    public void solve() throws NumberFormatException, IOException {
        int n = nextInt();
        int m = nextInt();
        int k = nextInt();

        long maxComboCount = n / k;
        long needCombos = Math.max(maxComboCount - (n - m), 0);

        long result = (k*((pow(2, needCombos+1)+MOD-2)%MOD) + (m-k*needCombos)%MOD) % MOD;

        out.println(result);
    }

    public void close() {
        out.flush();
        out.close();
    }
}

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;

/**
 *
 * @author WIN7
 */
public class Challenges {
    static long d = 1000000009;
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long n = sc.nextInt();
        long m = sc.nextInt();
        long k = sc.nextInt();
        long y = ((n - m) * k) % d;
        long x = n - y;
        long z = x / k;
        long t = x % k;
        long c = 2 * k * ( bigpow(z) - 1);
        c = c % d;
        c = (c + t) % d;
        long points = (y - (n - m)) % d + c % d;
        if (n < k * (n - m + 1)) {
            System.out.println(m);
        } else {
            System.out.println(points%d);
        }
    }

    static long bigpow(long x){
        if(x==0) return 1;
        long r = bigpow(x/2);
        if( (x&1) ==1 ) return r*r*2%d;
        return r*r%d;
    }

    static class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        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 boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {

            public boolean isSpaceChar(int ch);
        }
    }

    static class OutputWriter {

        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(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.io.BufferedReader;
import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.InputStream;

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

class TaskA {

    int MOD = 1000000009;

    public void solve(int testNumber, InputStreamReader inSt, PrintWriter out) {
        InputReader in = new InputReader(inSt);
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();

        long t = find(n, m, k);

        long twoPow = binPow(2, (int) t);
        twoPow--;

        long result = (2 * (k * twoPow % MOD)) % MOD;

        result += (m - t * k);
        result = result % MOD;

        out.println(result);
    }

    int binPow(int a, int n) {
        if (n == 0) {
            return 1;

        }

        if (n % 2 == 1) {
            return (int) ((binPow(a, n - 1) * (a+ 0l)) % MOD);
        } else {
            int b = (binPow(a, n / 2)) % MOD;

            return (int) (((b+0l) * b) % MOD);
        }
    }

    long find(long n, long m, long k) {
        long l = 0;
        long r = m / k;
        while (l < r) {
            long mid = (l + r) / 2;

            long m1 = m - mid * k;
            long n1 = n - mid * k;

            if (isPossible(n1, m1, k)) {
                r = mid;
            } else {
                l = mid + 1;
            }
        }

        return l;
    }

    boolean isPossible(long n, long m, long k) {
        long r = m / (k - 1);
        long q = m - (k - 1) * r;

        if (q == 0) {
            return r * (k - 1) + r - 1 <= n;
        }

        return r * (k - 1) + q + r <= n;
    }

    class InputReader {
        public BufferedReader reader;
        private String[] currentArray;
        int curPointer;

        public InputReader(InputStreamReader inputStreamReader) {
            reader = new BufferedReader(inputStreamReader);
        }

        public String next() {
            try {
                currentArray = null;
                return reader.readLine();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public void nextChars(char[] t) {
            try {
                currentArray = null;
                reader.read(t);
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public char nextChar() {
            try {
                currentArray = null;
                return (char) reader.read();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
        }

        public int nextInt() {
            if ((currentArray == null) || (curPointer >= currentArray.length)) {
                try {
                    currentArray = reader.readLine().split(" ");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                curPointer = 0;
            }
            return Integer.parseInt(currentArray[curPointer++]);
        }

        public long nextLong() {
            if ((currentArray == null) || (curPointer >= currentArray.length)) {
                try {
                    currentArray = reader.readLine().split(" ");
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
                curPointer = 0;
            }
            return Long.parseLong(currentArray[curPointer++]);
        }

    }
}

import java.io.*;
import java.util.*;
public final class quiz
{
    static BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
	static FastScanner sc=new FastScanner(br);
    static PrintWriter out=new PrintWriter(System.out);
	static long mod=(long)(1e9+9);
	static long[][] base=new long[][]{{2,0},{2,1}},val;

	static long[][] matrix_pow(long[][] base,long b)
	{
		long[][] res=new long[][]{{1,0},{0,1}};
		while(b>0)
		{
			if(b%2==1)
			{
				res=matrix_mul(res,base,2,2,2,2);
			}
			base=matrix_mul(base,base,2,2,2,2);
			b=b/2;
		}
		return res;
	}

	static long[][] matrix_mul(long[][] a,long[][] b,int r1,int c1,int r2,int c2)
	{
		long[][] c=new long[r1][c2];
		for(int i=0;i<r1;i++)
		{
			for(int j=0;j<c2;j++)
			{
				for(int k=0;k<c1;k++)
				{
					c[i][j]=(c[i][j]+(a[i][k]*b[k][j]))%mod;
				}
			}
		}
		return c;
	}

	public static void main(String args[]) throws Exception
	{
		long n=sc.nextLong(),m=sc.nextLong(),k=sc.nextLong(),low=0,high=m/k;val=new long[][]{{0,k}};
		while(low<high)
		{
			long mid=(low+high)>>1,p_left=m-(k*mid),req=(p_left/(k-1))+(((p_left)%(k-1)==0)?0:1),curr=p_left+(req-1);
			if((k*mid)+curr<=n)
			{
				high=mid;
			}
			else
			{
				low=mid+1;
			}
		}
		base=matrix_pow(base,low);long[][] res=matrix_mul(val,base,1,2,2,2);long ans=(res[0][0]+(m-(k*low)))%mod;out.println(ans);out.close();
	}
}
class FastScanner
{
    BufferedReader in;
    StringTokenizer st;

    public FastScanner(BufferedReader in) {
        this.in = in;
    }

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

	public String next() throws Exception {
		return nextToken().toString();
	}

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

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

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

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

public class Main
{
    public static long Pow(long x,long n)
    {
        final long Mod = (long)(1e9) + 9;
        long ans = 1;
        while( n != 0)
        {
            if(n % 2 == 1)
            {
                ans = ans * x % Mod;
            }
            x = x * x % Mod;
            n >>= 1;
        }
        return ans;
    }
    public static void main(String[] args)
    {
        final long Mod = (long)(1e9) + 9;
        Scanner cin = new Scanner(System.in);
        long i,j,n,m,k;
        while(cin.hasNext())
        {
            n = cin.nextLong();
            m = cin.nextLong();
            k = cin.nextLong();
            long sum = 0;
            long count = n / k * (k - 1) + n % k;
            if(count >= m)
            {
                System.out.println(m);
                continue;
            }
            long res = m - count;
            sum = (m - k * res) % Mod;
            sum = ((sum + (Pow(2 , res) - 1)*2*k%Mod)%Mod + Mod)%Mod;
            System.out.println(sum);
        }
    }
}

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

public class C
{
    public static void main(String[]args)
    {
        InputStream inputStream = System.in;
        OutputStream outputStream = System.out;
        InputReader in = new InputReader(inputStream);
        PrintWriter out = new PrintWriter(outputStream);
        TaskC solver = new TaskC();
        solver.solve(1,in,out);
        out.close();
    }
}

class TaskC
{
    static long mod = 1000000009;

    long mulMod( long a, long b )
    {
        return ((a%mod)*(b%mod))%mod;
    }

    long expMod( long base, long p )
    {
        if(p==0) return 1;
        long ret = expMod(base,p>>1);
        ret = mulMod(ret,ret);
        if( (p&1) == 1 ) ret = mulMod(ret,base);
        return ret;
    }

    boolean test( long n, long m, long k )
    {
        return (k*(m/(k-1)) + m%(k-1) - ((m%(k-1) == 0)?1:0) <= n);
    }

    long n,m,k;

    public void solve(int testNumber, InputReader in, PrintWriter out)
    {
        n = in.nextInt();
        m = in.nextInt();
        k = in.nextInt();

        long l = 0, r = Math.min(n/k,m/k);
        while(r>l)
        {
            long mid = (l+r)>>1;
            if(test(n-mid*k,m-mid*k,k)) r = mid;
            else l = mid+1;
        }

        long foo = (expMod(2,l+1)-2+mod)%mod;
        out.println((k*foo + (m - l*k) + mod) % mod);
    }
}

class InputReader
{
    public BufferedReader reader;
    public StringTokenizer tokenizer;
    public InputReader(InputStream stream){
        reader = new BufferedReader(new InputStreamReader(stream), 32768);
        tokenizer = null;
    }
    public String next(){
        while (tokenizer == null || !tokenizer.hasMoreTokens()){
            try{
                tokenizer = new StringTokenizer(reader.readLine());
            }
            catch (IOException e){
                throw new RuntimeException(e);
            }
        }
        return tokenizer.nextToken();
    }
    public int nextInt() {
        return Integer.parseInt(next());
    }
}

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

public class cf337c {
  static long mod,n,m,k;
  public static void main(String[] args) {
    FastIO in = new FastIO(), out = in;
    n = in.nextLong();
    m = in.nextLong();
    k = in.nextLong();
    mod = (long)1e9 + 9;
    long x = m - (n-n%k)/k * (k-1) - n%k;
    if(x < 0) x = 0;
    long ans = (pow(2,x+1)-2)*k + m-x*k;
    ans = ((ans%mod)+mod)%mod;
    out.println(ans);
    out.close();
  }
  static long pow(long x, long p) {
    if(p == 0) return 1%mod;
    long ans = pow(x,p/2);
    ans = (ans*ans)%mod;
    if(p%2 == 1) ans = (ans*x)%mod;
    return ans;
  }
  static class FastIO extends PrintWriter {
    BufferedReader br;
    StringTokenizer st;

    public FastIO() {
      this(System.in,System.out);
    }
    public FastIO(InputStream in, OutputStream out) {
      super(new BufferedWriter(new OutputStreamWriter(out)));
      br = new BufferedReader(new InputStreamReader(in));
      scanLine();
    }
    public void scanLine() {
      try {
        st = new StringTokenizer(br.readLine().trim());
      } catch(Exception e) {
        throw new RuntimeException(e.getMessage());
      }
    }
    public int numTokens() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return numTokens();
      }
      return st.countTokens();
    }
    public String next() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return next();
      }
      return st.nextToken();
    }
    public double nextDouble() {
      return Double.parseDouble(next());
    }
    public long nextLong() {
      return Long.parseLong(next());
    }
    public int nextInt() {
      return Integer.parseInt(next());
    }
  }
}

import java.awt.Label;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.StringTokenizer;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class C {

	public static long mod_pow(long pow, long mod){
		if(pow == 0){
			return 1;
		}else if(pow % 2 == 0){
			final long ret = mod_pow(pow / 2, mod) % mod;
			return (ret * ret) % mod;
		}else{
			return (mod_pow(pow - 1, mod) * 2) % mod;
		}
	}

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

		final long MOD = 1000000009;

		final long n = sc.nextLong();
		final long m = sc.nextLong();
		final long k = sc.nextLong();

		final long free = (n / k) * (k - 1) + n % k;
		/*
		for(int i = 0; i < 10; i++){
			System.out.println(i + " : " + mod_pow(i, MOD));
		}
		*/
		if(free >= m){
			System.out.println(m % MOD);
		}else{
			final long sum = (((2 * k * (mod_pow(m - free, MOD) - 1L)) % MOD) + (m - (m - free) * k))% MOD;
			System.out.println(sum);
		}

	}

	public static class Scanner {

		private BufferedReader br;
		private StringTokenizer tok;

		public Scanner(InputStream is) throws IOException{
			br = new BufferedReader(new InputStreamReader(is));
			getLine();
		}

		private void getLine() throws IOException{
			while(tok == null || !tok.hasMoreTokens()){
				tok = new StringTokenizer(br.readLine());
			}
		}

		private boolean hasNext(){
			return tok.hasMoreTokens();
		}

		public int nextInt() throws IOException{
			if(hasNext()){
				return Integer.parseInt(tok.nextToken());
			}else{
				getLine();
				return Integer.parseInt(tok.nextToken());
			}
		}

		public long nextLong() throws IOException{
			if(hasNext()){
				return Long.parseLong(tok.nextToken());
			}else{
				getLine();
				return Long.parseLong(tok.nextToken());
			}
		}

		public double nextDouble() throws IOException{
			if(hasNext()){
				return Double.parseDouble(tok.nextToken());
			}else{
				getLine();
				return Double.parseDouble(tok.nextToken());
			}
		}
	}
}

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

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

    static class TaskC {
        int mod = 1000000009;

        public void solve(int testNumber, InputReader in, PrintWriter out) {
            int n = in.nextInt();
            int m = in.nextInt();
            int k = in.nextInt();
            long ans = 0;
            if (n - m >= m / (k - 1)) {
                ans = m;
            } else {
                long cuts = n - m;
                ans += (cuts * (k - 1)) % mod;
                ans += ((m - cuts * (k - 1)) % k) % mod;
                long pow = (m - (cuts * (k - 1)) - (m - cuts * (k - 1)) % k) / k;
                ans += ((modPow(2, pow + 1, mod) - 2) * k) % mod;
                ans %= mod;
                if (ans < 0) {
                    ans += mod;
                }
            }
            out.println(ans);
        }

        long modPow(long x, long y, long m) {
            long exp = y;
            long base = x % m;
            long ans = 1;
            while (exp > 0) {
                if (exp % 2 == 1) {
                    ans = (ans * base) % m;
                }
                base = (base * base) % m;
                exp = exp >> 1;
            }
            return ans;
        }

    }

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

        public InputReader(InputStream inputStream) {
            reader = new BufferedReader(new InputStreamReader(inputStream));
        }

        private void fillTokenizer() {
            if (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (Exception e) {
                    throw new RuntimeException(e);
                }
            }
        }

        public String next() {
            fillTokenizer();
            return tokenizer.nextToken();
        }

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

    }
}

import java.util.Scanner;

public class Main {

    final static long Mod = 1000000009;
    static long n, m, k, t, l, u, ans;
    static Scanner cin = new Scanner(System.in);

    static long multi_mod(long base, long cur) {
        long res = 1;
        while(cur > 0) {
            if(cur % 2 == 1) res = (res * base) % Mod;
            cur >>= 1;
            base = (base * base) % Mod;
        }
        return res;
    }

    public static void main(String[] args) {
        n = cin.nextLong(); m = cin.nextLong(); k = cin.nextLong();
        l = (k - 1)*(n / k) + n % k;
        if(m <= l) {
            System.out.println(m);
        }
        else {
            t = n / k;
            u = m - l;
            ans = (0 + (t - u) * (k - 1) + n % k) % Mod;
            ans = (ans + ((k)*((multi_mod(2, u + 1) - 2 + Mod) % Mod)) % Mod) % Mod;
            System.out.println(ans);
        }
    }
}

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

public class Solve6 {

    public static void main(String[] args) throws IOException {
        PrintWriter pw = new PrintWriter(System.out);
        new Solve6().solve(pw);
        pw.flush();
        pw.close();
    }
    final int MOD = (int) 1E+9 + 9;

    public void solve(PrintWriter pw) throws IOException {
        FastReader sc = new FastReader();
        int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
        int low = 0, high = n;
        long ans = 0;
        while (low <= high) {
            int mid = (low + high) >> 1;
            if ((long) mid * k > m) {
                high = mid - 1;
                continue;
            }
            long x = check(n, m, k, mid);
            if (x == -1) {
                low = mid + 1;
            } else {
                ans = x;
                high = mid - 1;
            }
        }
        pw.println(ans);
    }

    public long check(int n, int m, int k, int mid) {
        int temp = n - mid * k;
        int x = mid * k + (temp / k) * (k - 1) + temp % k;
        if (x < m) {
            return -1;
        } else {
            long y = (long) (power(2, mid + 1) - 2 + MOD) % MOD;
            y *= k;
            y %= MOD;
            y += m - mid * k;
            y %= MOD;
            return y;
        }
    }

    public long power(long a, long n) {
        if (n == 1) {
            return a;
        }
        long y = power(a, n / 2);
        y %= MOD;
        if ((n & 1) == 1) {
            return ((y * y) % MOD) * a;
        } else {
            return y * y;
        }
    }

    static class FastReader {

        StringTokenizer st;
        BufferedReader br;

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

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

        public boolean hasNext() throws IOException {
            if (st != null && st.hasMoreTokens()) {
                return true;
            }
            String s = br.readLine();
            if (s == null || s.isEmpty()) {
                return false;
            }
            st = new StringTokenizer(s);
            return true;
        }

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

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

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

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

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

public class Solution {
    final static int MOD = (int)1e9 + 9;

    long pow(long a, long n) {
        long ret = 1;
        while (n > 0) {
            if ((n & 1) == 1) {
                ret *= a;
                ret %= MOD;
            }
            a *= a;
            a %= MOD;
            n >>= 1;
        }
        return ret;
    }

    long solve(long n, long m, long k) {
        if (k * (n - m + 1) - 1 >= n) {
            return m;
        }
        long a = n - k * (n - m);
        return (2L * k * pow(2, a / k) % MOD + (MOD - 2L * k % MOD) + (a % k) + (k - 1) * (n - m) % MOD) % MOD;
    }

    public void run() {
        try {
            int n = reader.nextInt();
            int m = reader.nextInt();
            int k = reader.nextInt();
            writer.println(solve(n, m, k));
        } catch (IOException ex) {
        }
        writer.close();
    }

    InputReader reader;
    PrintWriter writer;

    Solution() {
        reader = new InputReader();
        writer = new PrintWriter(System.out);
    }

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

}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader() {
        reader = new BufferedReader(new InputStreamReader(System.in));
        tokenizer = new StringTokenizer("");
    }

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

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

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

public class Problem2 {

	public static void main(String[] args){
		// TODO Auto-generated method stub
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		long MOD = 1000000009;
		long n = in.nextLong(), m= in.nextLong(), k = in.nextLong();
		long x = Math.max(0, m - (n/k)*(k-1) - n%k);
		long a = modExp(2, x + 1, MOD);
		//out.println(a);
		long ans = ( (a - 2) * (k % MOD) + m % MOD - (x%MOD) * (k%MOD) ) % MOD;
		if(ans < 0)
		{
			ans = ans + MOD;
		}
		out.println(ans);
		out.close();

	}

	static long modExp( long a, long b,  long MOD)
	{
		long ans = 1;
		String s = Long.toBinaryString(b);
		for(int i = 0; i < s.length(); ++i)
		{
			ans = (ans * ans) % MOD;
			if(s.charAt(i) == '1')
			{
				ans = (ans * a) % MOD;
			}
		}
		return ans;
	}

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

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

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

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

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

	}

}

import java.util.Scanner;

public class Main {
    static int mod = 1000000009;

    public static int pow(int n, int x) {
        if (x == 0)
            return 1;
        if (x % 2 == 0) {
            int temp = pow(n, x / 2) % mod;
            long ans = ((long)(temp) * temp) % mod;
            return (int) ans;
        } else {
            int temp = pow(n, x / 2) % mod;
            long ans = ((long)(temp) * temp * n) % mod;
            return (int) ans;
        }
    }

    public static void main(String[] args) {
        // System.out.println(p ow(2,3,4223));
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int temp = (m / (k - 1)) - 1;
        if (temp < n - m)
            System.out.println(m);
        else {
            long single = (k - 1) * (n - m);
            int remain = (int) (m - single);
            single += remain % k;
            remain -= remain % k;
            long t = pow(2, remain / k + 1);
            t -= 2;
            if(t<0)
                t=(t+mod)%mod;
        //  System.out.println(t);
        //  System.out.println(t);
            t *= k;
            t = (t + single) % 1000000009;
            System.out.println(t);
        }
    }
}

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

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

	public static long pow(long a, long n, long mod)
	{
//		a %= mod;
		long ret = 1;
		int x = 63-Long.numberOfLeadingZeros(n);
		for(;x >= 0;x--){
			ret = ret * ret % mod;
			if(n<<63-x<0)ret = ret * a % mod;
		}
		return ret;
	}

	void solve()
	{
		int n = ni(), m = ni(), K = ni();
		if(m <= n/K*(K-1)+n%K){
			out.println(m);
		}else{
			int mod = 1000000009;
			int f = m - (n/K*(K-1)+n%K);
			out.println(((pow(2, f+1, mod) + mod - 2) * K + (m - f*K)) % mod);
		}
	}

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

public class Main implements Runnable {

	public void solve() throws IOException {
		int N = nextInt(), W = nextInt(), K = nextInt();
                int L = N - W;
                //System.err.println(L + "  " + K);
                if(L * (long) K - 1 >= N){
                    System.out.println(W);
                    return;
                }

                long MOD = 1000000009;
                long a = N - (L) *(long)(K);
                long answer = (2L * K * pow(2, a / K, MOD) + ((MOD - 2) * K) % MOD + (a % K) + (L * (K-1))) % MOD;

                System.out.println(answer);
	}

        public long pow(long n, long p, long MOD){
            long res = 1;
            while(p > 0){
                if((p & 1) == 1)
                    res = (res * n) % MOD;
                p >>= 1;
                n = (n * (long)n) % MOD;
            }

            return res;
        }

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

        public void print1Int(int[] a){
                for(int i = 0; i < a.length; i++)
                        System.out.print(a[i] + " ");
                System.out.println();
        }

        public void print2Int(int[][] a){
                for(int i = 0; i < a.length; i++){
                        for(int j = 0; j < a[0].length; j++){
                                System.out.print(a[i][j] + " ");
                        }
                        System.out.println();
                }
        }

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			tok = null;
			solve();
			in.close();
		} catch (IOException e) {
			System.exit(0);
		}
	}

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

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

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

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

	BufferedReader in;
	StringTokenizer tok;
}

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.ObjectInputStream.GetField;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.HashSet;
import java.util.InputMismatchException;
import java.util.LinkedList;
import java.util.Queue;
import java.util.Stack;
import java.util.TreeMap;
import java.util.TreeSet;

public class Q21 {
	static long MOD = 1000000009;
	static boolean b[];
	static ArrayList<Integer>[] amp;
	static int sum[],dist[];
	static long ans = 0;
	static int p = 0;
	static FasterScanner sc = new FasterScanner();
	static Queue<Integer> q = new LinkedList<>();
	static ArrayList<String>[] arr;
	static ArrayList<Integer> parent = new ArrayList<>();
	static BufferedWriter log;
	static HashMap<Long,Long> hm;
	static HashSet<String> hs = new HashSet<>();
	static Stack<Integer> s = new Stack<>();
	static Pair prr[];
	public static void main(String[] args) throws IOException {
		log = new BufferedWriter(new OutputStreamWriter(System.out));
		long n = sc.nextLong(), m = sc.nextLong(), k = sc.nextLong();
		long x = n-m+1;
		if(m<=(k-1)*x){
			System.out.println(m);
		}
		else{
			long h = (m-(k-1)*(x-1));
			long temp1 = h/k, temp2 = h%k;
			long ans = ((((2*k)%MOD)*(power(2,temp1,MOD)-1+MOD))%MOD+((k-1)*(x-1))%MOD+temp2)%MOD;
			//System.out.println((((2*k)%MOD)*power(2,temp1,MOD))%MOD+" "+temp1+" "+temp2+" "+x+" "+ans);
			System.out.println(ans);
		}

		log.close();
	}
	static long power(long x, long y, long m)
	{
	    if (y == 0)
	        return 1;
	    long p = power(x, y/2, m) % m;
	    p = (p * p) % m;

	    return (y%2 == 0)? p : (x * p) % m;
	}
	private static void permutation(String prefix, String str) {
	    int n = str.length();
	    if (n == 0) hs.add(prefix);
	    else {
	        for (int i = 0; i < n; i++)
	            permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i+1, n));
	    }
	}
	public static char give(char c1,char c2){
		if(c1!='a' && c2!='a') return 'a';
		if(c1!='b' && c2!='b') return 'b';
		return 'c';
	}
	static class Graph{
		int vertex;
		long weight;
	}
	public static void buildTree(int n){
		int arr[] = sc.nextIntArray(n);
		for(int i = 0;i<n;i++){
			int x = arr[i]-1;
			amp[i+1].add(x);
			amp[x].add(i+1);
		}
	}
	public static void bfs(int x,long arr[]){

		b[x] = true;
		q.add(x);
		while(!q.isEmpty()){
			int y = q.poll();
			for(int i = 0;i<amp[y].size();i++) {
				if(!b[amp[y].get(i)]){
					q.add(amp[y].get(i));
					b[amp[y].get(i)] = true;
				}
			}
		}
	}

	public static void buildGraph(int n){

		for(int i =0;i<n;i++){
			int x = sc.nextInt(), y = sc.nextInt();
			amp[--x].add(--y);
			amp[y].add(x);
		}
	}

	public static void dfs(int x){
		b[x] = true;
		for(int i =0 ;i<amp[x].size();i++){
			if(!b[amp[x].get(i)]){
				dfs(amp[x].get(i));
			}
		}

	}
	static class Pair implements Comparable<Pair> {
		int u;
		int v;
		int z;
		public Pair(){

		}
		public Pair(int u, int v) {
			this.u = u;
			this.v = v;
		}

		public int hashCode() {
			int hu = (int) (u ^ (u >>> 32));
			int hv = (int) (v ^ (v >>> 32));
			return 31*hu + hv;
		}

		public boolean equals(Object o) {
			Pair other = (Pair) o;
			return (u == other.u && v == other.v);
		}

		public int compareTo(Pair other) {
			return Integer.compare(u, other.u) != 0 ? (Integer.compare(u, other.u)) : (Integer.compare(v, other.v));
		}

		public String toString() {
			return "[u=" + u + ", v=" + v + "]";
		}
	}
	static class SegmentTree{
		int st[];
		SegmentTree(int arr[], int n){
			int size = 4*n+1;
			st = new int[size];
			build(arr,0,n-1,0);
		}
		int build(int arr[], int ss, int se, int si){
			if(ss==se){
				st[si] = arr[ss];
				return st[si];
			}
			int mid = (ss+se)/2;
			st[si] = build(arr,ss,mid,si*2+1)^build(arr,mid+1,se,si*2+2);
			return st[si];
		}
		int getXor(int qs, int qe, int ss, int se, int si){
			if(qe<ss || qs>se){
				return 0;
			}
			if(qs<=ss && qe>=se) return st[si];
			int mid = (ss+se)/2;
            return getXor(qs,qe,ss,mid,2*si+1)^getXor(qs,qe, mid+1, se, 2*si+2);
		}
		void print(){
			for(int i = 0;i<st.length;i++){
				System.out.print(st[i]+" ");
				System.out.println("----------------------");
			}
		}
	}
	static int convert(int x){
		int cnt = 0;
		String str = Integer.toBinaryString(x);
		//System.out.println(str);
		for(int i = 0;i<str.length();i++){
			if(str.charAt(i)=='1'){
				cnt++;
			}
		}
		int ans = (int) Math.pow(3, 6-cnt);
		return ans;
	}
	static class Node2{
		Node2 left = null;
		Node2 right = null;
		Node2 parent = null;
		int data;
	}
	static class BinarySearchTree{
		Node2 root = null;
		int height = 0;
		int max = 0;
		int cnt = 1;
		ArrayList<Integer> parent = new ArrayList<>();
		HashMap<Integer, Integer> hm = new HashMap<>();
		public void insert(int x){
			Node2 n = new Node2();
			n.data = x;
			if(root==null){
				root = n;
			}
			else{
				Node2 temp = root,temp2 = null;
				while(temp!=null){
					temp2 = temp;
					if(x>temp.data) temp = temp.right;
					else temp = temp.left;
				}
				if(x>temp2.data) temp2.right = n;
				else temp2.left = n;
				n.parent = temp2;
				parent.add(temp2.data);
			}
		}
		public Node2 getSomething(int x, int y, Node2 n){
			if(n.data==x || n.data==y) return n;
			else if(n.data>x && n.data<y) return n;
			else if(n.data<x && n.data<y) return getSomething(x,y,n.right);
			else return getSomething(x,y,n.left);
		}
		public Node2 search(int x,Node2 n){
			if(x==n.data){
				max = Math.max(max, n.data);
				return n;
			}
			if(x>n.data){
				max = Math.max(max, n.data);
				return search(x,n.right);
			}
			else{
				max = Math.max(max, n.data);
				return search(x,n.left);
			}
		}
		public int getHeight(Node2 n){
			if(n==null) return 0;
			height = 1+ Math.max(getHeight(n.left), getHeight(n.right));
			return height;
		}
	}
	static long findDiff(long[] arr, long[] brr, int m){
		int i = 0, j = 0;
		long fa = 1000000000000L;
		while(i<m && j<m){
			long x = arr[i]-brr[j];
			if(x>=0){
				if(x<fa) fa = x;
				j++;
			}
			else{
				if((-x)<fa) fa = -x;
				i++;
			}
		}
		return fa;
	}
	public static long max(long x, long y, long z){
		if(x>=y && x>=z) return x;
		if(y>=x && y>=z) return y;
		return z;
	}

	public static void seive(long n){
		b = new boolean[(int) (n+1)];
		Arrays.fill(b, true);
		for(int i = 2;i*i<=n;i++){
			if(b[i]){
				for(int p = 2*i;p<=n;p+=i){
					b[p] = false;
				}
			}
		}
	}
	static long modInverse(long a, long mOD2){
	            return  power(a, mOD2-2, mOD2);
	}

	static long power2(long x,BigInteger y,long m){
		long ans = 1;
		BigInteger two = new BigInteger("2");
		while(y.compareTo(BigInteger.ZERO)>0){
			if(y.getLowestSetBit()==y.bitCount()){
				x = (x*x)%MOD;
				y = y.divide(two);
			}
			else{
				ans = (ans*x)%MOD;
				y = y.subtract(BigInteger.ONE);
			}
		}
		return ans;
	}
	static BigInteger power2(BigInteger x, BigInteger y, BigInteger m){
		BigInteger ans = new BigInteger("1");
		BigInteger one  = new BigInteger("1");
		BigInteger two  = new BigInteger("2");
		BigInteger zero  = new BigInteger("0");
		while(y.compareTo(zero)>0){
			//System.out.println(y);
			if(y.mod(two).equals(one)){
				ans = ans.multiply(x).mod(m);
				y = y.subtract(one);
			}
			else{
				x = x.multiply(x).mod(m);
				y = y.divide(two);
			}
		}
		return ans;
	}
	static BigInteger power(BigInteger x, BigInteger y, BigInteger m)
	{
	    if (y.equals(0))
	        return (new BigInteger("1"));
	    BigInteger p = power(x, y.divide(new BigInteger("2")), m).mod(m);
	    p = (p.multiply(p)).mod(m);

	    return (y.mod(new BigInteger("2")).equals(0))? p : (p.multiply(x)).mod(m);
	}
	static long d,x,y;
	public static void extendedEuclidian(long a, long b){
		if(b == 0) {
	        d = a;
	        x = 1;
	        y = 0;
	    }
	    else {
	        extendedEuclidian(b, a%b);
	        int temp = (int) x;
	        x = y;
	        y = temp - (a/b)*y;
	    }
	}

	public static long gcd(long n, long m){
		if(m!=0) return gcd(m,n%m);
		else return n;
	}

	public static class FasterScanner {
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

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

		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 String nextString() {
			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 long nextLong() {
			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 int nextInt() {
			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 int[] nextIntArray(int n) {
	        return nextIntArray(n, 0);
	    }

	    public int[] nextIntArray(int n, int off) {
	    	int[] arr = new int[n + off];
	    	for (int i = 0; i < n; i++) {
	    		arr[i + off] = nextInt();
	    	}
	    	return arr;
	    }

	    public long[] nextLongArray(int n) {
	    	return nextLongArray(n, 0);
	    }

		public long[] nextLongArray(int n, int off) {
		    long[] arr = new long[n + off];
		    for (int i = 0; i < n; i++) {
		        arr[i + off] = nextLong();
		    }
		    return arr;
		}

	    private 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;
		}
	}
}

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

public class Main {

	static long n , m , k , mod = 1000000009;

	static long powMod(long b,long pow)
	{
		if(b==0)return 0;
		if(pow==0)return 1;
		long h = powMod(b, pow/2)%mod;
		long ans = (h%mod * h%mod)%mod;
		if(pow%2!=0)ans=(ans%mod*b%mod)%mod;
		return ans%mod;
	}

	static long g(long x)
	{
		long ans =powMod(2, x+1)-2;
		if(ans<0)ans+=mod;
		ans = (ans%mod)*(k%mod);
		return ans%mod;
	}

	static long f(long x)
	{
		long consec = (x/k)*k;
		long ans = g(consec/k)%mod + (x-consec)%mod;
		return ans%mod;
	}

	static long solve()
	{
		long availBB = n-m , trgtBB = m/(k-1) -1;
		if(m%(k-1)!=0)trgtBB++;
		if(availBB>=trgtBB)
			return m%mod;
		else return f(m-((k-1)*availBB))%mod + (((k-1)%mod)*(availBB%mod))%mod;
	}

	public static void main(String[] args) throws IOException {
		Scanner sc = new Scanner(System.in);
		n = sc.nextLong() ; m = sc.nextLong() ; k = sc.nextLong();
		System.out.println(solve()%mod);
	}

	static class Scanner
	{
		StringTokenizer st;
		BufferedReader br;
		public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}
		public Scanner(String s) throws FileNotFoundException {br = new BufferedReader(new FileReader(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 String nextLine() throws IOException {return br.readLine();}
		public long nextLong() throws IOException {return Long.parseLong(next());}
		public double nextDouble() throws IOException {return Double.parseDouble(next());}
		public char nextChar() throws IOException{return next().charAt(0);}
		public boolean ready() throws IOException {return br.ready();}
		public int[] nextIntArr() throws IOException{
			st = new StringTokenizer(br.readLine());
			int[] res = new int[st.countTokens()];
			for (int i = 0; i < res.length; i++)
				res[i] = nextInt();
			return res;
		}
		public char[] nextCharArr() throws IOException{
			st = new StringTokenizer(br.readLine());
			char[] res = new char[st.countTokens()];
			for (int i = 0; i < res.length; i++)
				res[i] = nextChar();
			return res;
		}
	}

}

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

public class Template {
	public static void main(String[] args) throws IOException {
		st = new StringTokenizer(rd.readLine());
		n = Long.parseLong(st.nextToken());
		m = Long.parseLong(st.nextToken());
		k = Long.parseLong(st.nextToken());
		long s = n - m;
		s = Math.min(s, m / (k - 1));
		s = Math.min(s, n / k);
		long score = 0;
		score = (s * (k - 1))%P;
		long n1 = n - k * s, m1 = m - (k - 1) * s;
		sc = 0;
	//	rec(n, m);
	//	System.out.println(sc);
		if (m1 == n1) {
			score = (score + full(m1)) % P;
			System.out.println(score);
			return;
		}
			score = (score + m1) % P;
			System.out.println(score);
	}

	static long full(long N) {
		long x = N / k, r = N - x * k;
		long powTwo = powMod(2, x + 1) - 2 + 2*P;
		powTwo %= P;
		powTwo = (powTwo * k) % P;
		powTwo = (powTwo + r) % P;
		return powTwo;
	}

	static long sc = 0;

	static void rec(long N, long M){
		if(N==M){ sc = (sc + full(N))%P; return; }
		if(N>=k && M>=k-1){
			sc = (sc + (k-1))%P;
			rec(N-k, M-(k-1));
			return;
		}
		sc = (sc + M)%P;
	}

	static long powMod(long a, long p) {
		if (p == 0)
			return 1L;
		long h = powMod(a, (p >> 1));
		h = (h * h) % P;
		return p % 2 == 0 ? h : (a * h) % P;
	}

	static long n, m, k;

	static long P = 1000000009;

	static StringTokenizer st;
	static BufferedReader rd = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter pw = new PrintWriter(System.out);

}

import java.math.BigInteger;
import java.util.Scanner;

public class ds {

	public static int max = 1000000009;

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);

		int n = in.nextInt();
		int m = in.nextInt();
		int k = in.nextInt();
		int w = n - m;
		if ((long)w*(k-1) >= m) {
			System.out.println(m % max);
		} else {
			long rem = (m%max - (w%max*(k-1)%max)%max)%max;
			long pow = rem / k;
			long rr=(w%max*(k-1)%max)%max;
			BigInteger ans = BigInteger
					.valueOf(rr)
					.mod(BigInteger.valueOf(max))
					.add(BigInteger.valueOf(rem).mod(BigInteger.valueOf(k))
							.mod(BigInteger.valueOf(max)))
					.mod(BigInteger.valueOf(max));
			long ans1 = (2%max * k%max)%max;
			BigInteger kk=BigInteger.valueOf(2).modPow(BigInteger.valueOf(pow), BigInteger.valueOf(max)).subtract(BigInteger.ONE);
			ans = ans.mod(BigInteger.valueOf(max)).add(BigInteger.valueOf(ans1).multiply(kk).mod(BigInteger.valueOf(max))).mod(BigInteger.valueOf(max));
			System.out.println(ans.add(BigInteger.valueOf(max)).mod(BigInteger.valueOf(max)));
		}

	}

}

import java.io.OutputStreamWriter;
import java.io.BufferedWriter;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.List;
import java.io.IOException;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.ArrayList;
import java.util.NoSuchElementException;
import java.math.BigInteger;
import java.io.InputStream;

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

class TaskC {
	long MOD = IntegerUtils.power(10, 9) + 9;
	public void solve(int testNumber, InputReader in, OutputWriter out){
	    long nquestions = in.ri(), mcorrectlyanswered = in.ri(), kneededtodouble = in.ri();
	    long wrong = nquestions - mcorrectlyanswered;
		long endfinequestions = wrong * kneededtodouble;
		long beginningbadquestionsallinrow = nquestions - endfinequestions;
		if (beginningbadquestionsallinrow < 0){
			out.printLine(mcorrectlyanswered);
			return;
		}
		long curscore = 0;
		long addend = beginningbadquestionsallinrow - (beginningbadquestionsallinrow / kneededtodouble)*kneededtodouble;
		long timesdouble = beginningbadquestionsallinrow / kneededtodouble;
		curscore += IntegerUtils.power(2, timesdouble + 1, MOD) - 2 + MOD;
		curscore *= kneededtodouble;
		curscore %= MOD;
		long res = curscore + (mcorrectlyanswered - beginningbadquestionsallinrow) + addend;
		out.printLine(res % MOD);
	}
}

class IntegerUtils {
	public static long power(long base, long exponent) {
		if (exponent == 0)
			return 1;
		long result = power(base, exponent >> 1);
		result = result * result;
		if ((exponent & 1) != 0)
			result = result * base;
		return result;
	}

	public static long power(long base, long exponent, long mod) {
		if (base >= mod)
			base %= mod;
		if (exponent == 0)
			return 1 % mod;
		long result = power(base, exponent >> 1, mod);
		result = result * result % mod;
		if ((exponent & 1) != 0)
			result = result * base % mod;
		return result;
	}
}

class InputReader {
	private InputStream stream;
	private byte[] buf = new byte[1024];
	private int curChar;
	private int numChars;
	private SpaceCharFilter filter;

	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 ri(){
		return readInt();
	}

	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 boolean isSpaceChar(int c) {
		if (filter != null)
			return filter.isSpaceChar(c);
		return isWhitespace(c);
	}

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

class OutputWriter {
	private final PrintWriter writer;

	public OutputWriter(OutputStream outputStream) {
		writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(outputStream)));
	}
	public void close() {
		writer.close();
	}
	public void printLine(long i) {
		writer.println(i);
	}
}

import static java.lang.System.in;
import static java.lang.System.out;

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

public class C337quiz {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	long MAX = 1000000009;

	long pow (long n, long k){
		if (k==0) return 1;
		long res = pow(n, k/2);
		res = (res*res)%MAX;
		if (k%2==1) res = (res*n)%MAX;
		return (long)res;
	}

	public void run() throws IOException {
		String input;
		String[] inputArray;
		input = br.readLine();
		inputArray = input.split(" ");

		long n = Long.valueOf(inputArray[0]);
		long m = Long.valueOf(inputArray[1]);
		long k = Long.valueOf(inputArray[2]);
		long t = n/k;
		long ans = m;
		if (m>(t*(k-1) + n%k)){
			long r = m - (t*(k-1) + n%k);
			ans = (ans + (pow(2,r+1)-r-2 + MAX)*k) %MAX;
		}
		sb.append(ans);
		ln(sb);
	}

	public static void main(String[] args) throws IOException {
		new C337quiz().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}

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

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

class TaskA {
    int mod = 1000000009;

    public void solve(int testNumber, Parser in, OutputWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();

        int o = m;
        m -= n - (n/k);
        if (m < 0) m = 0;

        long temp = n/k;
        long ans;
        if (m == 0) ans = 0;
        else {
            ans = (MathUtils.modpow(2, m+1, mod) + mod - 2) % mod;
            ans = (ans * k) % mod;
        }

        out.println((ans + (o - m*k)) % mod);
    }
}

class Parser
{
    private BufferedReader din;
    private StringTokenizer tokenizer;

    public Parser(InputStream in)
    {
        din = new BufferedReader(new InputStreamReader(in));
        tokenizer = null;
    }

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

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

    }

class OutputWriter extends PrintWriter {
    public OutputWriter(Writer out) {
        super(out);
    }

    public OutputWriter(OutputStream out) {
        super(out);
    }

    }

class MathUtils {

    public static long modpow(int b, int e, int m) {
        if (e == 0) return 1%m;
        else if (e == 1) return b%m;

        long temp = modpow(b, e/2, m);
        temp = (temp * temp) % m;
        if (e % 2 == 1) temp = (temp * b) % m;

        return temp;
    }

    }

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

public class Main {
    static final int mod = (int) (1e9 + 9);

    public static void main(String[] args) throws IOException {
        Scanner sc = new Scanner(System.in);
        PrintWriter out = new PrintWriter(System.out);
        int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
        int extra = n % k;
        m -= extra;
        n -= extra;
        int ans = extra;
        int min = m - (n / k) * (k - 1);
        if (min <= 0) out.println(m+extra);
        else {
             ans += m - (min * k);
            ans = (int) ((ans + 1l * k * (modPow(2, min + 1) - 2)) % mod);
            while (ans < 0) ans += mod;
            out.println(ans);
        }
        out.close();
        out.flush();
    }

    static int modPow(int b, int e) {
        int res = 1;
        while (e > 0) {
            if ((e & 1) == 1) res = (int) ((1l * res * b) % mod);
            b = (int) ((1l * b * b) % mod);
            e >>= 1;
        }
        return res;
    }

    static class Scanner {
        StringTokenizer st;
        BufferedReader br;

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

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

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

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

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

        public char nextChar() throws IOException {
            return next().charAt(0);
        }

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

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

        public int[] nextIntArray(int n) throws IOException {
            int[] a = new int[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public long[] nextLongArray(int n) throws IOException {
            long[] a = new long[n];
            for (int i = 0; i < n; i++)
                a[i] = nextLong();
            return a;
        }

        public Integer[] nextIntegerArray(int n) throws IOException {
            Integer[] a = new Integer[n];
            for (int i = 0; i < n; i++)
                a[i] = nextInt();
            return a;
        }

        public double[] nextDoubleArray(int n) throws IOException {
            double[] ans = new double[n];
            for (int i = 0; i < n; i++)
                ans[i] = nextDouble();
            return ans;
        }

        public short nextShort() throws IOException {
            return Short.parseShort(next());
        }

    }

}

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

public class Quiz {
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        long n = Long.parseLong(st.nextToken());
        long m = Long.parseLong(st.nextToken());
        long k = Long.parseLong(st.nextToken());
        long mod = 1000000009;
        long d = n-m;
        n -= d*k;
        if (n <= 0)
        {
            System.out.println(m);
            return;
        }
        long sum = (n%k) + d*(k-1);
        sum += 2*k*(pow(2,n/k,mod)-1);
        sum %= mod;
        System.out.println(sum);
    }

    public static long pow(long a, long n, long mod)
    {
        if (n == 0)
            return 1;
        long pow = pow(a,n/2,mod);
        pow = (pow*pow) % mod;
        if (n % 2 == 1)
            pow = (pow*a) % mod;
        return pow;
    }
}

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

public class A {

	static final int mod = (int)1e9 + 9;

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

		int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
		long delta = Math.floorDiv(m - 1l *(n - m + 1) * (k - 1) + k - 1, k);
		if(delta <= 0)
			out.println(m);
		else
		{
			long score = m + (powMod(2, delta + 1) - (delta + 2)) * k;
			out.println((score % mod + mod) % mod);
		}
		out.flush();
		out.close();
	}

	static long powMod(long b, long e)
	{
		long r = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				r = r * b % mod;
			b = b * b % mod;
			e >>= 1;
		}
		return r;
	}

	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 double nextDouble() throws IOException { return Double.parseDouble(next()); }

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

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author BSRK Aditya
 */
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);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long numQuestions = in.nextInt();
        long numCorrectlyAnsweredQuestions = in.nextInt();
        long sizeForDoublingScore = in.nextInt();

        long score = 0;

        long numIncorrectlyAnsweredQuestions = numQuestions - numCorrectlyAnsweredQuestions;

        long numDoublings = Math.max(numQuestions / sizeForDoublingScore - numIncorrectlyAnsweredQuestions, 0);
        score += 2*sizeForDoublingScore*Long.parseLong(new BigInteger("2").modPow(new BigInteger(String.valueOf(numDoublings)), new BigInteger("1000000009")).subtract(BigInteger.ONE).toString());
        score += numCorrectlyAnsweredQuestions - sizeForDoublingScore*numDoublings;
        score %= 1000000009;

        out.println(score);
    }
}

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C337_1
{

	public static long mod = 1000000009;
	public static long INF = (1L << 60);
	static FastScanner2 in = new FastScanner2();
	static OutputWriter out = new OutputWriter(System.out);

	public static void main(String[] args)
	{

		long n=in.nextInt();
		long m=in.nextInt();
		long k=in.nextInt();
		long minX=max(0, m-((n-n%k)/k)*(k-1)-n%k);
		long answer=(pow(2, minX+1, mod)-2)*k+m-minX*k;
		answer=(answer%mod+mod)%mod;
		out.println(answer);
		out.close();

	}

	public static long pow(long x, long n)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p))
		{
			if ((n & 1) != 0)
			{
				res = (res * p);
			}
		}
		return res;
	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FastScanner2
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

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

		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 String nextString()
		{
			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 long nextLong()
		{
			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 int nextInt()
		{
			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 int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private 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 InputReader
	{
		public BufferedReader reader;
		public StringTokenizer tokenizer;

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

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

		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[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextLong();
			}
			return a;
		}

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

	static class OutputWriter
	{
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(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 println(Object... objects)
		{
			print(objects);
			writer.println();
		}

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

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

}

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

public class A {

	private long pow(long num, long pow, long mod) {
		if (pow <= 0) {
			return 1;
		}
		if ((pow & 1) != 0) {
			return (num * pow(num, pow-1, mod)) % mod;
		}
		else {
			long tmp = pow(num, pow>>1, mod) % mod;
			return (tmp*tmp)%mod;
		}
	}

	public void run() {
		long MOD = 1000000009;
		long n = nextInt();
		long m = nextInt();
		long k = nextInt();

		long critical = n/k;
		if (n-critical >= m) {
			out.println(m);
		}
		else {
			long doubles = m - (n-critical);
			long ans = (pow(2, doubles + 1, MOD) - 2 + MOD)%MOD;
			ans = (ans * k)%MOD;
			ans = (ans + (m-(doubles*k)))%MOD;
			out.println(ans);
		}
		out.flush();
	}

	private static BufferedReader br = null;
	private static StringTokenizer stk = null;
	private static PrintWriter out = null;

	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		(new A()).run();
	}

	private void loadLine() {
		try {
			stk = new StringTokenizer(br.readLine());
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	private int nextInt() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return Integer.parseInt(stk.nextToken());
	}

	private long nextLong() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return Long.parseLong(stk.nextToken());
	}

	private double nextDouble() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return Double.parseDouble(stk.nextToken());
	}

	private String nextWord() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return (stk.nextToken());
	}

}

//package codeforces;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.Closeable;
import java.io.FileReader;
import java.io.FileWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.PriorityQueue;
import java.util.Queue;
import java.util.Set;
import java.util.StringTokenizer;
import java.util.TreeSet;

public class A implements Closeable {
    BufferedReader reader = new BufferedReader(new InputStreamReader(System.in));
    PrintWriter writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));

    A() throws IOException {
//        reader = new BufferedReader(new FileReader("input.txt"));
//        writer = new PrintWriter(new FileWriter("output.txt"));
    }

    StringTokenizer stringTokenizer;

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

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

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

    private int MOD = 1000 * 1000 * 1000 + 7;

    int sum(int a, int b) {
        a += b;
        return a >= MOD ? a - MOD : a;
    }

    int product(int a, int b) {
        return (int) (1l * a * b % MOD);
    }

    int pow(int x, int k) {
        int result = 1;
        while (k > 0) {
            if (k % 2 == 1) {
                result = product(result, x);
            }
            x = product(x, x);
            k /= 2;
        }
        return result;
    }

    int inv(int x) {
        return pow(x, MOD - 2);
    }

    void solve() throws IOException {
        MOD = 1000 * 1000 * 1000 + 9;
        int n = nextInt(), m = nextInt(), k = nextInt();
        if(n == m) {
            int groups = n / k;
            int tail = n % k;
            int answer = sum(product(pow(2, groups + 1), k), MOD - product(2, k));
            answer = sum(answer, tail);
            writer.println(answer);
            return;
        }
        int o = n - m;
        long grouped = 1l * k * o;
        if(grouped >= n) {
            writer.println(m);
            return;
        }
        int tail = (int)(n - grouped);
        int groups = tail / k;
        tail = tail % k;
        int answer = sum(product(pow(2, groups + 1), k), MOD - product(2, k));
        answer = sum(answer, tail);
        answer = sum(answer, o * (k - 1));
        writer.println(answer);
    }

    public static void main(String[] args) throws IOException {
        try (A a = new A()) {
            a.solve();
        }
    }

    @Override
    public void close() throws IOException {
        reader.close();
        writer.close();
    }
}

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

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;
        }
    }
    public static long mod=1000000009,N=1000000009;
    static long exponentiation(long base, long exp)
    {
        if (exp == 0)
            return 1;
        if (exp == 1)
            return base % N;
        long t = exponentiation(base, exp / 2);
        t = (t * t) % N;
        if (exp % 2 == 0)
            return t;
        else
            return ((base % N) * t) % N;
    }
    public static void main(String[] args)throws Exception
    {
        InputReader in=new InputReader(System.in);
        PrintWriter w=new PrintWriter(System.out);
        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long[] power=new long[10000000];
        long ng=(n/k);
        if(n==m)
        {
            //long x=n/k;
            long x=(long)Math.max(0, m - (n - n%k) / k * (k-1) - n%k);
            long num=0,count=0;
            num=(((((exponentiation(2L,x+1L)%mod-(2%mod)+mod)%mod)*(k%mod))%mod + m)%mod - ((x%mod)*(k%mod))%mod+mod)%mod;
            w.println(num);
        }
        else
        {
            if(n%k==(k-1))
                ng++;
            if(ng*(k-1)>=m)
            {
                w.println(m);
            }
            else
            {
                long score=0;
                long x=(long)Math.max(0, m - (n - n%k) / k * (k-1) - n%k);
                long count=0;
                //w.println(x);
                score=(((((exponentiation(2L,x+1L)%mod-(2%mod)+mod)%mod)*(k%mod))%mod + m)%mod - ((x%mod)*(k%mod))%mod+mod)%mod;

                w.println(score);
            }
        }
        w.close();
    }
}

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

/**
 * Created by jizhe on 2016/2/3.
 */
public class Quiz {
    private static int bs1(int N, int M, int K)
    {
        int lo = 0, hi = N/K;

        while( lo <= hi )
        {
            int mid = lo+(hi-lo)/2;
            int m = mid*(K-1);
            int n = mid*K;
            if( N-n < M-m )
            {
                hi = mid-1;
            }
            else if( N-n > M-m )
            {
                lo = mid+1;
            }
            else
            {
                return mid;
            }
        }

        return hi;
    }

    private static int bs2(int N, int M, int K, int hi)
    {
        int lo = 0;

        while( lo <= hi )
        {
            int mid = lo+(hi-lo)/2;
            int m = mid*(K-1);

            if( m < M )
            {
                lo = mid+1;
            }
            else if( m > M )
            {
                hi = mid-1;
            }
            else
            {
                return mid;
            }
        }

        return hi;
    }

    private static long fastPowMod(long a, long b, long MOD)
    {
        long result = 1;

        while( b > 0 )
        {
            if( (b&1) == 1 )
            {
                result = (result*a)%MOD;
            }
            a = (a*a)%MOD;
            b /= 2;
        }

        return result;
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));

        int N = in.nextInt();
        int M = in.nextInt();
        int K = in.nextInt();

        long MOD = 1000000009;

        int setKMax = bs1(N, M, K);

        //System.out.printf("setKMax: %d\n", setKMax);

        int setK = bs2(N, M, K, setKMax);

        //System.out.printf("setK: %d\n", setK);

        int m1 = M-setK*(K-1);
        int p = m1/K;

        //System.out.printf("m1: %d, p: %d\n", m1, p);

        long score = fastPowMod(2, p+1, MOD)-2;
        if( score < 0 )
        {
            score += MOD;
        }
        score = (score*K)%MOD;
        score += m1-p*K;
        score = (score+(setK*(K-1))%MOD)%MOD;

        System.out.printf("%d\n", score);
    }
}

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

public class cf337c {
  static long mod,n,m,k;
  public static void main(String[] args) {
    FastIO in = new FastIO(), out = in;
    n = in.nextLong();
    m = in.nextLong();
    k = in.nextLong();
    mod = (long)1e9 + 9;
    long x = m - (n-n%k)/k * (k-1) - n%k;
    if(x < 0) x = 0;
    long ans = (pow(2,x+1)-2)*k + m-x*k;
    ans = ((ans%mod)+mod)%mod;
    out.println(ans);
    out.close();
  }
  static long pow(long x, long p) {
    if(p == 0) return 1%mod;
    long ans = pow(x,p/2);
    ans = (ans*ans)%mod;
    if(p%2 == 1) ans = (ans*x)%mod;
    return ans;
  }
  static class FastIO extends PrintWriter {
    BufferedReader br;
    StringTokenizer st;

    public FastIO() {
      this(System.in,System.out);
    }
    public FastIO(InputStream in, OutputStream out) {
      super(new BufferedWriter(new OutputStreamWriter(out)));
      br = new BufferedReader(new InputStreamReader(in));
      scanLine();
    }
    public void scanLine() {
      try {
        st = new StringTokenizer(br.readLine().trim());
      } catch(Exception e) {
        throw new RuntimeException(e.getMessage());
      }
    }
    public int numTokens() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return numTokens();
      }
      return st.countTokens();
    }
    public String next() {
      if(!st.hasMoreTokens()) {
        scanLine();
        return next();
      }
      return st.nextToken();
    }
    public double nextDouble() {
      return Double.parseDouble(next());
    }
    public long nextLong() {
      return Long.parseLong(next());
    }
    public int nextInt() {
      return Integer.parseInt(next());
    }
  }
}

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

public class A
{
	private static Scanner sc;

	public static boolean works(int n, int m, int k, int mid)
	{
		int maxQuestions = 0 < mid ? mid - 1 : 0;

		int t = n - mid;
		int q = t / k;
		int r = t % k;
		maxQuestions += q*(k - 1) + r;

		return maxQuestions >= m;
	}
	public static int index(int n, int m, int k)
	{
		int lo = 0;
		int hi = n + 1;

		while(lo < hi)
		{
			int mid = (lo + hi) / 2;

			if(mid == lo)
				break;

			if(works(n, m, k, mid))
			{
				hi = mid;
			}
			else
			{
				lo = mid + 1;
			}
		}

		return works(n, m, k, lo) ? lo : lo + 1;
	}

	public static void main(String... args)
	{
		long mod = 1000000009;

		sc = new Scanner(System.in);
		//5 3 2
		int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();

		int idx = index(n, m, k);
		//System.out.println(idx);
		if(0 < idx)
		{
			idx--;
			long t = idx / k;
			long points = idx % k;
			long right = BigInteger.valueOf(2).modPow(BigInteger.valueOf(t), BigInteger.valueOf(mod)).subtract(BigInteger.ONE).longValue();
			//System.out.println(right);
			points += 2 * k * ((right + mod) % mod);
			points += m - idx;

			System.out.println((points % mod + mod) % mod);
		}
		else
		{
			System.out.println(m % mod);
		}
	}

}

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

public class ManaoQuiz{
	private static long pow(long b, long p, long x){
		if(p==0){
			return (long)1;
		}else if(p%2==0){
			long ans1=pow(b, p/2, x);
			return (ans1*ans1)%x;
		}else{
			long ans1=pow(b, p/2, x);
			return (ans1*ans1*2)%x;
		}
	}
	private static long computePow(long i, long x){
		long ans=(long)2*(pow((long)2, i, x)-(long)1);
		//System.out.println("i:"+i+" x:"+x+" ans:"+ans);
		return ans;
	}
	public static void main(String[] argv) throws Exception{
		BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
		String[] words=br.readLine().trim().split(" ");
		long n, m, k;
		n=Long.parseLong(words[0]); m=Long.parseLong(words[1]); k=Long.parseLong(words[2]);
		long p=n/k;
		long mi=n-m;
		long x=1000000000+9;
		if(p>=mi){
			long q=p-mi;
			//System.out.println("p:"+p+" mi:"+mi+" q:"+q);
			long y1=((computePow(q, x)*k)%x+(mi*(k-1))%x + n%k)%x;
			//long p1=(computePow(q, x)*k), p2=(mi*(k-1)), p3=n%k;
			//System.out.println(p1+","+p2+","+p3);
			System.out.println(y1);
		}else{
			System.out.println(m%x);
		}
	}
}

import java.math.BigInteger;
import java.util.Scanner;

public class ds {

	public static int max = 1000000009;

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);

		int n = in.nextInt();
		int m = in.nextInt();
		int k = in.nextInt();
		int w = n - m;
		if ((long)w*(k-1) >= m) {
			System.out.println(m % max);
		} else {
			long rem = (m%max - (w%max*(k-1)%max)%max)%max;
			long pow = rem / k;
			long rr=(w%max*(k-1)%max)%max;
			BigInteger ans = BigInteger
					.valueOf(rr)
					.mod(BigInteger.valueOf(max))
					.add(BigInteger.valueOf(rem).mod(BigInteger.valueOf(k))
							.mod(BigInteger.valueOf(max)))
					.mod(BigInteger.valueOf(max));
			long ans1 = (2%max * k%max)%max;
			BigInteger kk=BigInteger.valueOf(2).modPow(BigInteger.valueOf(pow), BigInteger.valueOf(max)).subtract(BigInteger.ONE);
			ans = ans.mod(BigInteger.valueOf(max)).add(BigInteger.valueOf(ans1).multiply(kk).mod(BigInteger.valueOf(max))).mod(BigInteger.valueOf(max));
			System.out.println(ans.add(BigInteger.valueOf(max)).mod(BigInteger.valueOf(max)));
		}

	}

}

import java.io.IOException;
import java.io.InputStream;
import java.io.PrintWriter;
import java.util.InputMismatchException;

public class CFFF {
	static PrintWriter out;
	static final int oo = 987654321;
	static final long mod = (long)(1e9)+9;
	public static void main(String[] args) {
		MScanner sc = new MScanner();
		out = new PrintWriter(System.out);

		long N = sc.nextLong();
		long M = sc.nextLong();
		long K = sc.nextLong();

		if(M<=N-N/K)
			out.println(M);
		else{
			long ans = (fastModExpo(2,M-(N-N%K)/K*(K-1)-N%K+1,mod)-2)*K+M-(M-(N-N%K)/K*(K-1)-N%K)*K;
			out.println((mod+ans)%mod);
		}
		out.close();
	}
	static long fastModExpo(int base, long pow, long mod) {
		if (pow == 0)
			return 1L;
		if ((pow & 1) == 1)
			return (base*fastModExpo(base, pow - 1,mod))%mod;
		long temp = fastModExpo(base, pow / 2, mod);
		return (temp*temp)%mod;
	}

	static class MScanner {
		private InputStream stream;
		private byte[] buf = new byte[1024];
		private int curChar;
		private int numChars;

		public MScanner() {
			stream = System.in;
			// stream = new FileInputStream(new File("dec.in"));

		}

		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++];
		}

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

		boolean isEndline(int c) {
			return c == '\n' || c == '\r' || c == -1;
		}

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

		int[] nextInt(int N) {
			int[] ret = new int[N];
			for (int a = 0; a < N; a++)
				ret[a] = nextInt();
			return ret;
		}

		int[][] nextInt(int N, int M) {
			int[][] ret = new int[N][M];
			for (int a = 0; a < N; a++)
				ret[a] = nextInt(M);
			return ret;
		}

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

		long[] nextLong(int N) {
			long[] ret = new long[N];
			for (int a = 0; a < N; a++)
				ret[a] = nextLong();
			return ret;
		}

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

		double[] nextDouble(int N) {
			double[] ret = new double[N];
			for (int a = 0; a < N; a++)
				ret[a] = nextDouble();
			return ret;
		}

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

		String[] next(int N) {
			String[] ret = new String[N];
			for (int a = 0; a < N; a++)
				ret[a] = next();
			return ret;
		}

		String nextLine() {
			int c = read();
			while (isEndline(c))
				c = read();
			StringBuilder res = new StringBuilder();
			do {
				res.appendCodePoint(c);
				c = read();
			} while (!isEndline(c));
			return res.toString();
		}

		String[] nextLine(int N) {
			String[] ret = new String[N];
			for (int a = 0; a < N; a++)
				ret[a] = nextLine();
			return ret;
		}

	}
}

import static java.lang.System.in;
import static java.lang.System.out;

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

public class C337quiz {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	long MAX = 1000000009;

	long pow (long n, long k){
		if (k==0) return 1;
		long res = pow(n, k/2);
		res = (res*res)%MAX;
		if (k%2==1) res = (res*n)%MAX;
		return (long)res;
	}

	public void run() throws IOException {
		String input;
		String[] inputArray;
		input = br.readLine();
		inputArray = input.split(" ");

		long n = Long.valueOf(inputArray[0]);
		long m = Long.valueOf(inputArray[1]);
		long k = Long.valueOf(inputArray[2]);
		long t = n/k;
		long ans = m;
		if (m>(t*(k-1) + n%k)){
			long r = m - (t*(k-1) + n%k);
			ans = (ans + (pow(2,r+1)-r-2 + MAX)*k) %MAX;
		}
		sb.append(ans);
		ln(sb);
	}

	public static void main(String[] args) throws IOException {
		new C337quiz().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}

import java.util.*;

public class CF196_C {

	static long N, M, K;
	final static long DIV = 1000000009;

	public static long longPow(long x, long n)
	{
		long ans;
		if(n == 0)
			return 1;
		if(n%2 == 1)
		{
			ans = longPow(x, n-1)*x;
			return ans%DIV;
		}
		else
		{
			ans = longPow(x, n/2);
			return (ans*ans)%DIV;
		}

	}

	public static long doubleCal(long douTeam)
	{
		long score, r=0;
		score = 0;
		//for(long i=0; i<douTeam; i++)
		//	score = (score+K)*2%DIV;

		r = (long)longPow(2, douTeam);
		score = (r*2)%DIV;
		score = (score-2 + DIV)%DIV;
		score = (score*K)%DIV;
		score %= DIV;

		return score;
	}

	public static void main(String[] args) {
		// TODO Auto-generated method stub

		long wrongNum, teamNum, remaidNum;
		long eachTeamWro, remaidWroNum, douTeam;
		long ans=0;
		Scanner cin = new Scanner(System.in);

		N = cin.nextLong();
		M = cin.nextLong();
		K = cin.nextLong();

		wrongNum = N-M;
		teamNum = N/K;
		remaidNum = N%K;
		eachTeamWro = wrongNum/teamNum;
		remaidWroNum = wrongNum%teamNum;
		douTeam = teamNum - remaidWroNum;
		if(wrongNum == 0)
			ans = doubleCal(douTeam) + remaidNum;
		else if(eachTeamWro!=0)
		{
			ans = M%DIV;
		}
		else
		{
			ans = (doubleCal(douTeam) + N-douTeam*K-wrongNum)%DIV;
		}

		System.out.println(ans);
		cin.close();
	}

}

import java.awt.Label;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.BitSet;
import java.util.Collections;
import java.util.LinkedList;
import java.util.PriorityQueue;
import java.util.Scanner;
import java.util.StringTokenizer;

import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

public class C {

	public static long mod_pow(long pow, long mod){
		if(pow == 0){
			return 1;
		}else if(pow % 2 == 0){
			final long ret = mod_pow(pow / 2, mod) % mod;
			return (ret * ret) % mod;
		}else{
			return (mod_pow(pow - 1, mod) * 2) % mod;
		}
	}

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

		final long MOD = 1000000009;

		final long n = sc.nextLong();
		final long m = sc.nextLong();
		final long k = sc.nextLong();

		final long free = (n / k) * (k - 1) + n % k;
		/*
		for(int i = 0; i < 10; i++){
			System.out.println(i + " : " + mod_pow(i, MOD));
		}
		*/
		if(free >= m){
			System.out.println(m % MOD);
		}else{
			final long sum = (((2 * k * (mod_pow(m - free, MOD) - 1L)) % MOD) + (m - (m - free) * k))% MOD;
			System.out.println(sum);
		}

	}

	public static class Scanner {

		private BufferedReader br;
		private StringTokenizer tok;

		public Scanner(InputStream is) throws IOException{
			br = new BufferedReader(new InputStreamReader(is));
			getLine();
		}

		private void getLine() throws IOException{
			while(tok == null || !tok.hasMoreTokens()){
				tok = new StringTokenizer(br.readLine());
			}
		}

		private boolean hasNext(){
			return tok.hasMoreTokens();
		}

		public int nextInt() throws IOException{
			if(hasNext()){
				return Integer.parseInt(tok.nextToken());
			}else{
				getLine();
				return Integer.parseInt(tok.nextToken());
			}
		}

		public long nextLong() throws IOException{
			if(hasNext()){
				return Long.parseLong(tok.nextToken());
			}else{
				getLine();
				return Long.parseLong(tok.nextToken());
			}
		}

		public double nextDouble() throws IOException{
			if(hasNext()){
				return Double.parseDouble(tok.nextToken());
			}else{
				getLine();
				return Double.parseDouble(tok.nextToken());
			}
		}
	}
}

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

public class A {
	public static void main(String[] args) throws Exception {
		int n=nextInt();
		int m=nextInt();
		int k=nextInt();
		int wa=n-m;
		if(n/k<=wa){
			System.out.println(m);
		}else{
			int notFull=wa;
			int full=n/k-wa;
			long res=1;
			int power=full+1;
			int mod=1000000009;
			long powTwo=2;
			while(power>0){
				if((power&1)==1){
					res=(res*powTwo)%mod;
				}
				power>>=1;
				powTwo=(powTwo*powTwo)%mod;
			}
			res=(((res-2+mod)%mod)*k)%mod;
			res=((res+notFull*(k-1))%mod+n%k)%mod;
			System.out.println(res);
		}
	}
	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));
	static StringTokenizer tokenizer = new StringTokenizer("");

	static int nextInt() throws Exception {
		return Integer.parseInt(next());
	}

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

	static String next() throws Exception {
		while (true) {
			if (tokenizer.hasMoreTokens()) {
				return tokenizer.nextToken();
			}
			String s = br.readLine();
			if (s == null) {
				return null;
			}
			tokenizer = new StringTokenizer(s);
		}
	}
}

//package CF;

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

public class B {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		long n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
		int mod = (int) 1e9 + 9;
		long res = m;
		if (n - m < (m + k - 2) / (k - 1) - 1) {
			long tmp = m - ((n/ k)*(k-1)+n%k);
//			System.out.println(tmp);
			res = (modPow(2, tmp + 1, mod) - 2 + mod) % mod * k % mod;
			res = (res + (m-tmp*k+mod)%mod) % mod;
		}
		out.println(res);
		out.flush();
		out.close();
	}

	static long modPow(long a, long e, int mod) // O(log e)
	{
		a %= mod;
		long res = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner {
		BufferedReader bf;
		StringTokenizer st;

		public Scanner(InputStream i) {
			bf = new BufferedReader(new InputStreamReader(i));

		}

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

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

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double 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 long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
	}
}

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.math.BigInteger;
import java.math.RoundingMode;
public class a {
    public static int vertices=0;
    public static void main(String[] args) {
       Scanner s = new Scanner(System.in);
       long n=s.nextLong();
       long m=s.nextLong();
       long k=s.nextLong();
      if(n*(k-1)>=(long)m*k-1)
          System.out.println(m);
      else{
       BigInteger bi1=new BigInteger(Long.toString((long)(k-1)*(n-m)));
          //System.out.println(bi1);
       BigInteger bi2=new BigInteger(Long.toString((long)m*k-(long)n*(k-1)));
          //System.out.println(bi2);
       BigInteger bi3=bi2.divide(new BigInteger(Long.toString(k)));
       bi1=bi1.add(bi2.mod(new BigInteger(Long.toString(k))));
       BigInteger bi4=new BigInteger("2");
       BigInteger bi5=bi4.modPow(bi3.add(new BigInteger("1")),new BigInteger("1000000009"));
       bi5=bi5.multiply(new BigInteger(Long.toString(k)));
       bi5=bi5.subtract(new BigInteger(Long.toString(2*k)));
       bi1=bi1.add(bi5);
       bi1=bi1.mod(new BigInteger("1000000009"));
          System.out.println(bi1);
      }
   }
}

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

public class Solution {
    final static int MOD = (int)1e9 + 9;

    long pow(long a, long n) {
        long ret = 1;
        while (n > 0) {
            if ((n & 1) == 1) {
                ret *= a;
                ret %= MOD;
            }
            a *= a;
            a %= MOD;
            n >>= 1;
        }
        return ret;
    }

    long solve(long n, long m, long k) {
        if (k * (n - m + 1) - 1 >= n) {
            return m;
        }
        long a = n - k * (n - m);
        return (2L * k * pow(2, a / k) % MOD + (MOD - 2L * k % MOD) + (a % k) + (k - 1) * (n - m) % MOD) % MOD;
    }

    public void run() {
        try {
            int n = reader.nextInt();
            int m = reader.nextInt();
            int k = reader.nextInt();
            writer.println(solve(n, m, k));
        } catch (IOException ex) {
        }
        writer.close();
    }

    InputReader reader;
    PrintWriter writer;

    Solution() {
        reader = new InputReader();
        writer = new PrintWriter(System.out);
    }

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

}

class InputReader {
    BufferedReader reader;
    StringTokenizer tokenizer;

    InputReader() {
        reader = new BufferedReader(new InputStreamReader(System.in));
        tokenizer = new StringTokenizer("");
    }

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

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

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

public class Main
{
    public static long Pow(long x,long n)
    {
        final long Mod = (long)(1e9) + 9;
        long ans = 1;
        while( n != 0)
        {
            if(n % 2 == 1)
            {
                ans = ans * x % Mod;
            }
            x = x * x % Mod;
            n >>= 1;
        }
        return ans;
    }
    public static void main(String[] args)
    {
        final long Mod = (long)(1e9) + 9;
        Scanner cin = new Scanner(System.in);
        long i,j,n,m,k;
        while(cin.hasNext())
        {
            n = cin.nextLong();
            m = cin.nextLong();
            k = cin.nextLong();
            long sum = 0;
            long count = n / k * (k - 1) + n % k;
            if(count >= m)
            {
                System.out.println(m);
                continue;
            }
            long res = m - count;
            sum = (m - k * res) % Mod;
            sum = ((sum + (Pow(2 , res) - 1)*2*k%Mod)%Mod + Mod)%Mod;
            System.out.println(sum);
        }
    }
}

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

public class Solution {

    public static void solve(InputReader in, PrintWriter out, DebugWriter debug) throws IOException {
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();

        long x = Math.max(0, m - (n - n % k) / k * (k-1) - n % k);

        long scoreNoSerial = m-x*k;
        long scoreSerial = ((pow2(x)-1)*k*2) % mod ;

        debug.println(x);
        debug.println(scoreNoSerial);
        debug.println(scoreSerial);

        out.println((scoreSerial+scoreNoSerial) % mod);
    }

    public static long mod = (long) Math.pow(10, 9)+9;

    public static long pow2(long x){
        long[] array2 = new long[64];
        array2[0] = 2;

        for (int i=1; i<array2.length; i++){
            array2[i] = (array2[i-1]*array2[i-1]) % mod;
            //System.out.println( i + ": " + array2[i]);
        }

        long ans = 1;
        String binary = Long.toBinaryString(x);
        //System.out.println("Bin: " + binary);
        for (int i=binary.length()-1; i>=0; i--){
            if (binary.charAt(i) == '1'){
                ans *= array2[binary.length()-1-i];
                ans %= mod;
            }
        }

        //System.out.println("2^" + x + "=" + ans);
        return ans;
    }

    public static void main(String[] args) throws IOException{
        InputReader in;
        PrintWriter out;
        DebugWriter debug;

        if (args.length > 0 && args[0].equals("file")) {
            in = new InputReader(new BufferedReader(new FileReader("input.txt")));
            out = new PrintWriter(new FileWriter("output.txt"));
            debug = new DebugWriter(true);

            int sampleNumber = 1;
            do {
                String nextSample = "Sample #" + sampleNumber++ + ": ";
                out.println(nextSample);
                debug.println(nextSample);

                solve(in, out, debug);

                out.println("");
                debug.println("");
            } while (in.reader.readLine() != null);
        } else {
            in = new InputReader(new BufferedReader(new InputStreamReader(System.in)));
            out = new PrintWriter(new OutputStreamWriter(System.out));
            debug = new DebugWriter(false);

            solve(in, out, debug);
        }

        in.reader.close();
        out.close();
    }

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

        public InputReader(BufferedReader reader) {
            this.reader = reader;
            tokenizer = null;
        }

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

            return tokenizer.nextToken();
        }

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

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

            return array;
        }
    }

    public static class DebugWriter {
        public boolean enable;

        public DebugWriter(boolean enable){
            this.enable = enable;
        }

        public void print(Object o){
            if (enable) System.out.print(o);
        }

        public void println(Object o){
            if (enable) System.out.println(o);
        }
    }

}

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

public class A {
	BufferedReader reader;
    StringTokenizer tokenizer;
    PrintWriter out;

    long MOD = 1000000009;
    public long mod_add(long n1, long n2){
    	return (n1 + n2) % MOD;
    }
    public long mod_time(long n1, long n2){
    	return (n1 * n2) % MOD;
    }
    public long mod_power(long a, int k) {
        if (k == 0) return 1;
        if (k % 2 == 0) return mod_power(a * a % MOD, k / 2);
        return a * mod_power(a, k - 1) % MOD;
	}

	public void solve() throws IOException {
		int N = nextInt();
		int M = N - nextInt(); //wrong
		int K = nextInt();

		int full = N/K - M;
		if( full < 0){
			out.println( N - M );return;
		}
		long ans = mod_time( K * 2, mod_power(2, full) - 1 );
//		out.println( full + ", " + ans );

		ans = mod_add(ans, N-M-full*K );

		out.println( ans );
	}

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		new A().run();
	}

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

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

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

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

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

}

import java.io.*;
import java.math.BigDecimal;
import java.math.BigInteger;
import java.util.*;
import java.awt.Point;

public class CodeForces {
    static boolean ONLINE_JUDGE = System.getProperty("ONLINE_JUDGE") != null;
    private final long MOD = 1000000009;

    long power(long a, long b)
    {
        long res = 1;
        while (b > 0) {
            if ((b & 1) == 1) {
                res *= a;
                if (res >= MOD)
                    res %= MOD;
            }
            a *= a;
            if (a >= MOD)
                a %= MOD;
            b >>= 1;
        }
        return res;
    }

    void runCase(int caseNum) throws IOException {
        long n = nextLong();
        long m = nextLong();
        long k = nextLong();

        if (n - m >= n / k) {
            System.out.println(m);
            return;
        }
        long res = 0;
        long rem = (k - 1) * (n - m);
        m -= rem;
        long bound = m / k;
        res = (power(2, bound + 1) + MOD - 2) % MOD;
        res *= k;
        res %= MOD;
//        for (long i = 0; i < bound; ++i) {
//            res += k;
//            res <<= 1;
//            if (res >= MOD)
//                res %= MOD;
//        }
        res += rem;
        res += m % k;
        res %= MOD;
        System.out.println(res);
    }

    public static void main(String[] args) throws IOException {
        if (ONLINE_JUDGE){
            System.out.println();
            in = new BufferedReader(new InputStreamReader(System.in));
            out = new PrintWriter(System.out);
        }else{
            in = new BufferedReader(new FileReader("input.txt"));
            out = new PrintWriter(System.out);
            //out = new PrintWriter("output.txt");
        }
        new CodeForces().runIt();
        out.flush();
        out.close();
        return;
    }

    static BufferedReader in;
    private StringTokenizer st;
    static PrintWriter out;

    static int pos;
    static String curInput = "";

    String next() throws IOException {
        while (!st.hasMoreTokens()) {
            String line = in.readLine();
            if (line == null) {
                return null;
            }
            st = new StringTokenizer(line);
        }
        return st.nextToken();
    }

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

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

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

    void runIt() throws IOException {
        st = new StringTokenizer("");

//        int N = nextInt();
//        for (int i = 0; i < N; i++) {
//            runCase(i + 1);
//        }
        runCase(0);
        out.flush();
    }

}

import java.util.*;
public class Main {
static long mod = 1000000009L;
public static long modPow(int a){
	if(a==0)
		return 1;
	long temp=modPow(a/2);
	temp=(temp*temp)%mod;
	if(a%2==1)
		temp=2*temp%mod;
		return temp;
}
public static void main(String [] args){
	Scanner in=new Scanner(System.in);
	int n=in.nextInt();
	int m=in.nextInt();
	int k=in.nextInt();
	if(m + n/k <= n){
		System.out.print(m);
		return;
	}
	int full = n/k - (n - m);
	//System.out.println(full);
	long ans = ((modPow(full+1) - 2 + mod)%mod)*k%mod;
	//System.out.println(ans);
	ans += m - k*full;
		System.out.print(ans%mod);
}
}

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

public class Task implements Runnable {
    static FastReader in;
    static PrintWriter out;

    static final long  MOD = 1000000009;

    static long modpow(long a, long b) {
        long ret = 1;
        for (; b > 0; b >>= 1) {
            if ((b & 1) == 1) {
                ret = ret * a % MOD;
            }
            a = a * a % MOD;
        }
        return ret;
    }

    public void solve() throws IOException {
        long n = in.nextLong();
        long m = in.nextLong();
        long k = in.nextLong();
        long t = Math.max(0, m - n % k - n / k * (k - 1));
        long score = (modpow(2, t + 1) - 2 - t + MOD + MOD) % MOD;
        score = (score * k + m) % MOD;
        out.println(score);
    }

    public void run() {
        try {
            in = new FastReader();
            out = new PrintWriter(System.out);
            solve();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

class FastReader {
    BufferedReader br;
    StringTokenizer in;

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

    FastReader(String filename) {
        try {
            this.br = new BufferedReader(new FileReader(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

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

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

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

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.InputMismatchException;

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 = ((long)(N - M)%bigMod * (long)(K - 1)%bigMod)%bigMod;
				long x = (M - ans);
				long y = x / K;
				long z = x % K;
				val = (int) (pow(2, y, bigMod) % bigMod);
				//System.out.println(val);
				ans += ((((2 * (long)(val - 1)) % bigMod) * K) % bigMod + z)
						% bigMod;
				System.out.println(ans%bigMod);
			}
		}

		out.close();
	}

	public static long pow(long a, long b, long 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.io.*;
import java.util.*;

public class Main
{
	public static void main(String[] args) throws IOException
	{
		// int t = ni();
		int t = 1;
		while(t-->0) {
			long n = ni();
			long m = ni();
			long k = ni();
			long rem = n-m-(m%(k-1));
			int parts = (int)Math.ceil(1d*m/(k-1));
			long x = m - (n/k)*(k-1) - n%k;
			if(x<=0){
				System.out.println(m);
			}
			else{
				long score_doubled = ((k*(powm(2,x+1,mod)-2))%mod + mod)%mod;
				// System.out.println(score_doubled);
				long ans = ((score_doubled+(m-k*x))%mod + mod)%mod;
				System.out.println(ans);
			}
		}
	}

	static final int mod=1000000009;
    static StringBuilder ans=new StringBuilder();
	static Reader in=new Reader();
	static final double eps=1e-9;

	//////////////////////////////////
	//input functions/////////////////
	static int ni(){return Integer.parseInt(in.next());}
	static long nl(){return Long.parseLong(in.next());}
	static String ns(){return in.next();}
	static double nd(){return Double.parseDouble(in.next());}
	static int[] nia(int n){int a[]=new int[n];for(int i=0; i<n; i++)a[i]=ni();return a;}
	static int[] pnia(int n){int a[]=new int[n+1];for(int i=1; i<=n; i++)a[i]=ni();return a;}
	static long[] nla(int n){long a[]=new long[n];for(int i=0; i<n; i++)a[i]=nl();return a;}
	static String[] nsa(int n){String a[]=new String[n];for(int i=0; i<n; i++)a[i]=ns();return a;}
	static double[] nda(int n){double a[]=new double[n];for(int i=0; i<n; i++)a[i]=nd();return a;}

	//////output functions////////////////
	static void pr(Object a){ans.append(a+"\n");}
	static void pr(){ans.append("\n");}
	static void p(Object a){ans.append(a);}
	static void pra(int[]a){for(int i:a)ans.append(i+" ");ans.append("\n");}
	static void pra(long[]a){for(long i:a)ans.append(i+" ");ans.append("\n");}
	static void pra(String[]a){for(String i:a)ans.append(i+" ");ans.append("\n");}
	static void pra(double[]a){for(double i:a)ans.append(i+" ");ans.append("\n");}
	static void sop(Object a){System.out.print(a);}
	static void sopln(Object a){System.out.println(a);}
	static void flush(){System.out.print(ans);ans=new StringBuilder();}

	static void exit(){System.out.print(ans);System.exit(0);}
	static int min(int... a){int min=a[0];for(int i:a)min=Math.min(min, i);return min;}
	static int max(int... a){int max=a[0];for(int i:a)max=Math.max(max, i);return max;}
	static int gcd(int... a){int gcd=a[0];for(int i:a)gcd=gcd(gcd, i);return gcd;}
	static long min(long... a){long min=a[0];for(long i:a)min=Math.min(min, i);return min;}
	static long max(long... a){long max=a[0];for(long i:a)max=Math.max(max, i);return max;}
	static long gcd(long... a){long gcd=a[0];for(long i:a)gcd=gcd(gcd, i);return gcd;}
	static String pr(String a, long b){String c="";while(b>0){if(b%2==1)c=c.concat(a);a=a.concat(a);b>>=1;}return c;}
	static long powm(long a, long b, long m){long an=1;long c=a;while(b>0){if(b%2==1)an=(an*c)%m;c=(c*c)%m;b>>=1;}return an;}
	static int gcd(int a, int b){if(b==0)return a;return gcd(b, a%b);}
	static long gcd(long a, long b){if(b==0)return a;return gcd(b, a%b);}

	static class Reader {
        BufferedReader reader;
        StringTokenizer tokenizer;
        public Reader() {
            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
            tokenizer = null;
        }
        String next() {while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {tokenizer = new StringTokenizer(reader.readLine());}
				catch (IOException e) {throw new RuntimeException(e);}}
            return tokenizer.nextToken();}
        int nextInt() {return Integer.parseInt(next());}
        long nextLong() {return Long.parseLong(next());}
        double nextDouble() {return Double.parseDouble(next());}
    }

}

import java.math.BigInteger;
import java.util.Scanner;

public class Quiz {
	static int x = 1000000009;
	static long ModExp(long base,long power)
	{
		if (power == 0)
			return 1;
		if (power == 1)
			return base%x;

		if (power%2==1) {
			return (base*ModExp(base, power-1))%x;
		}
		else
		{
			long intermediate = ModExp(base, power/2)%x;
			return (intermediate*intermediate)%x;
		}
	}
	public static void main(String args[])
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int rightSeq = k-1;
		int a = Math.min(m/rightSeq, n-m);
		int score = Math.min(m,a*(k-1));
		m -= score;
		if (m%k!=0)
		{
			score += m%k;
		}
		System.out.println((x+(ModExp(2, m/k+1)-2)*k+score)%x);
	}
}

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

public class A{

static class Node implements Comparable<Node>{
	int id;
	int x;
	public  Node(int id,int x) {
		this.id=id;
		this.x=x;

	}
	public int compareTo(Node c) {
		return c.x-this.x;
	}
}
//public static PrintWriter pw;
public static PrintWriter pw=new PrintWriter(System.out);
public static void solve() throws IOException{
//	pw=new PrintWriter(new FileWriter("C:\\Users\\shree\\Downloads\\small_output_in"));
	FastReader sc=new FastReader();
	long n=sc.L(); long m=sc.L(); long k=sc.L();
	long x=Math.max(0,m-((n-n%k)/k)*(k-1)-n%k);

	pw.println( (((((modPow(2,x+1,M)-2+M)%M)*k)%M+m)%M-(x*k)%M+M)%M);
	//pw.println((modPow(2,x+1,M)-2 +M)%M );
	pw.close();
}

public static void main(String[] args)  {
    new Thread(null ,new Runnable(){
      public void run(){
          try{

              solve();
          } catch(Exception e){
              e.printStackTrace();
          }
      }
  },"1",1<<26).start();

}

static long modPow(long x,long y,long M){
	if(y==0) return 1;
	if(y%2==0) return modPow((x*x)%M,y/2,M)%M;
	else return (x*modPow((x*x)%M,(y-1)/2,M))%M;
}

static long M=(long)1e9+9;

	static class FastReader {
        BufferedReader br;
        StringTokenizer st;

        public FastReader() throws FileNotFoundException{
            //br=new BufferedReader(new FileReader("C:\\Users\\shree\\Downloads\\B-small-practice.in"));
        	 br = new BufferedReader(new InputStreamReader(System.in));

        }

        String next() {
            while (st == null || !st.hasMoreElements()) {
                try {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e) {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

        int I(){   return Integer.parseInt(next()); }
        long L(){  return Long.parseLong(next()); }
        double D() {  return Double.parseDouble(next()); }
        String nextLine() {
            String str = "";
            try {
                str = br.readLine();
            }
            catch (IOException e) {
                e.printStackTrace();
            }
            return str;
        }
     }
}

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
    public long MOD = (long)1e9 + 9;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long N = in.nextLong();
        long M = in.nextLong();
        long K = in.nextLong();

        long left = M - (N / K * (K - 1) + N % K);
        if (left <= 0) {
            out.println(M);
            return;
        }

        long single = M - left * K;
        long res = ((powMod(2, left + 1) - 2 + MOD) % MOD * K % MOD + single) % MOD;
        out.println(res);
    }

    private long powMod(long a, long b) {
        if(b == 0) return 1;
        long res = powMod(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1)
            res = res * a % MOD;
        return res;
    }
}

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

     public class CodeForces {

        public static void main(String[] args) throws IOException {
            Reader.init(System.in);
            int n = Reader.nextInt(), m = Reader.nextInt(), k = Reader.nextInt();
            int maxD = n/k, z = n - m;
            int x = Math.max(maxD - z, 0);

            System.out.println((((pow(2, x+1) - 2) * k + m-x*k % mod + mod)) % mod);

        }

        static int mod = (int) 1e9 + 9;

        static long pow(long n, long p){
            if(p == 0)
                return 1;

            if((p&1) == 1)
                return (n * pow(n, p-1)) % mod;

            long res = pow(n, p/2);
            return (res * res) % mod;
        }
    }

    class  Edge implements Comparable<Edge>{

        int to;
        int from;
        int cost;

        Edge(int a, int b, int c){
            from = a;
            to = b;
            cost = c;
        }

        @Override
        public int compareTo(Edge t) {
            return t.cost - cost;
        }
    }

    class NN implements Comparable<NN>{
        int mony;
        int f;

        NN(int a, int b){
            mony = a;
            f = b;
        }

        @Override
        public int compareTo(NN t) {
            return mony - t.mony;
        }

    }

    class Reader {

        static BufferedReader reader;
        static StringTokenizer tokenizer;

        public static int pars(String x) {
            int num = 0;
            int i = 0;
            if (x.charAt(0) == '-') {
                i = 1;
            }
            for (; i < x.length(); i++) {
                num = num * 10 + (x.charAt(i) - '0');
            }

            if (x.charAt(0) == '-') {
                return -num;
            }

            return num;
        }

        static void init(InputStream input) {
            reader = new BufferedReader(
                    new InputStreamReader(input));
            tokenizer = new StringTokenizer("");
        }

        static void init(FileReader input) {
            reader = new BufferedReader(input);
            tokenizer = new StringTokenizer("");
        }

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

        static int nextInt() throws IOException {
            return pars(next());
        }

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

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

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

public class Quiz {
    public static int mod = 1000000009;
    public static void main(String[] args) throws IOException {
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        long n = Long.parseLong(st.nextToken());
        long m = Long.parseLong(st.nextToken());
        long k = Long.parseLong(st.nextToken());
        long d = n-m;
        n -= d*k;
        if (n <= 0)
        {
            System.out.println(m);
            return;
        }
        long sum = (n%k) + d*(k-1);
        sum += 2*k*(pow(2,n/k)-1);
        sum %= mod;
        System.out.println(sum);
    }

    public static long pow(long a, long n)
    {
        if (n == 0)
            return 1;
        long pow = pow(a,n/2);
        pow = pow*pow % mod;
        if (n % 2 == 1)
            pow = pow*a % mod;
        return pow;
    }
}

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

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

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

	int mod=(int)1e9+9;

	long n, m, k;

	void run(){
		n=sc.nextLong();
		m=sc.nextLong();
		k=sc.nextLong();
		solve();
	}

	void solve(){
		long ans=0;
		long s=n-m;
		long remain=max(n-s*k, 0);
//		debug("remain", remain);
		ans=m-remain;
//		debug("ans", ans);
		long r=remain%k;
		ans=(ans+r)%mod;
		remain-=r;
//		debug("remain2", remain);
		long a=remain/k;
		long add=(powMod(2, a, mod)-1)*k%mod*2%mod;
//		debug("add", add);
		ans=(ans+add)%mod;
//		debug(ans);
		println(ans+"");
	}

	long powMod(long x, long k, long mod){
		if(k==0){
			return 1%mod;
		}else if(k%2==0){
			return powMod(x*x%mod, k/2, mod);
		}else{
			return x*powMod(x, k-1, mod)%mod;
		}
	}

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

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

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

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

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author BSRK Aditya
 */
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);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();

        BigInteger min_points = BigInteger.ZERO;

        int endBlock = n%k;
        min_points = min_points.add(new BigInteger(String.valueOf(Math.min(endBlock, m))));
        m -= Math.min(endBlock, m);
        n -= n%k;

        int numBlocks = n/k;
        int numDoublings = Math.max(0, numBlocks - (n-m));
        min_points = min_points.add(
                new BigInteger("2")
                        .multiply(new BigInteger(String.valueOf(2)).modPow(new BigInteger(String.valueOf(numDoublings)), new BigInteger(String.valueOf(1000000009))).subtract(BigInteger.ONE))
                        .multiply(new BigInteger(String.valueOf(k))));
        m -= numDoublings*k;
        n -= numDoublings*k;

        min_points = min_points.add(new BigInteger(String.valueOf(m)));

        out.println(min_points.mod(new BigInteger(String.valueOf(1000000009))));
    }
}

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

public class SolutionA{

	public static void main(String[] args){
		new SolutionA().run();
	}
	int mod = 1000000009;

	void solve(){
		int n = in.nextInt();
		int m = in.nextInt();
		int k = in.nextInt();
		long l = 0;
		long r = n;
		long ans = 1;
		long cur = n;
		while(l <= r){
			long mid = (l+r) >> 1;
			long x = (n - mid * k);
			if(mid * k > n || x % k + (x/k) * (k-1) + mid * k >= m) {
				cur =mid;
				r = mid-1;
			}
			else l = mid+1;
		}
		long ost = m - cur * k;
		//out.println(cur);
		//out.println(ost);
		long t = 2;
		cur++;
		while(cur > 0){
			if(cur % 2 == 1){
				ans *= t;
				ans %= mod;
			}
			t = t*t % mod;
			cur/=2;
		}
		ans = (ans - 2 + mod) % mod;
		ans = ans * k % mod;
		out.println((ans + ost) % mod);
	}

	class Pair implements Comparable<Pair>{
		int x, y;
		Pair(int x, int y){
			this.x = x;
			this.y = y;
		}
		@Override
		public int compareTo(Pair o) {
			if(o.x == x) return ((Integer) y).compareTo(o.y);
			return ((Integer) x).compareTo(o.x);
		}

	}
	FastScanner in;
	PrintWriter out;
	void run(){
		in = new FastScanner(System.in);
		out = new PrintWriter(new OutputStreamWriter(System.out));
		solve();
		out.close();
	}

	void runIO(){
		try{
			in = new FastScanner(new File("expr.in"));
			out = new PrintWriter(new FileWriter(new File("expr.out")));
			solve();
			out.close();
		}catch(Exception ex){
			ex.printStackTrace();
		}
	}
	class FastScanner{
		BufferedReader bf;
		StringTokenizer st;
		public FastScanner(File f){
			try{
				bf = new BufferedReader(new FileReader(f));
			}
			catch(IOException ex){
				ex.printStackTrace();
			}
		}
		public FastScanner(InputStream is){
			bf = new BufferedReader(new InputStreamReader(is));
		}
		String next(){
			while(st == null || !st.hasMoreTokens()){
				try{
					st = new StringTokenizer(bf.readLine());
				}
				catch(IOException ex){
					ex.printStackTrace();
				}
			}
			return st.nextToken();
		}
		int nextInt(){
			return Integer.parseInt(next());
		}
		double nextDouble(){
			return Double.parseDouble(next());
		}
		float nextFloat(){
			return Float.parseFloat(next());
		}
		String nextLine(){
			try{
				return bf.readLine();
			}
			catch(Exception ex){
				ex.printStackTrace();
			}
			return "";
		}
		long nextLong(){
			return Long.parseLong(next());
		}
		BigInteger nextBigInteger(){
			return new BigInteger(next());
		}
		BigDecimal nextBigDecimal(){
			return new BigDecimal(next());
		}
		int[] nextIntArray(int n){
			int a[] = new int[n];
			for(int i = 0; i < n; i++)
				a[i] = Integer.parseInt(next());
			return a;
		}
		long[] nextLongArray(int n){
			long a[] = new long[n];
			for(int i = 0; i < n; i++)
				a[i] = Long.parseLong(next());
			return a;
		}
	}
}

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

public class C {

	static long mod = 1000000009L;

	static long powMod(long x) {
		if (x == 0)
			return 1;
		if (x == 1)
			return 2;
		if (x % 2 == 0) {
			long ans = powMod(x / 2);
			return ((ans % mod) * (ans % mod)) % mod;
		}
		return ((powMod(x - 1) % mod) * (2 % mod)) % mod;
	}

	public static void main(String[] args) throws IOException {
		PrintWriter out = new PrintWriter(System.out);
		sc = new StringTokenizer(br.readLine());
		long n = nxtLng();
		long m = nxtLng();
		long k = nxtLng();
		long p = n / k;
		long nt = n - m;
		if (nt >= p) {
			long ans = (((k - 1) % mod) * (p % mod)) % mod;
			ans = ((ans % mod) + ((n % k) % mod)) % mod;
			ans = ((ans % mod) - ((nt - p) % mod)) % mod;
			out.println(ans % mod);
		} else {
			long ans = (((k - 1) % mod) * (nt % mod)) % mod;
			long remg = p - nt;
			long res = powMod(remg + 1) % mod;
			res = (res - 2 + mod) % mod;
			res = ((res % mod) * (k % mod)) % mod;
			ans = ((ans % mod) + (res % mod)) % mod;
			ans = ((ans % mod) + ((n % k) % mod)) % mod;
			out.println(ans % mod);
		}
		br.close();
		out.close();
	}

	static BufferedReader br = new BufferedReader(new InputStreamReader(
			System.in));

	static StringTokenizer sc;

	static String nxtTok() throws IOException {
		while (!sc.hasMoreTokens()) {
			String s = br.readLine();
			if (s == null)
				return null;
			sc = new StringTokenizer(s.trim());
		}
		return sc.nextToken();
	}

	static int nxtInt() throws IOException {
		return Integer.parseInt(nxtTok());
	}

	static long nxtLng() throws IOException {
		return Long.parseLong(nxtTok());
	}

	static double nxtDbl() throws IOException {
		return Double.parseDouble(nxtTok());
	}

	static int[] nxtIntArr(int n) throws IOException {
		int[] a = new int[n];
		for (int i = 0; i < n; i++)
			a[i] = nxtInt();
		return a;
	}

	static long[] nxtLngArr(int n) throws IOException {
		long[] a = new long[n];
		for (int i = 0; i < n; i++)
			a[i] = nxtLng();
		return a;
	}

	static double[] nxtDblArr(int n) throws IOException {
		double[] a = new double[n];
		for (int i = 0; i < n; i++)
			a[i] = nxtDbl();
		return a;
	}

	static char[] nxtCharArr() throws IOException {
		return nxtTok().toCharArray();
	}
}

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

public class P337C {

    static boolean multipleIndependent = false;
    static int mod = (int) (1e9) + 9;

    void run() {
        int n = in.nextInt(), m = in.nextInt(), k = in.nextInt();
        int nd = m + n / k - n;// number of doubling
        if (nd <= 0) {
            out.println(m);
        } else {
            long result = ((k * (modPower(2, nd + 1, mod) + mod - 2) % mod) % mod + (m - nd * k)) % mod;
            out.println(result);
        }
    }

    long modPower(int b, int p, int mod) {
        if (p == 0) {
            return 1;
        }
        long m = modPower(b, p / 2, mod);
        if (p % 2 == 1) {
            return (b * ((m * m) % mod)) % mod;
        } else {
            return (m * m) % mod;
        }
    }

    /* -----: Template :----- */
    static InputReader in;
    static PrintWriter out;

    public static void main(String[] args) {
        try (PrintWriter o = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)))) {
            in = new InputReader(System.in);
            out = o;
            int q = multipleIndependent ? in.nextInt() : 1;
            while (q-- > 0) {
                new P337C().run();
            }
        } catch (Exception ex) {
            ex.printStackTrace();
        }
    }

    static Integer[] toWrapper(int[] arr) {
        Integer[] res = new Integer[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    static Integer[][] toWrapper(int[][] arr) {
        Integer[][] res = new Integer[arr.length][];
        for (int i = 0; i < arr.length; i++) {
            res[i] = toWrapper(arr[i]);
        }
        return res;
    }

    static Long[] toWrapper(long[] arr) {
        Long[] res = new Long[arr.length];
        for (int i = 0; i < arr.length; i++) {
            res[i] = arr[i];
        }
        return res;
    }

    static Long[][] toWrapper(long[][] arr) {
        Long[][] res = new Long[arr.length][];
        for (int i = 0; i < arr.length; i++) {
            res[i] = toWrapper(arr[i]);
        }
        return res;
    }

    static class InputReader {

        private final BufferedReader reader;
        private StringTokenizer tokenizer;

        public InputReader(InputStream stream) {
            int bufferSize = 32 * 1024;
            reader = new BufferedReader(new InputStreamReader(stream), bufferSize);
            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 String nextLine() {
            if (true) {
                throw new RuntimeException("nextLine: not tested");
            }
            while (tokenizer == null || !tokenizer.hasMoreTokens()) {
                try {
                    tokenizer = new StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new RuntimeException(e);
                }
            }
            StringBuilder sb = new StringBuilder();
            return tokenizer.nextToken("\n");
        }

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

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

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

        public long[] nextLongArray(int n) {
            long[] arr = new long[n];
            for (int i = 0; i < n; i++) {
                arr[i] = nextLong();
            }
            return arr;
        }

        public int[][] nextIntMap(int n, int m) {
            int[][] map = new int[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = nextIntArray(m);
            }
            return map;
        }

        public long[][] nextLongMap(int n, int m) {
            long[][] map = new long[n][m];
            for (int i = 0; i < n; i++) {
                map[i] = nextLongArray(m);
            }
            return map;
        }

        public char[][] nextCharMap(int n) {
            char[][] map = new char[n][];
            for (int i = 0; i < n; i++) {
                map[i] = next().toCharArray();
            }
            return map;
        }
    }
}

/*
[ ( ^ _ ^ ) ]
*/
import java.io.*;
import java.util.*;

public class test {
    int INF = (int)1e9;
    long MOD = 1000000009;

    long pow(long a, long n, long mod) {
        if (n == 0) {
            return 1;
        }
        long rs = 1;
        while (n > 0) {
            if (n % 2 == 1) {
                rs *= a;
            }
            rs %= mod;
            n >>= 1;
            a *= a;
            a %= mod;
        }
        return rs;
    }

    void solve(InputReader in, PrintWriter out) throws IOException {
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();
        long x = m - ((n/k)*(k-1) + n%k);
        x = Math.max(0, x);
        long rs = ((((pow(2, x+1, MOD) -2-x+MOD)%MOD)*k)%MOD + m)%MOD;
        out.println(rs);
    }

    public static void main(String[] args) throws IOException {
        if(args.length>0 && args[0].equalsIgnoreCase("d")) {
            DEBUG_FLAG = true;
        }
        InputReader in = new InputReader();
        PrintWriter out = new PrintWriter(System.out);
        int t = 1;//in.nextInt();
        long start = System.nanoTime();
        while(t-->0) {
            new test().solve(in, out);
        }
        long end = System.nanoTime();
        debug("\nTime: " + (end-start)/1e6 + " \n\n");
        out.close();
    }

    static boolean DEBUG_FLAG = false;
    static void debug(String s) {
        if(DEBUG_FLAG) System.out.print(s);
    }

    public static void show(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }

    static class InputReader {
        static BufferedReader br;
        static StringTokenizer st;

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

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

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

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

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

import java.io.BufferedInputStream;
import java.io.IOException;
import java.util.InputMismatchException;

public class Main
{
	private final int MOD = (int)(1e9 + 9);

	public long quickPow(long x, long p)
	{
		long ans = 1;
		while(p > 0)
		{
			if(1 == p % 2)
			{
				ans = ans * x % MOD;
			}
			x = x * x % MOD;
			p >>= 1;
		}
		return ans % MOD;
	}

	public void foo()
	{
		MyScanner scan = new MyScanner();
		long n = scan.nextInt();
		long m = scan.nextInt();
		long k = scan.nextInt();
		if((n - m) * k >= n)
		{
			System.out.println(m);
		}
		else
		{
			long ans = ((n - m) * (k - 1) + (n - (n - m) * k) % k) % MOD;
			long doubleTimes = (n - (n - m) * k) / k;
			ans = (ans + (quickPow(2, doubleTimes + 1) - 2 + MOD) * k % MOD) % MOD;
			System.out.println(ans);
		}
	}

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

	class MyScanner
	{
	    private byte[] buf = new byte[1024];
	    private int curChar;
	    private int numChars;
	    BufferedInputStream bis = new BufferedInputStream(System.in);

	    public int read()
	    {
	        if (-1 == numChars)
	        {
	        	throw new InputMismatchException();
	        }
	        if (curChar >= numChars)
	        {
	            curChar = 0;
	            try
	            {
	                numChars = bis.read(buf);
	            }
	            catch (IOException e)
	            {
	                throw new InputMismatchException();
	            }
	            if (numChars <= 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
	        {
	            if (c < '0' || c > '9')
	            {
	            	throw new InputMismatchException();
	            }
	            res *= 10;
	            res += c - '0';
	            c = read();
	        } while (!isSpaceChar(c));
	        return res * sgn;
	    }

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

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

import java.util.Scanner;

public class A338 {

	public static void main (String args[]){

		Scanner in= new Scanner(System.in);
		long n = in.nextInt();
		long m=in.nextInt();
		long k=in.nextInt();

		long x = n-m;
		long y=n/k;
		if(x>=y)
			System.out.println(m);
		else
		{
			long t= y-x;
			long ans=0;
			ans+=k*(pow(t+1)-2);
			ans%=1000000009;
			ans+=m-t*k;
			ans%=1000000009;
			if(ans<0)
				ans+=1000000009;
			System.out.println(ans);

		}

	}

	public static long pow(long m ){

		if(m==1)
			return 2;
		long x = pow(m/2);

		x%=1000000009;
		x*=x;
		if(m%2!=0)
			x*=2;
		x%=1000000009;
		return (x);

	}

}

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
    public long MOD = (long)1e9 + 9;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long N = in.nextLong();
        long M = in.nextLong();
        long K = in.nextLong();

        long left = M - (N / K * (K - 1) + N % K);
        if (left <= 0) {
            out.println(M);
            return;
        }

        long single = M - left * K;
        long res = (powMod(2, left) * K % MOD + single) % MOD;
        out.println(res);
    }

    private long powMod(long a, long b) {
        if(b == 0) return 1;
        long res = powMod(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1)
            res = res * a % MOD;
        return res;
    }
}

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

public class compare
{
    static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

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

    public static void main(String[] args){
        int i;
        long n,m,x,re=0;
        FastReader sc=new FastReader();
            //min1=996;
            m=sc.nextLong();
            n=sc.nextLong();
            x=sc.nextLong();
        if(n<=m-m/x)
            System.out.println(n);
        else{
            re=((((pow(2,n+m/x-m,1000000009))-1)%1000000009)*2*x)%1000000009;
            re+=(n-x*(n+m/x-m))%1000000009;
            System.out.println(re);
        }
    }
     static long pow(long x, long y, long p)
{
    long res = 1;

    x = x % p;

    while (y > 0)
    {

        if ((y&1)==1)
            res = (res*x) % p;

        // y must be even now
        y = y>>1; // y = y/2
        x = (x*x) % p;
    }
    return res;
}
}

import java.util.*;

public class ProblemC {
    public static void main(String[] args) {
        game G=new game();
        G.input();
        G.solve();
    }
}

class game {
    long n,m,k;
    long modulo=1000000009;

    public long mu(long a,long b) {
        if (b==1) return a;
        if (b==0) return 1;
        else {
            long k=mu(a,b/2);
            if (b%2==0) return ((k%modulo)*(k%modulo))%modulo;
            else return (a*((k%modulo)*(k%modulo))%modulo)%modulo;
        }
    }

    public void input() {
        Scanner in = new Scanner(System.in);
        n=in.nextLong();
        m=in.nextLong();
        k=in.nextLong();
        in.close();
    }

    public void solve() {
        long mod=n%k,div=n/k,so=div*(k-1)+mod,con=m-so;
        if (con==0) {
            System.out.println(so%modulo);
        }
        else {
            long no = so-(con*(k-1));
            long diem = k*2*mu(3,con-1);
            long kq=(no+diem)%modulo;
            System.out.println(kq);
        }
    }
}

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

public class Main{

    BufferedReader in;
    StringTokenizer str = null;
    PrintWriter out;

    private String next() throws Exception{
    	if (str == null || !str.hasMoreElements())
    	    str = new StringTokenizer(in.readLine());
    	return str.nextToken();
    }

    private int nextInt() throws Exception{
	   return Integer.parseInt(next());
    }

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

    final long MOD = 1000000009;

    public void run() throws Exception{
    	in = new BufferedReader(new InputStreamReader(System.in));
    	out = new PrintWriter(System.out);

        long n = nextLong(), m = nextLong(), k = nextLong();
        long x = Math.max(0, m - (n-n%k)/k*(k-1)-n%k);
        long p = pow(2, x + 1);
        p-=2;
        if (p < 0) p+=MOD;
        p*=k;
        p%=MOD;
        p+=m;
        p-=x*k;
        if (p < 0) p+=MOD;
        out.println(p);
        out.close();
    }

    private long pow(long a, long n) {
        long ret = 1;
        while(n > 0) {
            if (n % 2 == 1) {
                ret*=a;
            }
            a*=a;
            a%=MOD;
            ret%=MOD;
            n/=2;
        }
        return ret;
    }

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

import static java.lang.System.in;
import static java.lang.System.out;

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

public class C337quiz {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	int MAX = 1000000009;

	int pow (int n, int k){
		if (k==0) return 1;
		long res = pow(n, k/2);
		res = (res*res)%MAX;
		if (k%2==1) res = (res*n)%MAX;
		return (int)res;
	}

	public void run() throws IOException {
		String input;
		String[] inputArray;
		input = br.readLine();
		inputArray = input.split(" ");

		int n = Integer.valueOf(inputArray[0]);
		int m = Integer.valueOf(inputArray[1]);
		int k = Integer.valueOf(inputArray[2]);
		int t = n/k;
		long ans = m;
		if (m>(t*(k-1) + n%k)){
			int r = m - (t*(k-1) + n%k);
			ans = (ans + (pow(2,r+1)-r-2 + MAX)*k) %MAX;
		}
		sb.append(ans);
		ln(sb);
	}

	public static void main(String[] args) throws IOException {
		new C337quiz().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Quiz {
	static int mod = 1000000009;

	static 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[10005]; // 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();
		}
	}

	static long power(long x, long y) {
		if (y == 0)
			return 1;
		long p = power(x, y / 2) % mod;
		p = (p * p) % mod;
		return (y % 2 == 0) ? p : (x * p) % mod;
	}

	public static void main(String[] args) throws IOException {
		Reader in = new Reader();
		int i, t, n, m, k, buckets;
		long ans = 0;
		n = in.nextInt();
		m = in.nextInt();
		k = in.nextInt();
		if (n == 0 || m == 0) {
			System.out.println("0");
			return;
		}
		buckets = n - m + 1;
		if (buckets >= m) {
			System.out.println(m);
			return;
		}
//		if()
		long maxInABucket = k - 1;
		long val = 0;
		if (m - (maxInABucket * buckets) <= 0) {
			System.out.println(m);
			return;
		}
		System.out.println(-1 % mod);
		val = (maxInABucket + (m - (maxInABucket * buckets))) % mod;
		long mul = (power(2, val / k + 1) % mod - 2 + mod) % mod;
		ans = (ans % mod + (k * mul) % mod);
		System.out.println(ans + " " + val + " " + mul);
		ans = (ans % mod + (m - (k * (val / k))) % mod) % mod;
		System.out.println(ans);
	}
}

import java.math.BigInteger;
import java.util.Scanner;

public class ds {

	public static int max = 1000000009;

	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);

		int n = in.nextInt();
		int m = in.nextInt();
		int k = in.nextInt();
		int w = n - m;
		if (w*(k-1) >= m) {
			System.out.println(m % max);
		} else {
			int rem = m - w*(k-1);
			int pow = rem / k;

			BigInteger ans = BigInteger
					.valueOf(w)
					.mod(BigInteger.valueOf(max))
					.add(BigInteger.valueOf(rem).mod(BigInteger.valueOf(k))
							.mod(BigInteger.valueOf(max)))
					.mod(BigInteger.valueOf(max));
			long ans1 = 2 * k;
			ans = ((ans.mod(BigInteger.valueOf(max)).subtract(
					BigInteger.valueOf(ans1).mod(BigInteger.valueOf(max)))
					.add(BigInteger.valueOf(k).mod(BigInteger.valueOf(max)).multiply(
							BigInteger.valueOf(2)
									.modPow(BigInteger.valueOf(pow).add(
											BigInteger.ONE),
											BigInteger.valueOf(max))).mod(BigInteger.valueOf(max)))).mod(BigInteger.valueOf(max)));
			System.out.println(ans.mod(BigInteger.valueOf(max)));
		}

	}

}

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

public class B {
	static int mod=1000000009;
public static int powMod(long e)
	{
		long b=2;
		long ans=1;
		while(e>0)
		{
			if(e%2==1)
			{
				ans=(ans*b)%mod;
				e--;
			}
			e/=2;
			b=(b*b)%mod;
		}
		return (int) ans;
	}
	public static void main(String[] args) throws IOException {
		Scanner sc=new Scanner(System.in);
		long n=sc.nextInt();
		long m=sc.nextInt();
		long k=sc.nextInt();
		long x=n/k;

		long max=x*(k-1)+Math.max(0, n%k);

		long d=Math.max(0,m-max );
		long ans=0;
		/*while(d-->0)
		{
			ans+=k;
			ans%=1000000009;
			ans*=2;
			ans%=1000000009;
			m-=k;
		}*/

		//ans+=((1<<(d+1))-2)*1.0*k;

		ans+=(powMod(d+1)-2)%mod*1L*k;

		ans%=mod;
		m-=(k*1L*d);
		ans+=m;

		ans%=mod;

		System.out.println(ans);
	}

}
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 double nextDouble() throws IOException
	{
		String x = next();
		StringBuilder sb = new StringBuilder("0");
		double 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();}

}

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

public class C {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException
	{
		reader = new BufferedReader(new InputStreamReader(System.in));
		tokenizer = null;
		long MOD = 1000000009L;
		long n = nextLong();
		long m = nextLong();
		long k = nextLong();
		long noDup = (n - m) * k;
		if (noDup <=  n)
		{
			long total = (((n - m) % MOD) * (k - 1)) % MOD;
			long Dup = n - noDup;
			long Dups = Dup / k;
			BigInteger MOD1 = BigInteger.valueOf(MOD);
			BigInteger DUPS = BigInteger.valueOf(Dups + 1);
			long add = BigInteger.valueOf(2).modPow(DUPS, MOD1).longValue() - 2;
			total = ((total + Dup % k) % MOD + (k * add) % MOD) % MOD;
			System.out.println(total);
		} else
			System.out.println(m);
	}

	static BufferedReader reader;
	static StringTokenizer tokenizer;

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

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

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

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

}

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

public class P337C {
	public static void main(String[] args) {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		Task solver = new Task();
		solver.solve(in, out);
		out.close();
	}

	static class Task {

		final long M = (long) 1e9 + 7;

		public void solve(InputReader in, PrintWriter out) {
			int n = in.nextInt();
			int m = in.nextInt();
			int k = in.nextInt();
			int t = Math.min(n / k, n - m);
			long score = 0;
			score += (k - 1) * t;
			int r = n - k * t;
			int p = r / k;
			score += ((pow(p + 1) - 2) * k) % M;
			score += r % k;
			score %= M;
			out.println(score);
		}

		private long pow(int n) {
			if (n == 0)
				return 1;
			else if ((n & 1) == 0) {
				long val = pow(n / 2);
				return (val * val) % M;
			} else
				return (2 * pow(n - 1)) % M;
		}
	}

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

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

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

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

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

		public String nextLine() {
			try {
				return reader.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
		}

	}
}

import java.util.*;

public class C {
	static final int MOD = 1000000009;
	static long pow(long n, long m){
		if (m == 0){
			return 1;
		}
		if (m == 1){
			return n;
		}
		long p = pow(n, m >> 1);
		p = (p*p)%MOD;
		if ((m & 1) != 0){
			p = (p*n)%MOD;
		}
		return p;
	}
	static long solve(long n, long m, long k){
		if (m < k || (m + (m/(k - 1) - 1) <= n)){
			return m;
		}
		long lo = 1;
		long hi = n/k + 1;
		while (lo < hi){
			final long mi = (lo + hi)/2;
			if (n - mi*k >= m - mi*(k - 1)){
				lo = mi;
			}else{
				hi = mi - 1;
			}
		}
		long res = lo*(k - 1);
		long continious = m - lo*(k - 1);
		long fraction = continious/k;
		if (fraction >= 1){
			res += k*((pow(2, fraction + 1) - 2 + MOD)%MOD);
			res %= MOD;
		}
		res += (continious%k);
		res %= MOD;
		return res;
	}
	public static void main(String [] args){
		final Scanner s = new Scanner(System.in);
		final long n = s.nextLong();
		final long m = s.nextLong();
		final long k = s.nextLong();
		System.out.println(solve(n, m, k));
		s.close();
	}
}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class A {

    static StringTokenizer st;
    static BufferedReader in;
    static PrintWriter pw;

    public static void main(String[] args) throws IOException {
        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
//      long a = 2;
//      int q = nextInt();
//      long sum = a;
//      int s = q;
//      for (int i = 2; i <= s; i++) {
//          a = a*2+2;
//          sum += a;
//      }
//      System.out.println(sum);
//      System.out.println((4*((long)Math.pow(2, s)-1)-2*s));
        int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        long t = (long)(n-m) * k;
        int mod = (int) (1e9+9);
        long ans = 0;
        if (t-1 < n) {
            int s = (int) (n - t);
            int cnt = s / k;
            ans = BigInteger.valueOf(2).modPow(BigInteger.valueOf(cnt), BigInteger.valueOf(mod)).longValue();
            ans = (ans-1+mod) % mod;
            ans = ans * 4 % mod;
            ans = (ans-2*cnt+2*mod) % mod;
            ans = ans * k % mod;
            ans = (ans+(long)(k-1) * (n-m) % mod) % mod;
            ans = (ans+s % k) % mod;
        }
        else
            ans = m;
        System.out.println(ans);
        pw.close();
    }
    private static int nextInt() throws IOException{
        return Integer.parseInt(next());
    }

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

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

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

import java.util.Scanner;

public class C {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long s=0;
		int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt(),c=n/k;
		if(m<=c*(k-1)+(n%k))System.out.println(m);
		else {
			int a=m-c*(k-1)-(n%k);
			long l=0,pase=0;
			for(int i=0;i<a;i++) {
				s+=2*(l+1);
				l=s;
				pase+=k;
			}
			System.out.println(l*k+m-pase);
		}
	}
}

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

public class P337C {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] info = br.readLine().split(" ");
		long questions = Long.parseLong(info[0]);
		long correctQts = Long.parseLong(info[1]);
		long consCorrQts = Long.parseLong(info[2]);
		long minScore = getMinimumScore(questions, correctQts, consCorrQts);
		System.out.println(minScore);
	}

	private static long getMinimumScore(long questions, long correctQts,
			long consCorrQts) {
		long by = 1000000009;
		long div = questions/consCorrQts;
		long blocks = questions - div;
		long missing = correctQts - blocks;
		long dupliScore = ((missing%by)*(2*consCorrQts))%by;
		long normalScore = ((blocks-missing)%by) * (consCorrQts-1);
		long minScore = (dupliScore + normalScore)%by;
		return minScore;
	}

}

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

public class code
{
	static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

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

    public static void main(String args[])throws IOException
	{
        FastReader scn = new FastReader();

        long n = scn.nextLong();
        long m = scn.nextLong();
        long k = scn.nextLong();

        long complete = (n/k)*(k-1);
        long partial = n%k;
        if( complete + partial >= m )
        {
            System.out.println(m);
            return;
        }

        long ans_mid = -1;
        long l = 0;
        long r = m - 1;
        while(l <= r)
        {
            long mid = (l+r)/2;

            complete = ((n - 2 - mid)/k)*(k-1);
            partial = (n - 2 - mid)%k;

            if(complete < 0)
                complete = 0;
            if(partial < 0)
                partial = 0;

            long possible  = (mid + 1) + complete + partial;

            if(possible >= m)
            {
                r = mid - 1;
                ans_mid = mid;
            }
            else
            {
                l = mid + 1;
            }
        }

        long P = 1000000009L;

        complete = ((n - 2 - ans_mid)/k)*(k-1);
        partial = (n - 2 - ans_mid)%k;
        if(complete < 0)
            complete = 0;
        if(partial < 0)
            partial = 0;

        long points  = ((ans_mid + 1)%k + complete + partial)%P;

        long power = (ans_mid + 1)/k;
        long points2 = getTwoPower(power + 1, P);

        points2 = (points2 - 2)%P;
        points2 = (points2 * k)%P;

        points += points2;
        if(points < 0)
            points = points + P;
        System.out.println(points);
	}

    public static long getTwoPower(long power, long P)
    {
        if(power == 0)
            return 1;
        if(power == 1)
            return 2;

        long ans = getTwoPower(power/2, P);
        ans = (ans * ans)%P;
        if(power % 2 == 1)
            ans = (ans * 2)%P;
        return ans;
    }

    public static int getIndex(int[] list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list[middle]==value)
                return middle;
            else if(list[middle] < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return -1;
    }

    public static int getLessThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return r;
    }

    public static int getMoreThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return l;
    }

    public static long inverseModulo(long a, long P)
    {
        return powerModulo(a, P-2, P);
    }

    public static long powerModulo(long a, long p, long m)
    {
        if(p==0)
            return 1;

        long temp = powerModulo(a, p/2, m);
        temp = (temp * temp)%m;
        if(p%2 == 0)
            return temp;
        else
            return (a * temp)%m;

    }
}

class Pair implements Comparable<Pair>
{
    int a, b;

    public Pair(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public int compareTo(Pair p)
    {
        return this.b - p.b;
    }
}

class Node
{
    int value;
    int req_value;
    ArrayList<Integer> neighbors;
    boolean visited;

    public Node()
    {
        neighbors = new ArrayList<>();
    }

}

class MutableInt
{
    int count;
    ArrayList<Integer> list;
    public MutableInt()
    {
        list = new ArrayList<>();
    }
}

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 * @author BSRK Aditya
 */
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);
		TaskA solver = new TaskA();
		solver.solve(1, in, out);
		out.close();
	}
}

class TaskA {
    public void solve(int testNumber, Scanner in, PrintWriter out) {
        int n = in.nextInt(), m = in.nextInt(), k = in.nextInt();

        long score = 0;
        int leftCorrectAnswers = m;
        int leftWrongAnswers = n-m;

        int lastBlock = n%k;
        score += Math.min(lastBlock, leftCorrectAnswers);
        leftCorrectAnswers -= Math.min(lastBlock, leftCorrectAnswers);

        int numBlocks = n/k;
        int noDoubleBlocks = Math.min(numBlocks, leftWrongAnswers);
        int DoubleBlocks = numBlocks - noDoubleBlocks;

        score += new BigInteger("2")
                .modPow(new BigInteger(String.valueOf(DoubleBlocks+1)), new BigInteger("1000000009"))
                .subtract(BigInteger.ONE.add(BigInteger.ONE))
                .multiply(new BigInteger(String.valueOf(k))).mod(new BigInteger("1000000009")).longValue();

        score += noDoubleBlocks*(k-1);
        score %= 1000000009;

        out.println(score);
    }
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.math.BigInteger;
import java.io.InputStream;

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

class TaskC {
    int MOD=(int)(1e9+9);
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int N=in.readInt();
        int M=in.readInt();
        int K=in.readInt();
        long x=N-M;
        long a=M-(K-1)*x;

        if(a<=0){
            out.println(M);
            return;
        }
        long ans=(K-1)*x+a%K;
        ans%=MOD;
        long add=K*(pow(2,(int)(1+a/K))-2);

        ans=(ans+add)%MOD;
        out.println(ans);

    }
    long pow(long a,int b){
        long ans=1;
        while (b!=0){
            if(b%2!=0)
                ans=(ans*a)%MOD;
            b/=2;
            a=(a*a)%MOD;
        }
        return ans;
    }
}

class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        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 boolean isSpaceChar(int c) {
                if (filter != null)
                        return filter.isSpaceChar(c);
                return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {
                public boolean isSpaceChar(int ch);
        }
}

import java.io.*;
import java.math.BigInteger;
import java.util.*;
import static java.util.Arrays.*;

public class A {
    private static final int mod = (int)1e9+9;

    final IOFast io = new IOFast();

    long k;

    long rec(long n, long m, long cur) {
        long pow = 1;
        long margin = 10;
        long p = 1000;
        for(int i = 0; i < p; i++) pow = pow * 2 % mod;
        while(true) {
            if(n + 1 >= (m / (k - 1) * k + m % (k - 1)) || m < k) { return (m + cur) % mod; }
            long q = (p + margin) * k;
            if(n - q + 1 < ((m - q) / (k - 1) * k + (m - q) % (k - 1)) && m >= q) {
                n -= p * k;
                m -= p * k;
                cur = cur * pow % mod;
                cur += (pow - 1) * 2 * k % mod;
                cur %= mod;
                continue;
            }
            n -= k;
            m -= k;
            cur += k;
            cur = cur * 2 % mod;
//          System.err.println(cur);
        }
    }

    public void run() throws IOException {
        long n = io.nextLong();
        long m = io.nextLong();
        k = io.nextLong();
//      io.out.println(rec(n, m, 0));
//      if(true) return;

        long low = -1, high = m / k + 1;
        while(high - low > 1) {
            long mid = (low + high) / 2;
            long u = mid * k;
            if(m < u) { high = mid; continue; }
            if(u + (m - u - k) / (k - 1) * k + k - 1 + (m - u) % (k - 1) > n) {
                low = mid;
            }
            else {
                high = mid;
            }
//          System.err.println(mid + " " + (u + (m - u - k) / (k - 1) * k + k - 1 + (m - u) % (k - 1)) + " " + n);
        }

        long pow = powmod(2, high, mod);
        long score = m - high * k;
        score = (score + (pow - 1) * 2 * k) % mod;
        io.out.println(score);
    }

    static long powmod(long n, long r, int m) {
        long res = 1;
        for(; r != 0; r >>>= 1, n = n * n % m) {
            if((r&1) == 1) {
                res = res * n;
                if(res >= m) {
                    res %= m;
                }
            }
        }
        return res;
    }

    void main() throws IOException {
        //      IOFast.setFileIO("rle-size.in", "rle-size.out");
        try {
            run();
        }
        catch (EndOfFileRuntimeException e) { }
        io.out.flush();
    }

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

    static class EndOfFileRuntimeException extends RuntimeException {
        private static final long serialVersionUID = -8565341110209207657L; }

    static
    public class IOFast {
        private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        private PrintWriter out = new PrintWriter(System.out);

        void setFileIO(String ins, String outs) throws IOException {
            in = new BufferedReader(new FileReader(ins));
            out = new PrintWriter(new FileWriter(outs));
        }

        //      private static final int BUFFER_SIZE = 50 * 200000;
        private static int pos, readLen;
        private static final char[] buffer = new char[1024 * 8];
        private static final char[] str = new char[500000*8*2];
        private static boolean[] isDigit = new boolean[256];
        private static boolean[] isSpace = new boolean[256];
        private static boolean[] isLineSep = new boolean[256];

        static {
            for(int i = 0; i < 10; i++) { isDigit['0' + i] = true; }
            isDigit['-'] = true;
            isSpace[' '] = isSpace['\r'] = isSpace['\n'] = isSpace['\t'] = true;
            isLineSep['\r'] = isLineSep['\n'] = true;
        }

        public int read() throws IOException {
            if(pos >= readLen) {
                pos = 0;
                readLen = in.read(buffer);
                if(readLen <= 0) { throw new EndOfFileRuntimeException(); }
            }
            return buffer[pos++];
        }

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

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

        public char nextChar() throws IOException {
            while(true) {
                final int c = read();
                if(!isSpace[c]) { return (char)c; }
            }
        }

        int reads(char[] cs, int len, boolean[] accept) throws IOException {
            try {
                while(true) {
                    final int c = read();
                    if(accept[c]) { break; }
                    str[len++] = (char)c;
                }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return len;
        }

        public char[] nextLine() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isLineSep);

            try {
                if(str[len-1] == '\r') { len--; read(); }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return Arrays.copyOf(str, len);
        }

        public String nextString() throws IOException {
            return new String(next());
        }

        public char[] next() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isSpace);
            return Arrays.copyOf(str, len);
        }

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

    }

}

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

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;
        }
    }
    public static long mod=1000000009,N=1000000009;
    static long exponentiation(long base, long exp)
    {
        if (exp == 0)
            return 1;
        if (exp == 1)
            return base % N;
        long t = exponentiation(base, exp / 2);
        t = (t * t) % N;
        if (exp % 2 == 0)
            return t;
        else
            return ((base % N) * t) % N;
    }
    public static void main(String[] args)throws Exception
    {
        InputReader in=new InputReader(System.in);
        PrintWriter w=new PrintWriter(System.out);
        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long[] power=new long[10000000];
        long ng=(n/k);
        if(n==m)
        {
            long x=n/k;
            long num=0,count=0;
            num=(((((exponentiation(2L,x+1L)%mod-(2%mod)+mod)%mod)*(k%mod))%mod + m)%mod - ((x%mod)*(k%mod))%mod+mod)%mod;
            w.println(num);
        }
        else
        {
            if(n%k==(k-1))
                ng++;
            if(ng*(k-1)>=m)
            {
                w.println(m);
            }
            else
            {
                long score=0;
                long x=m-n+(n/k);
                long count=0;
                //w.println(x);
                score=(((((exponentiation(2L,x+1L)%mod-(2%mod)+mod)%mod)*(k%mod))%mod + m)%mod - ((x%mod)*(k%mod))%mod+mod)%mod;

                w.println(score);
            }
        }
        w.close();
    }
}

import java.util.*;

public class Quiz{
	static int MOD = (int)1e9 + 9;
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		long n = reader.nextInt();
		long m = reader.nextInt();
		long k = reader.nextInt();

		long r = (n + k - 1)/k;

		long longDrops = n%k;

		if(longDrops == 0){
			long d = m - (r * (k-1));

			if(d <= 0){
				System.out.println(m);
				return;
			}

			long sum = (fastExpo(2,d+1)-2) * k + (m - d*k);
			System.out.println(sum%MOD);
		}else{
			long d = (m-longDrops*r) - (r-1)*(k-longDrops-1);

			if(d <= 0){
				System.out.println(m);
				return;
			}

			long sum = (fastExpo(2,d+1)-2) * k + (m - d*k);
			System.out.println(sum%MOD);
		}
	}

	public static long fastExpo(long b, long p){
		if(p == 0)
			return 1;
		if(p % 2 == 1)
			return (b * fastExpo(b, p-1))%MOD;
		long x = fastExpo(b, p/2);
		return (x * x)%MOD;
	}
}

import java.io.InputStreamReader;
import static java.lang.Math.*;
import java.util.ArrayList;
import java.util.Scanner;
/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

/**
 *
 * @author pttrung
 */
public class C {

    public static long Mod = 1000000009;

    public static void main(String[] args) {
        Scanner in = new Scanner(new InputStreamReader(System.in));
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();
        long X = Math.max(0, m - (n - n % k) / k * (k - 1) - n % k);
        long result = (pow(2 , X + 1) - 2)*k % Mod;
        result +=  m - (X*k);

        System.out.println(result % Mod);

    }

    static long pow(long a, long b) {
        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;
        }
    }

    static void check(Point a, Point b, ArrayList<Point> p, Point[] rec, int index) {
        for (int i = 0; i < 4; i++) {
            int m = (i + index) % 4;
            int j = (i + 1 + index) % 4;
            Point k = intersect(minus(b, a), minus(rec[m], rec[j]), minus(rec[m], a));
            if (k.x >= 0 && k.x <= 1 && k.y >= 0 && k.y <= 1) {
                Point val = new Point(k.x * minus(b, a).x, k.x * minus(b, a).y);
                p.add(add(val, a));
                // System.out.println(a + " " + b + " " + rec[i] + " " + rec[j]);
                // System.out.println(add(val, a));
            }
        }
    }

    static Point intersect(Point a, Point b, Point c) {
        double D = cross(a, b);
        if (D != 0) {
            return new Point(cross(c, b) / D, cross(a, c) / D);
        }
        return null;
    }

    static Point convert(Point a, double angle) {
        double x = a.x * cos(angle) - a.y * sin(angle);
        double y = a.x * sin(angle) + a.y * cos(angle);
        return new Point(x, y);
    }

    static Point minus(Point a, Point b) {
        return new Point(a.x - b.x, a.y - b.y);
    }

    static Point add(Point a, Point b) {
        return new Point(a.x + b.x, a.y + b.y);
    }

    static double cross(Point a, Point b) {
        return a.x * b.y - a.y * b.x;
    }

    static class Point {

        double x, y;

        Point(double x, double y) {
            this.x = x;
            this.y = y;
        }

        @Override
        public String toString() {
            return "Point: " + x + " " + y;
        }
    }
}

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;

public class Quiz {
	static int mod = 1000000009;

	static 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[10005]; // 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();
		}
	}

	public static void main(String[] args) throws IOException {
		Reader in = new Reader();
		int i, t, n, m, k, buckets;
		long ans = 0;
		n = in.nextInt();
		m = in.nextInt();
		k = in.nextInt();
		if (n == 0 || m == 0) {
			System.out.println("0");
			return;
		}
		buckets = n - m + 1;
		if (buckets >= m) {
			System.out.println(m);
			return;
		}
//		if()
		int maxInABucket = k - 1;
		long val = 0;
		i = 0;
		int count = 0;
		t = m;
		if (m - (maxInABucket * buckets) <= 0) {
			System.out.println(m);
			return;
		}

		val = maxInABucket + (m - (maxInABucket * buckets));
//		System.out.println(Arrays.toString(val));
		long x = val;
		System.out.println(x / k);
		for (i = 0; i < x / k; i++) {
			ans = (ans % mod + k % mod) % mod;
			ans = ((ans % mod) * 2) % mod;
			val -= k;
		}
		ans = (ans % mod + val % mod) % mod;
		ans = (ans % mod + (maxInABucket * (buckets - 1)) % mod) % mod;
		System.out.println(ans);
	}
}

import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.InputMismatchException;
import java.math.BigInteger;
import java.io.InputStream;

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

class TaskC {
    int MOD=(int)(1e9+9);
    public void solve(int testNumber, InputReader in, PrintWriter out) {
        int N=in.readInt();
        int M=in.readInt();
        int K=in.readInt();
        long x=N-M;
        long a=M-(K-1)*x;

        if(a<=0){
            out.println(M);
            return;
        }
        long ans=(((K-1)*x)%MOD+a%K)%MOD;
        long add=(K*(pow(2,(int)(2+a/K))-4-2*(a/K)))%MOD;
        ans=(ans+add)%MOD;
        out.println(ans);
    }
    long pow(long a,int b){
        long ans=1;
        while (b!=0){
            if(b%2!=0)
                ans=(ans*a)%MOD;
            b/=2;
            a=(a*a)%MOD;
        }
        return ans;
    }
}

class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        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 boolean isSpaceChar(int c) {
                if (filter != null)
                        return filter.isSpaceChar(c);
                return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {
                public boolean isSpaceChar(int ch);
        }
}

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;

/**
 *
 * @author WIN7
 */
public class Challenges {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long d = 1000000009;
        long n = sc.nextInt();
        long m = sc.nextInt();
        long k = sc.nextInt();
        long y = (n - m ) * k % d;
        long x = n - y;
        long z = x / k;
        long c = ((((k * z) % d) * (z + 1) % d) % d + x % k) % d;
        long points = (y - (n - m)) % d + c % d;
        if (x < 0) {
            System.out.println(m);
        } else {
            System.out.println(points);
        }
    }

    static class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        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 boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {

            public boolean isSpaceChar(int ch);
        }
    }

    static class OutputWriter {

        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(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.Scanner;

public class CF_337C {
	static int MOD = 1000000009;
	public static void main(String[] args) {
		Scanner in = new Scanner(System.in);
		int n = in.nextInt();
		int m = in.nextInt();
		int k = in.nextInt();
		in.close();

		int d = n - m;
		m -= d * (k - 1);
		n -= d * k;

		if (m <= 0) {
			System.out.println(m + (d * (k - 1)));
			return;
		}

		long ans = d * (k - 1);
		ans += n % k;
		ans %= MOD;

		int doubles = n / k;
		long a = powOf2(doubles + 1);

		a -= 2;
		a *= k;
		a %= MOD;

		ans = (ans + a) % MOD;
		System.out.println(ans);
	}

	static long powOf2(int p) {
		if (p == 0)
			return 1;
		if (p == 1)
			return 2;

		long a;
		if (p % 2 == 0) {
			a = powOf2(p / 2);
			return (a * a) % MOD;
		}

		a = powOf2((p - 1) / 2);
		return (2 * a * a) % MOD;
	}
}

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

public class Main
{
	public static void main(String[] args) throws IOException
	{
		// int t = ni();
		int t = 1;
		while(t-->0) {
			long n = ni();
			long m = ni();
			long k = ni();
			long rem = n-m-(m%(k-1));
			int parts = (int)Math.ceil(1d*m/(k-1));
			long x = m - (n/k)*(k-1) - n%k;
			if(x<=0){
				System.out.println(m);
			}
			else{
				System.out.println(m+" "+(n/k)*(k-1)+" "+n%k);
				System.out.println(x);
				long score_doubled = ((k*(powm(2,x+1,mod)-2))%mod + mod)%mod;
				// System.out.println(score_doubled);
				long ans = ((score_doubled+(m-k*x))%mod + mod)%mod;
				System.out.println(ans);
			}
		}
	}

	static final int mod=1000000009;
    static StringBuilder ans=new StringBuilder();
	static Reader in=new Reader();
	static final double eps=1e-9;

	//////////////////////////////////
	//input functions/////////////////
	static int ni(){return Integer.parseInt(in.next());}
	static long nl(){return Long.parseLong(in.next());}
	static String ns(){return in.next();}
	static double nd(){return Double.parseDouble(in.next());}
	static int[] nia(int n){int a[]=new int[n];for(int i=0; i<n; i++)a[i]=ni();return a;}
	static int[] pnia(int n){int a[]=new int[n+1];for(int i=1; i<=n; i++)a[i]=ni();return a;}
	static long[] nla(int n){long a[]=new long[n];for(int i=0; i<n; i++)a[i]=nl();return a;}
	static String[] nsa(int n){String a[]=new String[n];for(int i=0; i<n; i++)a[i]=ns();return a;}
	static double[] nda(int n){double a[]=new double[n];for(int i=0; i<n; i++)a[i]=nd();return a;}

	//////output functions////////////////
	static void pr(Object a){ans.append(a+"\n");}
	static void pr(){ans.append("\n");}
	static void p(Object a){ans.append(a);}
	static void pra(int[]a){for(int i:a)ans.append(i+" ");ans.append("\n");}
	static void pra(long[]a){for(long i:a)ans.append(i+" ");ans.append("\n");}
	static void pra(String[]a){for(String i:a)ans.append(i+" ");ans.append("\n");}
	static void pra(double[]a){for(double i:a)ans.append(i+" ");ans.append("\n");}
	static void sop(Object a){System.out.print(a);}
	static void sopln(Object a){System.out.println(a);}
	static void flush(){System.out.print(ans);ans=new StringBuilder();}

	static void exit(){System.out.print(ans);System.exit(0);}
	static int min(int... a){int min=a[0];for(int i:a)min=Math.min(min, i);return min;}
	static int max(int... a){int max=a[0];for(int i:a)max=Math.max(max, i);return max;}
	static int gcd(int... a){int gcd=a[0];for(int i:a)gcd=gcd(gcd, i);return gcd;}
	static long min(long... a){long min=a[0];for(long i:a)min=Math.min(min, i);return min;}
	static long max(long... a){long max=a[0];for(long i:a)max=Math.max(max, i);return max;}
	static long gcd(long... a){long gcd=a[0];for(long i:a)gcd=gcd(gcd, i);return gcd;}
	static String pr(String a, long b){String c="";while(b>0){if(b%2==1)c=c.concat(a);a=a.concat(a);b>>=1;}return c;}
	static long powm(long a, long b, long m){long an=1;long c=a;while(b>0){if(b%2==1)an=(an*c)%m;c=(c*c)%m;b>>=1;}return an;}
	static int gcd(int a, int b){if(b==0)return a;return gcd(b, a%b);}
	static long gcd(long a, long b){if(b==0)return a;return gcd(b, a%b);}

	static class Reader {
        BufferedReader reader;
        StringTokenizer tokenizer;
        public Reader() {
            reader = new BufferedReader(new InputStreamReader(System.in), 32768);
            tokenizer = null;
        }
        String next() {while (tokenizer == null || !tokenizer.hasMoreTokens()) {
				try {tokenizer = new StringTokenizer(reader.readLine());}
				catch (IOException e) {throw new RuntimeException(e);}}
            return tokenizer.nextToken();}
        int nextInt() {return Integer.parseInt(next());}
        long nextLong() {return Long.parseLong(next());}
        double nextDouble() {return Double.parseDouble(next());}
    }

}

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class A {

    static StringTokenizer st;
    static BufferedReader in;
    static PrintWriter pw;

    public static void main(String[] args) throws IOException {
        in = new BufferedReader(new InputStreamReader(System.in));
        pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
//      long a = 2;
//      int q = nextInt();
//      long sum = a;
//      int s = q;
//      for (int i = 2; i <= s; i++) {
//          a = a*2+2;
//          sum += a;
//      }
//      System.out.println(sum);
//      System.out.println((4*((long)Math.pow(2, s)-1)-2*s));
        int n = nextInt();
        int m = nextInt();
        int k = nextInt();
        long t = (long)(n-m) * k;
        int mod = (int) (1e9+9);
        long ans = 0;
        int x = m / (k-1);
        if (m % (k-1) != 0)
            x++;
        if (n-m < x-1) {
            int s = (int) (n - t);
            int cnt = s / k;
            ans = BigInteger.valueOf(2).modPow(BigInteger.valueOf(cnt), BigInteger.valueOf(mod)).longValue();
            ans = (ans-1+mod) % mod;
            ans = ans * 4 % mod;
            ans = (ans-2*cnt+2*mod) % mod;
            ans = ans * k % mod;
            ans = (ans+(long)(k-1) * (n-m) % mod) % mod;
            ans = (ans+s % k) % mod;
        }
        else
            ans = m;
        System.out.println(ans);
        pw.close();
    }
    private static int nextInt() throws IOException{
        return Integer.parseInt(next());
    }

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

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

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

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
    public long MOD = (long)1e9 + 9;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long N = in.nextLong();
        long M = in.nextLong();
        long K = in.nextLong();

        long left = M - (N / K * (K - 1) + N % K);
        if (left <= 0) {
            out.println(M);
            return;
        }

        long single = M - left * K;
        long res = ((powMod(2, left + 1) - 2) * K % MOD + single) % MOD;
        out.println(res);
    }

    private long powMod(long a, long b) {
        if(b == 0) return 1;
        long res = powMod(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1)
            res = res * a % MOD;
        return res;
    }
}

import java.io.*;
import java.math.BigInteger;
import java.util.*;
import static java.util.Arrays.*;

public class A {
    private static final int mod = (int)1e9+9;

    final IOFast io = new IOFast();

    long k;

    long rec(long n, long m, long cur) {
        long pow = 1;
        long margin = 10;
        long p = 1000;
        for(int i = 0; i < p; i++) pow = pow * 2 % mod;
        while(true) {
            if(n + 1 >= (m / (k - 1) * k + m % (k - 1)) || m < k) { return (m + cur) % mod; }
            long q = (p + margin) * k;
            if(n - q + 1 < ((m - q) / (k - 1) * k + (m - q) % (k - 1)) && m >= q) {
                n -= p * k;
                m -= p * k;
                cur = cur * pow % mod;
                cur += (pow - 1) * 2 * k % mod;
                cur %= mod;
                continue;
            }
            n -= k;
            m -= k;
            cur += k;
            cur = cur * 2 % mod;
//          System.err.println(cur);
        }
    }

    public void run() throws IOException {
        long n = io.nextLong();
        long m = io.nextLong();
        k = io.nextLong();
        io.out.println(rec(n, m, 0));
        if(true) return;

        long low = -1, high = m / k + 1;
        while(high - low > 1) {
            long mid = (low + high) / 2;
            long u = mid * k;
            if(m < u) { high = mid; continue; }
            if(u + (m - u) / (k - 1) * k + (m - u) % (k - 1) - 1 > n) {
                low = mid;
            }
            else {
                high = mid;
            }
        }

        long pow = powmod(2, high, mod);
        long score = m - high * k;
        score = (score + (pow - 1) * 2 * k) % mod;
        io.out.println(score);
    }

    static long powmod(long n, long r, int m) {
        long res = 1;
        for(; r != 0; r >>>= 1, n = n * n % m) {
            if((r&1) == 1) {
                res = res * n;
                if(res >= m) {
                    res %= m;
                }
            }
        }
        return res;
    }

    void main() throws IOException {
        //      IOFast.setFileIO("rle-size.in", "rle-size.out");
        try {
            run();
        }
        catch (EndOfFileRuntimeException e) { }
        io.out.flush();
    }

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

    static class EndOfFileRuntimeException extends RuntimeException {
        private static final long serialVersionUID = -8565341110209207657L; }

    static
    public class IOFast {
        private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        private PrintWriter out = new PrintWriter(System.out);

        void setFileIO(String ins, String outs) throws IOException {
            in = new BufferedReader(new FileReader(ins));
            out = new PrintWriter(new FileWriter(outs));
        }

        //      private static final int BUFFER_SIZE = 50 * 200000;
        private static int pos, readLen;
        private static final char[] buffer = new char[1024 * 8];
        private static final char[] str = new char[500000*8*2];
        private static boolean[] isDigit = new boolean[256];
        private static boolean[] isSpace = new boolean[256];
        private static boolean[] isLineSep = new boolean[256];

        static {
            for(int i = 0; i < 10; i++) { isDigit['0' + i] = true; }
            isDigit['-'] = true;
            isSpace[' '] = isSpace['\r'] = isSpace['\n'] = isSpace['\t'] = true;
            isLineSep['\r'] = isLineSep['\n'] = true;
        }

        public int read() throws IOException {
            if(pos >= readLen) {
                pos = 0;
                readLen = in.read(buffer);
                if(readLen <= 0) { throw new EndOfFileRuntimeException(); }
            }
            return buffer[pos++];
        }

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

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

        public char nextChar() throws IOException {
            while(true) {
                final int c = read();
                if(!isSpace[c]) { return (char)c; }
            }
        }

        int reads(char[] cs, int len, boolean[] accept) throws IOException {
            try {
                while(true) {
                    final int c = read();
                    if(accept[c]) { break; }
                    str[len++] = (char)c;
                }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return len;
        }

        public char[] nextLine() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isLineSep);

            try {
                if(str[len-1] == '\r') { len--; read(); }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return Arrays.copyOf(str, len);
        }

        public String nextString() throws IOException {
            return new String(next());
        }

        public char[] next() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isSpace);
            return Arrays.copyOf(str, len);
        }

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

    }

}

import java.io.*;
import java.math.BigInteger;
import java.util.*;
import static java.util.Arrays.*;

public class A {
    private static final int mod = (int)1e9+9;

    final IOFast io = new IOFast();

    long k;

    long rec(long n, long m, long cur) {
        long pow = 1;
        long p = 1000;
        for(int i = 0; i < p; i++) pow = pow * 2 % mod;
        while(true) {
            if(k * m - 1 <= n || m < k) { return (m + cur) % mod; }
            if(k * (m - (p + 10) * k) - 1 > (n - (p + 10) * k) && m >= (p + 10) * k) {
                n -= p * k;
                m -= p * k;
                cur = cur * pow % mod;
                cur += (pow - 1) * 2 * k % mod;
                cur %= mod;
                continue;
            }
            n -= k;
            m -= k;
            cur += k;
            cur = cur * 2 % mod;
        }
    }

    public void run() throws IOException {
        long n = io.nextLong();
        long m = io.nextLong();
        k = io.nextLong();
        io.out.println(rec(n, m, 0));
    }

    void main() throws IOException {
        //      IOFast.setFileIO("rle-size.in", "rle-size.out");
        try {
            run();
        }
        catch (EndOfFileRuntimeException e) { }
        io.out.flush();
    }

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

    static class EndOfFileRuntimeException extends RuntimeException {
        private static final long serialVersionUID = -8565341110209207657L; }

    static
    public class IOFast {
        private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        private PrintWriter out = new PrintWriter(System.out);

        void setFileIO(String ins, String outs) throws IOException {
            in = new BufferedReader(new FileReader(ins));
            out = new PrintWriter(new FileWriter(outs));
        }

        //      private static final int BUFFER_SIZE = 50 * 200000;
        private static int pos, readLen;
        private static final char[] buffer = new char[1024 * 8];
        private static final char[] str = new char[500000*8*2];
        private static boolean[] isDigit = new boolean[256];
        private static boolean[] isSpace = new boolean[256];
        private static boolean[] isLineSep = new boolean[256];

        static {
            for(int i = 0; i < 10; i++) { isDigit['0' + i] = true; }
            isDigit['-'] = true;
            isSpace[' '] = isSpace['\r'] = isSpace['\n'] = isSpace['\t'] = true;
            isLineSep['\r'] = isLineSep['\n'] = true;
        }

        public int read() throws IOException {
            if(pos >= readLen) {
                pos = 0;
                readLen = in.read(buffer);
                if(readLen <= 0) { throw new EndOfFileRuntimeException(); }
            }
            return buffer[pos++];
        }

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

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

        public char nextChar() throws IOException {
            while(true) {
                final int c = read();
                if(!isSpace[c]) { return (char)c; }
            }
        }

        int reads(char[] cs, int len, boolean[] accept) throws IOException {
            try {
                while(true) {
                    final int c = read();
                    if(accept[c]) { break; }
                    str[len++] = (char)c;
                }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return len;
        }

        public char[] nextLine() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isLineSep);

            try {
                if(str[len-1] == '\r') { len--; read(); }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return Arrays.copyOf(str, len);
        }

        public String nextString() throws IOException {
            return new String(next());
        }

        public char[] next() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isSpace);
            return Arrays.copyOf(str, len);
        }

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

    }

}

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

public class first
{
	static long fast_power(long a,long n,long m)
	{
		if(n==1)
		{
			return a%m;
		}
		if(n%2==1)
		{

			long power = fast_power(a,(n-1)/2,m)%m;
			return ((a%m) * ((power*power)%m))%m;
		}
		long power = fast_power(a,n/2,m)%m;
		return (power*power)%m;
	}
	public static void main(String arr[])
	{
		Scanner sc= new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int j = 1000000009;
		if(n==0)
		{
			System.out.println(0);return;
		}
		int todo = (n/k)*(k-1)+n%k;
		long score = m;
		long less = score-(long)todo;
		if(less>0)
		{
			long remain = score-less*k;
			score = ((fast_power(2,less+1,j)-(long)2)*(k))%j;
			score = (score+remain%j)%j;
		}
		System.out.println(score);

	}
}

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

public class A {

	private long pow(long num, long pow, long mod) {
		if (pow <= 0) {
			return 1;
		}
		if ((pow & 1) != 0) {
			return (num * pow(num, pow-1, mod)) % mod;
		}
		else {
			long tmp = pow(num, pow>>1, mod) % mod;
			return (tmp*tmp)%mod;
		}
	}

	public void run() {
		long MOD = 1000000009;
		long n = nextInt();
		long m = nextInt();
		long k = nextInt();

		long critical = n/k;
		if (n-critical >= m) {
			out.println(m);
		}
		else {
			long doubles = m - (n-critical);
			long ans = (pow(2, doubles, MOD) + MOD)%MOD;
			ans = (ans * k)%MOD;
			ans = (ans + (m-doubles*k))%MOD;
			out.println(ans);
		}
		out.flush();
	}

	private static BufferedReader br = null;
	private static StringTokenizer stk = null;
	private static PrintWriter out = null;

	public static void main(String[] args) throws IOException {
		br = new BufferedReader(new InputStreamReader(System.in));
		out = new PrintWriter(System.out);
		(new A()).run();
	}

	private void loadLine() {
		try {
			stk = new StringTokenizer(br.readLine());
		}
		catch (IOException e) {
			e.printStackTrace();
		}
	}

	private int nextInt() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return Integer.parseInt(stk.nextToken());
	}

	private long nextLong() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return Long.parseLong(stk.nextToken());
	}

	private double nextDouble() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return Double.parseDouble(stk.nextToken());
	}

	private String nextWord() {
		while (stk==null || !stk.hasMoreElements()) loadLine();
		return (stk.nextToken());
	}

}

import java.io.*;
import java.math.BigInteger;
import java.util.*;
import static java.util.Arrays.*;

public class A {
    private static final int mod = (int)1e9+9;

    final IOFast io = new IOFast();

    long k;

    long rec(long n, long m, long cur) {
        long pow = 1;
        long margin = 10;
        long p = 1000;
        for(int i = 0; i < p; i++) pow = pow * 2 % mod;
        while(true) {
            if(n + 1 >= (m / (k - 1) * k + m % (k - 1)) || m < k) { return (m + cur) % mod; }
            long q = (p + margin) * k;
            if(n - q + 1 < ((m - q) / (k - 1) * k + (m - q) % (k - 1)) && m >= q) {
                n -= p * k;
                m -= p * k;
                cur = cur * pow % mod;
                cur += (pow - 1) * 2 * k % mod;
                cur %= mod;
                continue;
            }
            n -= k;
            m -= k;
            cur += k;
            cur = cur * 2 % mod;
//          System.err.println(cur);
        }
    }

    public void run() throws IOException {
        long n = io.nextLong();
        long m = io.nextLong();
        k = io.nextLong();
//      io.out.println(rec(n, m, 0));
//      if(true) return;

        long low = -1, high = m / k + 1;
        while(high - low > 1) {
            long mid = (low + high) / 2;
            long u = mid * k;
            if(m < u) { high = mid; continue; }
            if(u + (m - u) / (k - 1) * k + (m - u) % (k - 1) - 1 > n) {
                low = mid;
            }
            else {
                high = mid;
            }
        }

        long pow = powmod(2, high, mod);
        long score = m - high * k;
        score = (score + (pow - 1) * 2 * k) % mod;
        io.out.println(score);
    }

    static long powmod(long n, long r, int m) {
        long res = 1;
        for(; r != 0; r >>>= 1, n = n * n % m) {
            if((r&1) == 1) {
                res = res * n;
                if(res >= m) {
                    res %= m;
                }
            }
        }
        return res;
    }

    void main() throws IOException {
        //      IOFast.setFileIO("rle-size.in", "rle-size.out");
        try {
            run();
        }
        catch (EndOfFileRuntimeException e) { }
        io.out.flush();
    }

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

    static class EndOfFileRuntimeException extends RuntimeException {
        private static final long serialVersionUID = -8565341110209207657L; }

    static
    public class IOFast {
        private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        private PrintWriter out = new PrintWriter(System.out);

        void setFileIO(String ins, String outs) throws IOException {
            in = new BufferedReader(new FileReader(ins));
            out = new PrintWriter(new FileWriter(outs));
        }

        //      private static final int BUFFER_SIZE = 50 * 200000;
        private static int pos, readLen;
        private static final char[] buffer = new char[1024 * 8];
        private static final char[] str = new char[500000*8*2];
        private static boolean[] isDigit = new boolean[256];
        private static boolean[] isSpace = new boolean[256];
        private static boolean[] isLineSep = new boolean[256];

        static {
            for(int i = 0; i < 10; i++) { isDigit['0' + i] = true; }
            isDigit['-'] = true;
            isSpace[' '] = isSpace['\r'] = isSpace['\n'] = isSpace['\t'] = true;
            isLineSep['\r'] = isLineSep['\n'] = true;
        }

        public int read() throws IOException {
            if(pos >= readLen) {
                pos = 0;
                readLen = in.read(buffer);
                if(readLen <= 0) { throw new EndOfFileRuntimeException(); }
            }
            return buffer[pos++];
        }

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

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

        public char nextChar() throws IOException {
            while(true) {
                final int c = read();
                if(!isSpace[c]) { return (char)c; }
            }
        }

        int reads(char[] cs, int len, boolean[] accept) throws IOException {
            try {
                while(true) {
                    final int c = read();
                    if(accept[c]) { break; }
                    str[len++] = (char)c;
                }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return len;
        }

        public char[] nextLine() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isLineSep);

            try {
                if(str[len-1] == '\r') { len--; read(); }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return Arrays.copyOf(str, len);
        }

        public String nextString() throws IOException {
            return new String(next());
        }

        public char[] next() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isSpace);
            return Arrays.copyOf(str, len);
        }

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

    }

}

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

public class code
{
    static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

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

    public static void main(String args[])throws IOException
    {
        FastReader scn = new FastReader();

        long n = scn.nextLong();
        long m = scn.nextLong();
        long k = scn.nextLong();

        if( ( ( (n+1)/k)*(k-1) ) >= m )
        {
            System.out.println(m);
            return;
        }

        long ans_mid = -1;
        long l = 0;
        long r = m;
        while(l <= r)
        {
            long mid = (l+r)/2;

            long possible  = (mid + 1) + (((n - 1 - mid)*(k-1))/k);
            if(possible >= m)
            {
                r = mid - 1;
                ans_mid = mid;
            }
            else
            {
                l = mid + 1;
            }
        }
        long P = 1000000009L;
        long points = ((n - 1 - ans_mid)*(k-1))/k;
        points = points % P;

        points += (ans_mid + 1)%k;
        points = points % P;

        long power = (ans_mid + 1)/k;
        long points2 = getTwoPower(power + 1, P);

        points2 = (points2 - 2)%P;
        points2 = (points2 * k)%P;

        points += points2;
        points = points % P;
        if(points < 0)
            points = points + P;
        System.out.println(points);
    }

    public static long getTwoPower(long power, long P)
    {
        if(power == 0)
            return 1;
        if(power == 1)
            return 2;

        long ans = getTwoPower(power/2, P);
        ans = (ans * ans)%P;
        if(power % 2 == 1)
            ans = (ans * 2)%P;
        return ans;
    }

    public static int getIndex(int[] list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list[middle]==value)
                return middle;
            else if(list[middle] < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return -1;
    }

    public static int getLessThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return r;
    }

    public static int getMoreThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return l;
    }

    public static long inverseModulo(long a, long P)
    {
        return powerModulo(a, P-2, P);
    }

    public static long powerModulo(long a, long p, long m)
    {
        if(p==0)
            return 1;

        long temp = powerModulo(a, p/2, m);
        temp = (temp * temp)%m;
        if(p%2 == 0)
            return temp;
        else
            return (a * temp)%m;

    }
}

class Pair implements Comparable<Pair>
{
    int a, b;

    public Pair(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public int compareTo(Pair p)
    {
        return this.b - p.b;
    }
}

class Node
{
    int value;
    int req_value;
    ArrayList<Integer> neighbors;
    boolean visited;

    public Node()
    {
        neighbors = new ArrayList<>();
    }

}

class MutableInt
{
    int count;
    ArrayList<Integer> list;
    public MutableInt()
    {
        list = new ArrayList<>();
    }
}

import java.io.DataInputStream;
import java.io.FileInputStream;
import java.io.IOException;
import java.util.Arrays;

public class Quiz {
	static int mod = 1000000009;

	static 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[10005]; // 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();
		}
	}

	public static void main(String[] args) throws IOException {
		Reader in = new Reader();
		int i, t, n, m, k, buckets;
		long ans = 0;
		n = in.nextInt();
		m = in.nextInt();
		k = in.nextInt();
		if (n == 0 || m == 0) {
			System.out.println("0");
			return;
		}
		buckets = n - m + 1;
		if (buckets >= m) {
			System.out.println(m);
			return;
		}
//		if()
		int maxInABucket = k - 1;
		int val[] = new int[buckets];
		i = 0;
		t = m;
		int filled = 0;
		while (t > 0) {
			if (t - (maxInABucket - filled) >= 0) {
				val[i] += maxInABucket - filled;
				t -= maxInABucket - filled;
			} else {
				val[i] += t;
				t = 0;
			}
			i++;
			if (i == buckets) {
				break;
//				i = 0;
//				filled = maxInABucket;
//				maxInABucket += k;
			}
		}
		filled = maxInABucket;
		maxInABucket += k;
		if (t > 0) {
			i = 0;
			while (t > 0) {
				if (t - (maxInABucket - filled) >= 0) {
					val[0] += maxInABucket - filled;
					t -= maxInABucket - filled;
				} else {
					val[0] += t;
					t = 0;
				}
				filled = maxInABucket;
				maxInABucket += k;
				i = (i + 1) % buckets;
			}
		}
		System.out.println(Arrays.toString(val));
		for (i = 0; i < buckets; i++) {
			int x = 0;
			for (int j = 1; j <= val[i]; j++) {
				ans = ((ans % mod) + 1) % mod;
				x++;
				if (x == k) {
					ans = ((ans % mod) * 2) % mod;
					x = 0;
				}
			}
		}
		System.out.println(ans);
	}
}

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

public class code
{
	static class FastReader
    {
        BufferedReader br;
        StringTokenizer st;

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

        String next()
        {
            while (st == null || !st.hasMoreElements())
            {
                try
                {
                    st = new StringTokenizer(br.readLine());
                }
                catch (IOException  e)
                {
                    e.printStackTrace();
                }
            }
            return st.nextToken();
        }

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

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

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

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

    public static void main(String args[])throws IOException
	{
        FastReader scn = new FastReader();

        long n = scn.nextLong();
        long m = scn.nextLong();
        long k = scn.nextLong();

        if( ( ( (n+1)/k)*(k-1) ) >= m )
        {
            System.out.println(m);
            return;
        }

        long ans_mid = -1;
        long l = 0;
        long r = m;
        while(l <= r)
        {
            long mid = (l+r)/2;

            long possible  = (mid + 1) + (((n - 1 - mid)/k)*(k-1));
            if(possible >= m)
            {
                r = mid - 1;
                ans_mid = mid;
            }
            else
            {
                l = mid + 1;
            }
        }

        long P = 1000000009L;
        long points = ((n - 1 - ans_mid)/k)*(k-1) ;
        points += (ans_mid + 1)%k;

        long power = (ans_mid + 1)/k;
        long points2 = getTwoPower(power + 1, P);

        points2 = (points2 - 2)%P;
        points2 = (points2 * k)%P;

        points += points2;
        if(points < 0)
            points = points + P;
        System.out.println(points);
	}

    public static long getTwoPower(long power, long P)
    {
        if(power == 0)
            return 1;
        if(power == 1)
            return 2;

        long ans = getTwoPower(power/2, P);
        ans = (ans * ans)%P;
        if(power % 2 == 1)
            ans = (ans * 2)%P;
        return ans;
    }

    public static int getIndex(int[] list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list[middle]==value)
                return middle;
            else if(list[middle] < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return -1;
    }

    public static int getLessThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return r;
    }

    public static int getMoreThanIndex(ArrayList<Integer> list, int value, int l, int r)
    {
        while( l <= r)
        {
            int middle = (l+r)/2;

            if(list.get(middle)==value)
                return middle;
            else if(list.get(middle) < value)
                l = middle + 1;
            else
                r = middle - 1;
        }
        return l;
    }

    public static long inverseModulo(long a, long P)
    {
        return powerModulo(a, P-2, P);
    }

    public static long powerModulo(long a, long p, long m)
    {
        if(p==0)
            return 1;

        long temp = powerModulo(a, p/2, m);
        temp = (temp * temp)%m;
        if(p%2 == 0)
            return temp;
        else
            return (a * temp)%m;

    }
}

class Pair implements Comparable<Pair>
{
    int a, b;

    public Pair(int a, int b)
    {
        this.a = a;
        this.b = b;
    }

    public int compareTo(Pair p)
    {
        return this.b - p.b;
    }
}

class Node
{
    int value;
    int req_value;
    ArrayList<Integer> neighbors;
    boolean visited;

    public Node()
    {
        neighbors = new ArrayList<>();
    }

}

class MutableInt
{
    int count;
    ArrayList<Integer> list;
    public MutableInt()
    {
        list = new ArrayList<>();
    }
}

import java.util.Scanner;
import java.math.BigInteger;
public class Quiz337C {

    public static void main(String[] args) {
        Scanner input = new Scanner(System.in);
        int questions = input.nextInt();
        int correct = input.nextInt();
        int multiplier = input.nextInt();

        //long kMinusResult = kMinusOneAssembler(questions, correct, multiplier);
        //int bruteForceResult = bruteForce(questions, correct, multiplier);
        //System.out.printf("The k minus one result is: %d\n",kMinusResult);
        //System.out.printf("The brute force result is: %d\n",bruteForceResult);

        int noMults = (int) Math.floor(questions/multiplier) - (questions - correct);
        if(noMults == 0)
        {
            System.out.print(correct);
            input.close();
            return;
        }
        int correctsRemaining = correct - (noMults * multiplier);
        BigInteger total = new BigInteger("2");
        BigInteger two = new BigInteger("2");
        BigInteger modulus = new BigInteger("1000000009");
        BigInteger exponent = BigInteger.valueOf(noMults + 1);
        BigInteger correctsBig = BigInteger.valueOf(correctsRemaining);
        BigInteger multiplierBig = BigInteger.valueOf(multiplier);
        //System.out.printf("Exponent: %d\n",exponent.longValue());
        //System.out.printf("Modulus: %d\n",modulus.longValue());
        total = total.modPow(exponent, modulus);
        total = total.subtract(two);

        //System.out.printf("Number of ks: %d\n",total.longValue());

        total = total.multiply(multiplierBig);

        //System.out.printf("Multiplier: %d\n", multiplierBig.longValue());

        //System.out.printf("Value from ks: %d\n",total.longValue());

        total = total.add(correctsBig);

        total = total.mod(modulus);

        input.close();

        System.out.print(total.longValue());

        return;

    }
    /*
    public static long kMinusOneAssembler(int questions, int correct, int multiplier)
    {
        boolean questionAnswers[] = new boolean[questions];
        int index = questions - 1;
        int remainingCorrects = correct;
        int remainingIncorrects = questions - correct;
        int untilMultiplier = multiplier;
        while(remainingCorrects != 0 || remainingIncorrects != 0)
        {
            if(untilMultiplier > 1)
            {
                if(remainingCorrects > 0)
                {
                    questionAnswers[index] = true;
                    untilMultiplier--;
                    remainingCorrects--;
                }
                else
                {
                    questionAnswers[index] = false;
                    untilMultiplier = multiplier;
                    remainingIncorrects--;
                }
            }
            else
            {
                if(remainingIncorrects > 0)
                {
                    questionAnswers[index] = false;
                    untilMultiplier = multiplier;
                    remainingIncorrects--;
                }
                else
                {
                    questionAnswers[index] = true;
                    untilMultiplier = multiplier;
                    remainingCorrects--;
                }
            }
            index--;
        }

        return arrayToScore(questionAnswers, questions, multiplier);
    }

    public static int bruteForce(int questions, int correct, int multiplier)
    {
        return 0;
    }

    public static long arrayToScore(boolean[] answers, int questions, int multiplier)
    {
        long total = 0;
        int index = 0;
        int untilMultiplier = multiplier;
        while(index < questions)
        {
            if(answers[index])
            {
                total++;
                untilMultiplier--;
                if(untilMultiplier == 0)
                {
                    total *= 2;
                    untilMultiplier = multiplier;
                }
            }
            else
            {
                untilMultiplier = multiplier;
            }
            total = total % 1000000009;
            index++;
        }
        return total;
    }
    */
}

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C337
{

	public static long mod = 1000000009;
	public static long INF = (1L << 60);
	static FastScanner2 in = new FastScanner2();
	static OutputWriter out = new OutputWriter(System.out);
	static int n,m,k;
	public static boolean func(int x)
	{
		//x consecutive true
		//n-x-1 remains and true has to be m-x
		int blocksize=(n-x-1)/k;
		int trueinother=blocksize*(k-1)+(n-x-1)%k;
		return (trueinother+x)>=m;
	}
	public static void main(String[] args)
	{

		n=in.nextInt();
		m=in.nextInt();
		k=in.nextInt();
		int l=0;
		int r=m;
		int answer=0;
		while(l<r)
		{
			int mid=(l+r)/2;
			if(func(mid))
			{
				answer=mid;
				r=mid;
			}
			else
			{
				l=mid+1;
			}
		}
		answer/=k;
		long ans=m+(pow(2, answer+1, mod)-(answer+2))*k;
		out.println((ans%mod+mod)%mod);
		out.close();

	}

	public static long pow(long x, long n)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p))
		{
			if ((n & 1) != 0)
			{
				res = (res * p);
			}
		}
		return res;
	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FastScanner2
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

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

		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 String nextString()
		{
			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 long nextLong()
		{
			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 int nextInt()
		{
			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 int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private 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 InputReader
	{
		public BufferedReader reader;
		public StringTokenizer tokenizer;

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

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

		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[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextLong();
			}
			return a;
		}

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

	static class OutputWriter
	{
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(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 println(Object... objects)
		{
			print(objects);
			writer.println();
		}

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

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

}

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

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;
        }
    }
    public static long mod=1000000009,N=1000000009;
    static long exponentiation(long base, long exp)
    {
        if (exp == 0)
            return 1;
        if (exp == 1)
            return base % N;
        long t = exponentiation(base, exp / 2);
        t = (t * t) % N;
        if (exp % 2 == 0)
            return t;
        else
            return ((base % N) * t) % N;
    }
    public static void main(String[] args)throws Exception
    {
        InputReader in=new InputReader(System.in);
        PrintWriter w=new PrintWriter(System.out);
        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long[] power=new long[10000000];
        long ng=(n/k);
        if(n==m)
        {
            long div=n/k;
            long num=0,count=0;
            num=((((exponentiation(2L,div+1L)%mod-(2%mod))*(k%mod))%mod + m)%mod - ((div%mod)*(k%mod))%mod)%mod;
            w.println(num);
        }
        else
        {
            if(n%k==(k-1))
                ng++;
            if(ng*(k-1)>=m)
            {
                w.println(m);
            }
            else
            {
                long score=0;
                long x=m-n+(n/k);
                long count=0;
                //w.println(x);
                score=((((exponentiation(2L,x+1L)%mod-(2%mod))*(k%mod))%mod + m)%mod - ((x%mod)*(k%mod))%mod)%mod;

                w.println(score);
            }
        }
        w.close();
    }
}

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

public class Main {
    public static void main(String args[])throws Exception
    {
        BufferedReader br=new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st;
        st=new StringTokenizer(br.readLine());
        long n=Long.parseLong(st.nextToken());
        long m=Long.parseLong(st.nextToken());
        long k=Long.parseLong(st.nextToken());
        long may=n/k;
        may=(k-1)*may;
        may+=(n%k);
        if(may>=m)
        {
            System.out.print(m);
            return ;
        }
        else
        {
            long diff=m-may;
            long score=0;
            long may1=diff*(k-1);
            score=may-may1;
            long count=0;
            for(int i=0;i<diff;i++)
            {
                count+=k;
                count*=2;
            }
            score+=count;
            System.out.print(score);
        }
    }
}

import java.awt.*;
import java.awt.event.*;
import java.awt.geom.*;
import java.io.*;
import java.math.*;
import java.text.*;
import java.util.*;

/*
br = new BufferedReader(new FileReader("input.txt"));
pw = new PrintWriter(new BufferedWriter(new FileWriter("output.txt")));
br = new BufferedReader(new InputStreamReader(System.in));
pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
 */

public class Main {
  private static BufferedReader br;
  private static StringTokenizer st;
  private static PrintWriter pw;

  public static void main(String[] args) throws IOException {
    br = new BufferedReader(new InputStreamReader(System.in));
    pw = new PrintWriter(new BufferedWriter(new OutputStreamWriter(System.out)));
    //int qq = 1;
    int qq = Integer.MAX_VALUE;
    //int qq = readInt();
    for(int casenum = 1; casenum <= qq; casenum++)  {
      int n = readInt();
      int correct = readInt();
      int consecutive = readInt();
      int wrong = n - correct;
      int lastWrong = n+1;
      if(wrong > 0) {
        lastWrong = n - (consecutive - 1) - (wrong-1) * consecutive;
        lastWrong = Math.max(0, lastWrong);
      }
      int numDoubles = (lastWrong-1) / consecutive;
      long ret = 0;
      if(numDoubles > 0) {
        ret = 2 * (modpow(2, numDoubles, 1000000009)-1) * consecutive;
        ret %= 1000000009;
      }
      ret += Math.max(0, correct - numDoubles * consecutive);
      ret %= 1000000009;
      pw.println(ret);
    }
    pw.close();
  }

  public static long modpow(long b, long e, long m) {
    long r = 1;
    while(e > 0) {
      if(e%2==1) {
        r*=b;
        r%=m;
      }
      b*=b;
      b%=m;
      e/=2;
    }
    return r;
  }

  private static void exitImmediately() {
    pw.close();
    System.exit(0);
  }

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

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

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

  private static String nextToken() throws IOException  {
    while(st == null || !st.hasMoreTokens())  {
      if(!br.ready()) {
        exitImmediately();
      }
      st = new StringTokenizer(br.readLine().trim());
    }
    return st.nextToken();
  }
}

import java.math.BigInteger;
import java.util.Scanner;

public class Quiz {
	static int x = 1000000009;
	static long ModExp(long base,long power)
	{
		if (power == 0)
			return 1;
		if (power == 1)
			return base%x;

		if (power%2==1) {
			return (base*ModExp(base, power-1))%x;
		}
		else
		{
			long intermediate = ModExp(base, power/2)%x;
			return (intermediate*intermediate)%x;
		}
	}
	public static void main(String args[])
	{
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int rightSeq = k-1;
		int a = Math.min(m/rightSeq, n-m+1);
		int score = Math.min(m,a*(k-1));
		m -= score;
		if (m%k!=0)
		{
			score -= (k-m%k);
			m += (k-m%k);
		}
		BigInteger b = new BigInteger("2");
		BigInteger c = new BigInteger((m/k+1)+"");

		System.out.println(((ModExp(2, m/k+1)-2)*k+score)%x);
	}
}

import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;
public class C {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        // PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        // StringTokenizer st = new StringTokenizer(bf.readLine());
        // int n = Integer.parseInt(st.nextToken);
        // int n = Integer.parseInt(bf.readLine());
        Scanner scan = new Scanner(System.in);
        long n = scan.nextLong();
        long m = scan.nextLong();
        long k = scan.nextLong();
        long x = n-m;
        long noofones = n-k*(n-m);
        long intblocks = noofones/k;
        long remainder = noofones % k;
        long valones = (long)(pow(intblocks) - 1)*k;
        long totval = valones * 2 + remainder;
        long ans = totval + (k-1)*x;
        ans = ans % 1000000009;
        if(m == 0) ans = 0;
        if(m < k) ans = m;
        if(m == k) ans = 2*m;
        System.out.println(ans);
    }
    public static long pow(long n) {
        long ans = 1;
        n = n % 1000000008;
        long div = n/63;
        long rem = n % 63;
        for(int i=0; i<div; i++) {
            ans = ans * 844428231;
            ans = ans % 1000000009;
        }
        long mult = (long) (Math.pow(2, rem) % 1000000009);
        ans *= mult;
        ans = ans % 1000000009;
        return ans;
    }

}

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

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;
        }
    }
    public static long mod=1000000009,N=1000000009;
    static long exponentiation(long base, long exp)
    {
        if (exp == 0)
            return 1;
        if (exp == 1)
            return base % N;
        long t = exponentiation(base, exp / 2);
        t = (t * t) % N;
        if (exp % 2 == 0)
            return t;
        else
            return ((base % N) * t) % N;
    }
    public static void main(String[] args)throws Exception
    {
        InputReader in=new InputReader(System.in);
        PrintWriter w=new PrintWriter(System.out);
        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long[] power=new long[10000000];
        long ng=(n/k);
        if(n==m)
        {
            long div=n/k;
            long num=0,count=0;
            num=((exponentiation(2L,div+1L)%mod)*(k%mod))%mod;
            if(n%k!=0 && ((div*k)<m))
            {
                long req=(m-((div%mod)*(k%mod)));
                num=((num%mod)+(req%mod))%mod;
            }
            w.println(num);
        }
        else
        {
            if(n%k==(k-1))
                ng++;
            if(ng*(k-1)>=m)
            {
                w.println(m);
            }
            else
            {
                long score=0;
                long x=m-n+(n/k);
                long count=0;
                score=((exponentiation(2L,x+1L)%mod)*(k%mod))%mod;
                ng=(n/k)-x;

                long rq=(long)Math.min(ng,m-(x*k));
                score+=((rq%mod)*((k-1)%mod))%mod;

                if(m>(rq*(k-1))+(x*k))
                {
                    score+=n%k;
                }
                w.println(score);
            }
        }
        w.close();
    }
}

import java.util.Scanner;

public class Main {

	final static long Mod = 1000000009;
    static long n, m, k, t, l, u, ans;
    static Scanner cin = new Scanner(System.in);

    static long multi_mod(long base, long cur) {
		long res = 1;
		while(cur > 0) {
			if(cur % 2 == 1) res = (res * base) % Mod;
			cur >>= 1;
			base = (base * base) % Mod;
		}
    	return res;
    }

	public static void main(String[] args) {
		n = cin.nextLong(); m = cin.nextLong(); k = cin.nextLong();
	    l = (k - 1)*(n / k) + n % k;
        if(m <= l) {
            System.out.println(m);
        }
        else {
        	t = n / k;
        	u = m - l;
        	ans = (0 + (t - u) * (k - 1) + n % k) % Mod;
        	System.out.println(ans);
        	ans = (ans + (k)*(multi_mod(k, u + 1) - 2) % Mod) % Mod;
        	System.out.println(ans);
        }
	}
}

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

public class Template {
	public static void main(String[] args) throws IOException {
		st = new StringTokenizer(rd.readLine());
		n = Long.parseLong(st.nextToken());
		m = Long.parseLong(st.nextToken());
		k = Long.parseLong(st.nextToken());
		long s = n - m;
		s = Math.min(s, m / (k - 1));
		s = Math.min(s, n / k);
		long score = 0;
		score = s * (k - 1);
		long n1 = n - k * s, m1 = m - (k - 1) * s;
		if (m1 == n1) {
			score = (score + full(m1)) % P;
			System.out.println(score);
			return;
		}
		if (n1 <= k) {
			score = (score + m1) % P;
			System.out.println(score);
			return;
		}
	}

	static long full(long N) {
		long x = N / k, r = N - x * k;
		long powTwo = powMod(2, x + 1) - 2 - x;
		powTwo = (powTwo * 2) % P;
		powTwo = (powTwo * k) % P;
		powTwo = (powTwo + r) % P;
		return powTwo;
	}

	static long powMod(long a, long p) {
		if (p == 0)
			return 1L;
		long h = powMod(a, (p >> 1));
		h = (h * h) % P;
		return p % 2 == 0 ? h : (a * h) % P;
	}

	static long n, m, k;

	static long P = 1000000009;

	static StringTokenizer st;
	static BufferedReader rd = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter pw = new PrintWriter(System.out);

}

import java.math.BigInteger;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Scanner;

public class Program {

	/**
	 * @param args
	 */
	public static void main(String[] args) {
		Scanner sc = new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int blocks = n / k;
		int left = n % k;
		int max = blocks * (k - 1) + left;
		if (max >= m)
			System.out.println(m);
		else {
			int error = m - max;
			long bonus = modulo(2,error, 1000000009);
			bonus--;
			bonus*=2;
			bonus = bonus % 1000000009;
			bonus*=k;
			bonus = bonus % 1000000009;
			long rest = m - error * k;
			long result = bonus+rest;
			result = bonus % 1000000009;

			// BigInteger compensation = new BigInteger(String.valueOf(k));
			// compensation = compensation.add(new BigInteger("1"));
			// compensation = compensation.multiply(new
			// BigInteger(String.valueOf(error)));
			// result = result.add(compensation);
			System.out.println(result);
		}
	}

	private static int GCD(int a, int b) {
		if (b == 0)
			return a;
		else
			return GCD(b, a % b);
	}

	private static int LCD(int a, int b) {
		return (a / (GCD(a, b))) * b;
	}

	private static int min(int a, int b) {
		return a < b ? a : b;
	}

	private static int modulo(int a, int b, int c) {
		long x = 1;
		long y = a;
		while (b > 0) {
			if (b % 2 == 1) {
				x = (x * y) % c;
			}
			y = (y * y) % c; // squaring the base
			b /= 2;
		}
		return (int) x % c;
	}
}

import java.io.*;
import java.math.BigInteger;
import java.util.*;
import static java.util.Arrays.*;

public class A {
    private static final int mod = (int)1e9+9;

    final IOFast io = new IOFast();

    long k;

    long rec(long n, long m, long cur) {
        long pow = 1;
        long p = 1000;
        for(int i = 0; i < p; i++) pow = pow * 2 % mod;
        while(true) {
            if(n / k >= m || m < k) { return (m + cur) % mod; }
            if((n - p * 10) / k < (m - p * 10) && m >= (p + 10) * k) {
                n -= p * k;
                m -= p * k;
                cur = cur * pow % mod;
                cur += (pow - 1) * 2 * k % mod;
                cur %= mod;
                continue;
            }
            n -= k;
            m -= k;
            cur += k;
            cur = cur * 2 % mod;
        }
    }

    public void run() throws IOException {
        long n = io.nextLong();
        long m = io.nextLong();
        k = io.nextLong();
        io.out.println(rec(n, m, 0));
    }

    void main() throws IOException {
        //      IOFast.setFileIO("rle-size.in", "rle-size.out");
        try {
            run();
        }
        catch (EndOfFileRuntimeException e) { }
        io.out.flush();
    }

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

    static class EndOfFileRuntimeException extends RuntimeException {
        private static final long serialVersionUID = -8565341110209207657L; }

    static
    public class IOFast {
        private BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
        private PrintWriter out = new PrintWriter(System.out);

        void setFileIO(String ins, String outs) throws IOException {
            in = new BufferedReader(new FileReader(ins));
            out = new PrintWriter(new FileWriter(outs));
        }

        //      private static final int BUFFER_SIZE = 50 * 200000;
        private static int pos, readLen;
        private static final char[] buffer = new char[1024 * 8];
        private static final char[] str = new char[500000*8*2];
        private static boolean[] isDigit = new boolean[256];
        private static boolean[] isSpace = new boolean[256];
        private static boolean[] isLineSep = new boolean[256];

        static {
            for(int i = 0; i < 10; i++) { isDigit['0' + i] = true; }
            isDigit['-'] = true;
            isSpace[' '] = isSpace['\r'] = isSpace['\n'] = isSpace['\t'] = true;
            isLineSep['\r'] = isLineSep['\n'] = true;
        }

        public int read() throws IOException {
            if(pos >= readLen) {
                pos = 0;
                readLen = in.read(buffer);
                if(readLen <= 0) { throw new EndOfFileRuntimeException(); }
            }
            return buffer[pos++];
        }

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

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

        public char nextChar() throws IOException {
            while(true) {
                final int c = read();
                if(!isSpace[c]) { return (char)c; }
            }
        }

        int reads(char[] cs, int len, boolean[] accept) throws IOException {
            try {
                while(true) {
                    final int c = read();
                    if(accept[c]) { break; }
                    str[len++] = (char)c;
                }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return len;
        }

        public char[] nextLine() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isLineSep);

            try {
                if(str[len-1] == '\r') { len--; read(); }
            }
            catch(EndOfFileRuntimeException e) { ; }

            return Arrays.copyOf(str, len);
        }

        public String nextString() throws IOException {
            return new String(next());
        }

        public char[] next() throws IOException {
            int len = 0;
            str[len++] = nextChar();
            len = reads(str, len, isSpace);
            return Arrays.copyOf(str, len);
        }

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

    }

}

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

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;
        }
    }
    public static void main(String[] args)throws Exception
    {
        InputReader in=new InputReader(System.in);
        PrintWriter w=new PrintWriter(System.out);
        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long ng=(n/k);

        if(n%k==(k-1))
            ng++;
        if(ng*(k-1)>=m)
        {
            w.println(m);
        }
        else
        {
            long scr=ng*(k-1);
            long used=scr;
            long dif=m-used;
            scr+=dif;
            scr+=(k*dif);
            w.println(scr);
        }
        w.close();
    }
}

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

public class Problem2 {

	public static void main(String[] args){
		// TODO Auto-generated method stub
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		long MOD = 1000000009;
		long n = in.nextLong(), m= in.nextLong(), k = in.nextLong();
		long x = Math.max(0, m - (n/k)*(k-1) - n%k);
		long a = modExp(2, x + 1, MOD);
		//out.println(a);
		out.println(( (a - 2) * (k % MOD) + m % MOD - (x%n) * (k%n) ) % MOD);
		out.close();

	}

	static long modExp( long a, long b,  long MOD)
	{
		long bi;
		long ans = 1;
		String s = Long.toBinaryString(b);
		for(int i = 0; i < s.length(); ++i)
		{
			ans = (ans * ans) % MOD;
			if(s.charAt(i) == '1')
			{
				ans = (ans * a) % MOD;
			}
		}
		return ans;
	}

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

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

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

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

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

	}

}

import static java.lang.System.in;
import static java.lang.System.out;

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

public class C337quiz {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	int MAX = 1000000009;

	int pow (int n, int k){
		if (k==0) return 1;
		long res = pow(n, k/2);
		res = (res*res)%MAX;
		if (k%2==1) res = (res*n)%MAX;
		return (int)res;
	}

	public void run() throws IOException {
		String input;
		String[] inputArray;
		input = br.readLine();
		inputArray = input.split(" ");

		int n = Integer.valueOf(inputArray[0]);
		int m = Integer.valueOf(inputArray[1]);
		int k = Integer.valueOf(inputArray[2]);
		int t = n/k;
		int ans = m;
		if (m>(t*(k-1) + n%k)){
			int r = m - (t*(k-1) + n%k);
			ans = (ans + (pow(2,r)-1)*k) %MAX;
		}
		sb.append(ans);
		ln(sb);
	}

	public static void main(String[] args) throws IOException {
		new C337quiz().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}

import java.math.BigInteger;
import java.util.Scanner;

public class Main {
	public static void main(String[] args) {

		Scanner Input=new Scanner(System.in);
		long n=Input.nextLong(),m=Input.nextLong(),k=Input.nextLong();
		long x=(n/k)*(k-1)+(n%k);
		if(m<=x)System.out.println(m);
		else{
		BigInteger MOD=BigInteger.valueOf(1000000009);
		BigInteger X=BigInteger.valueOf(x);
		BigInteger K=BigInteger.valueOf(k);
		BigInteger extra=BigInteger.valueOf(m-x);
		X=X.subtract( extra.multiply(K.subtract(BigInteger.valueOf(1)))  );
		BigInteger Ans=BigInteger.valueOf(2);
		Ans=Ans.modPow(extra.add(BigInteger.valueOf(1)), MOD);
		Ans=Ans.subtract(BigInteger.valueOf(2));
		Ans=(Ans.multiply(K.mod(MOD)).mod(MOD));
		Ans=(Ans.mod(MOD)).add(X);
		System.out.println(Ans);
		}

		Input.close();

	}

}

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

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

public class Main {

    public static void main(String[] args) throws IOException {
        new Main().run();
    }
    StreamTokenizer in;
    PrintWriter out;
    //deb////////////////////////////////////////////////

    public static void deb(String n, Object n1) {
        System.out.println(n + " is : " + n1);
    }

    public static void deb(int[] A) {

        for (Object oo : A) {
            System.out.print(oo + " ");
        }
        System.out.println("");
    }

    public static void deb(long[] A) {

        for (Object oo : A) {
            System.out.print(oo + " ");
        }
        System.out.println("");
    }

    public static void deb(BigInteger[] A) {

        for (Object oo : A) {
            System.out.print(oo + " ");
        }
        System.out.println("");
    }

    public static void deb(int[][] A) {
        for (int i = 0; i < A.length; i++) {
            for (Object oo : A[i]) {
                System.out.print(oo + " ");
            }
            System.out.println("");
        }

    }

    public static void deb(long[][] A) {
        for (int i = 0; i < A.length; i++) {
            for (Object oo : A[i]) {
                System.out.print(oo + " ");
            }
            System.out.println("");
        }

    }

    public static void deb(String[][] A) {
        for (int i = 0; i < A.length; i++) {
            for (Object oo : A[i]) {
                System.out.print(oo + " ");
            }
            System.out.println("");
        }

    }
    /////////////////////////////////////////////////////////////

    int nextInt() throws IOException {
        in.nextToken();
        return (int) in.nval;
    }

    long nextLong() throws IOException {
        in.nextToken();
        return (long) in.nval;
    }

    class Pair<X, Y> {

        public X x;
        public Y y;

        public Pair(X x, Y y) {
            this.x = x;
            this.y = y;
        }

        public void setX(X x) {
            this.x = x;
        }

        public void setY(Y y) {
            this.y = y;
        }
    }

    boolean inR(int x, int y) {
        return (x >= 0) && (x < nn) && (y >= 0) && (y < nn);
    }
    static int nn;

    void run() throws IOException {
        //  in = new StreamTokenizer(new BufferedReader(new FileReader("circles.in")));
        //  out = new PrintWriter(new FileWriter("circles.out"));
        in = new StreamTokenizer(new BufferedReader(new InputStreamReader(System.in)));
        out = new PrintWriter(new OutputStreamWriter(System.out));
        solve();
        out.flush();
    }
    static long MOD=1000000009;
static long modPow(long a, int pow) {
        long res = 1;
        while (pow > 0) {
            if ((pow & 1) != 0) {
                res = res * a % MOD;
            }
            pow >>= 1;
            a = a * a % MOD;
        }
        return res;
    }

    void solve() throws IOException {
        //   BufferedReader re= new BufferedReader(new FileReader("C:\\Users\\ASELA\\Desktop\\A.in"));
       // BufferedReader re = new BufferedReader(new InputStreamReader(System.in));
        int n=nextInt(),m=nextInt(),k=nextInt();
        int an=n/k+n%k;
        long ans=0;
        if(an>=m){
            System.out.println(m);
            return;
        }
        int rem=m-an;
        ans=modPow(2, rem+1)-2;
        ans*=k;
        ans+=m-rem*k;
        ans%=MOD;
       // System.out.println("sjkd"+rem);
        if(ans<0)ans+=MOD;
        System.out.println(ans);
    }
}

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

public class Task implements Runnable {
    static FastReader in;
    static PrintWriter out;

    static final long  MOD = 1000000009;

    static long modpow(long a, long b) {
        long ret = 1;
        for (; b > 0; b >>= 1) {
            if ((b & 1) == 1) {
                ret = ret * a % MOD;
            }
            a = a * a % MOD;
        }
        return ret;
    }

    public void solve() throws IOException {
        long n = in.nextLong();
        long m = in.nextLong();
        long k = in.nextLong();
        long t = Math.max(0, m - n % k - n / k * (k - 1));
        long score = modpow(2, t + 1) - 2 - t;
        score = (score * k + m) % MOD;
        out.println(score);
    }

    public void run() {
        try {
            in = new FastReader();
            out = new PrintWriter(System.out);
            solve();
            out.close();
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

class FastReader {
    BufferedReader br;
    StringTokenizer in;

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

    FastReader(String filename) {
        try {
            this.br = new BufferedReader(new FileReader(filename));
        } catch (IOException e) {
            e.printStackTrace();
            System.exit(1);
        }
    }

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

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

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

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

import java.util.Scanner;

public class Main {
    static int mod = 1000000009;

    public static int pow(int n, int x) {
        if (x == 0)
            return 1;
        if (x % 2 == 0) {
            int temp = pow(n, x / 2) % mod;
            long ans = ((long)(temp) * temp) % mod;
            return (int) ans;
        } else {
            int temp = pow(n, x / 2) % mod;
            long ans = ((long)(temp) * temp * n) % mod;
            return (int) ans;
        }
    }

    public static void main(String[] args) {
        // System.out.println(p ow(2,3,4223));
        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int temp = (m / (k - 1)) - 1;
        if (temp < n - m)
            System.out.println(m);
        else {
            long single = (k - 1) * (n - m);
            int remain = (int) (m - single);
            single += remain % k;
            remain -= remain % k;
            long t = pow(2, remain / k + 1);
            t -= 2;
        //  System.out.println(t);
            t *= k;
            t = (t + single) % 1000000009;
            System.out.println(t);
        }
    }
}

import java.util.*;

public class Quiz{
	static int MOD = (int)1e9 + 9;
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		long n = reader.nextInt();
		long m = reader.nextInt();
		long k = reader.nextInt();

		long r = (n + k - 1)/k;
		long d = m - (r * (k-1));

		if(d <= 0){
			System.out.println(m);
			return;
		}

		long sum = (fastExpo(2,d+1)-2) * k + (m - d*k);
		System.out.println(sum%MOD);
	}

	public static long fastExpo(long b, long p){
		if(p == 0)
			return 1;
		if(p % 2 == 1)
			return (b * fastExpo(b, p-1))%MOD;
		long x = fastExpo(b, p/2);
		return (x * x)%MOD;
	}
}

import java.util.*;

public class CF337C {

    public static void main(String[] args) {

        Scanner in = new Scanner(System.in);
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int maxcon = n/k;

        int last = n - maxcon * k;
        int db = m - (k - 1) * maxcon - last;
        int nondb = maxcon - db;
        int mod = 1000000009;

        long score = 0;
        long temp;
        if (db > 0)
        {
            long pow2 = (long)(Math.pow(2, db) - 1) % mod;
            temp = 2 * k * pow2 % mod;
            score += temp;
        }
        temp = (k-1) * nondb % mod;
        score += temp;
        score += last % mod;

        System.out.println(score);
    }
}

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Writer;
import java.math.BigInteger;
import java.util.Arrays;
import java.util.InputMismatchException;
import java.util.Random;
import java.util.Scanner;

/**
 *
 * @author WIN7
 */
public class Challenges {

    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        long d = 1000000009;
        long n = sc.nextInt();
        long m = sc.nextInt();
        long k = sc.nextInt();
        long y = ((n - m) * k) % d;
        long x = n - y;
        long z = x / k;
        long t = x % k;
        long c = 2 * k * ((long) Math.pow(2, z)-1);
        c = c % d;
        c = (c + t) % d;
        long points = (y - (n - m)) % d + c % d;
        if (n < k * (n - m + 1)) {
            System.out.println(m);
        } else {
            System.out.println(points);
        }
    }

    static class InputReader {

        private InputStream stream;
        private byte[] buf = new byte[1024];
        private int curChar;
        private int numChars;
        private SpaceCharFilter filter;

        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 boolean isSpaceChar(int c) {
            if (filter != null) {
                return filter.isSpaceChar(c);
            }
            return isWhitespace(c);
        }

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

        public interface SpaceCharFilter {

            public boolean isSpaceChar(int ch);
        }
    }

    static class OutputWriter {

        private final PrintWriter writer;

        public OutputWriter(OutputStream outputStream) {
            writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(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.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.text.DecimalFormat;
import java.util.StringTokenizer;

public class C implements Runnable {
    private final static long START_TIME=System.currentTimeMillis();
    private final static boolean LOG_ENABLED=true;
    private final static boolean ONLINE_JUDGE = LOG_ENABLED && (System.getProperty("ONLINE_JUDGE") != null);
    private final static String SYSTEM_ENCODING="utf-8";
    private final static int DEFAULT_BUFFER_SIZE=100000;

    private static class Logger{
        private final PrintWriter logWriter=Util.newPrintWriter(System.err,true);
        private final DecimalFormat df=new DecimalFormat("0.000");
        private void message(String type, String message, Object ... params){
            if(ONLINE_JUDGE){
                return;
            }
            logWriter.printf("["+type+"] "+df.format((System.currentTimeMillis()-START_TIME)/1000.0)+": "+message+"\r\n", params);
        }
        public void debug(String message, Object ... params){
            message("DEBUG", message, params);
        }
    }

    public final static class Util{
        public final static String LINE_SEPARATOR=System.getProperty("line.separator");
        public static PrintWriter newPrintWriter(OutputStream out, boolean autoFlush){
            try {
                return new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(out), SYSTEM_ENCODING),autoFlush);
            } catch (UnsupportedEncodingException e) {
                throw new IllegalStateException(e);
            }
        }

        public static PrintWriter newPrintWriter(Writer writer, boolean autoFlush){
            return new PrintWriter(writer,autoFlush);
        }

        private static void flushStringBuilder(Writer writer, StringBuilder sb) throws IOException {
            if(sb.length()>DEFAULT_BUFFER_SIZE){
                writer.append(sb);
                sb.setLength(0);
            }
        }

        public static void printArray(Writer writer, Object ... elements) throws IOException{
            StringBuilder sb = new StringBuilder();
            boolean first=true;
            for(Object o:elements){
                if(first){
                    first=false;
                }else{
                    sb.append(" ");
                }
                sb.append(o);
                flushStringBuilder(writer, sb);
            }
            sb.append(LINE_SEPARATOR);
            writer.append(sb);
        }
        public static void printArray(Writer writer, int ... elements) throws IOException{
            StringBuilder sb = new StringBuilder();
            boolean first=true;
            for(Object o:elements){
                if(first){
                    first=false;
                }else{
                    sb.append(" ");
                }
                sb.append(o);
                flushStringBuilder(writer, sb);
            }
            sb.append(LINE_SEPARATOR);
            writer.append(sb);
        }

    }

    public final static class FastScanner{
        private BufferedReader reader;
        private StringTokenizer currentTokenizer;
        public FastScanner(Reader reader) {
            if(reader instanceof BufferedReader){
                this.reader=(BufferedReader) reader;
            }else{
                this.reader=new BufferedReader(reader);
            }
        }

        public String next(){
            if(currentTokenizer==null || !currentTokenizer.hasMoreTokens()){
                try {
                    currentTokenizer=new  StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new IllegalStateException(e);
                }
            }

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

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

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

    }

    private final static Logger log=new Logger();
    private final BufferedReader reader;
    private final FastScanner in;
    private final PrintWriter out;

    public C(Reader reader, Writer writer){
        this.reader=new BufferedReader(reader);
        this.out=new PrintWriter(writer,false);
        in=new FastScanner(this.reader);
    }

    public static void main(String[] args) throws IOException {
        new C(new InputStreamReader(System.in, SYSTEM_ENCODING),new OutputStreamWriter(new BufferedOutputStream(System.out), SYSTEM_ENCODING)).run();
    }

    public void run(){
        log.debug("Started");
        try{
            solve();
            out.flush();
        }finally{
            log.debug("Stopped");
        }
    }

    private void solve(){
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int endCount=(n-m)/(k-1);
        if((n-m)%(k-1)!=0){
            endCount++;
        }
        int beginCount=m-endCount;

        if(beginCount<0){
            beginCount=0;
        }
        int div=1000000009;
        long score=getScore2(k,div,beginCount);
        score+=endCount*(k-1);

        long x = Math.max(0, m - (n - n % k) / k * (k-1) - n % k);

        out.println(((exponentiationBySquaring(2, x+1, div)-2)*k + m-x*k)%div);
    }

    /**
     * @return
     */
    private long getScore(int k, int div, int beginCount) {
        long score=0;

        for(int i=0;i<beginCount/k;i++){
            score=(score+k)*2;
            if(score>div){
                score=score%div;
            }
        }
        return (score+beginCount%k)%div;
    }

    private long getScore2(int k, int div, int beginCount) {
        long result = (exponentiationBySquaring(2,(beginCount/k)+1,div)-2)*k+beginCount%k;
        return result;
    }
    long pow(long value, long pow, long div){
        long result=1;
        for(int i=0;i<pow;i++){
            result=(result*value)%div;
        }
        return result;
    }
    private static long exponentiationBySquaring(long number, long pow, long mod) {
        final int MAX_BIT=62;
        long mask=1l<<MAX_BIT;
        long result=1l;
        boolean modEnabled=mod>0;
        while(mask>0){
            result*=result;
            if(modEnabled){
                result%=mod;
            }
            if((mask&pow)!=0){
                result*=number;
            }
            if(modEnabled){
                result%=mod;
            }
            mask>>=1;
        }
        return result;
    }

}

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

public class Myclass {
     static ArrayList a[]=new ArrayList[3000001];
     static boolean visited[]=new boolean [3000001];

     public static void main(String[]args)
    {
        InputReader in=new InputReader(System.in);
        PrintWriter pw = new PrintWriter(System.out);
        long mod=(long) (1e9+9L);
        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long div=(long) Math.ceil((double)(n*1F)/(1F*(n-m+1)));
        if(div-1<k)
        	pw.print(m%mod);
        else
        {
        	long have=k*(n-m);
        	long take=(n-have)/k;
        	long ans=0L;
        	if(take>0) {
            	long diff=((2*k+k)*2-(k*2));
            	diff%=mod;
            	if(take>1)
            		ans=((k*2)%mod+(diff*(modularExponentiation(2,take-1,mod))%mod)%mod)%mod;
            	else
            		ans=(k*2)%mod;

        	}
        	ans=(take%k+ans)%mod;
        	ans=(have-(n-m)+mod+ans)%mod;
        	pw.print(ans);
        }

        pw.flush();
        pw.close();

    }
    private static void debug(Object... o) {
        System.out.println(Arrays.deepToString(o));
    }
   static class InputReader
        {
        private final InputStream stream;
        private final byte[] buf = new byte[8192];
        private int curChar, snumChars;
        private SpaceCharFilter filter;

        public InputReader(InputStream stream)
        {
            this.stream = stream;
        }
        public int snext()
        {
            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 = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            int res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } while (!isSpaceChar(c));
            return res * sgn;
        }

        public long nextLong()
        {
            int c = snext();
            while (isSpaceChar(c))
            {
                c = snext();
            }
            int sgn = 1;
            if (c == '-')
            {
                sgn = -1;
                c = snext();
            }
            long res = 0;
            do
            {
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = snext();
            } 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;
        }
        static class tri implements Comparable<tri> {
            int p, c, l;

            tri(int p, int c, int l) {
                this.p = p;
                this.c = c;
                this.l = l;
            }

            public int compareTo(tri o) {
                return Integer.compare(l, o.l);
            }
        }

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

        public String nextLine()
        {
            int c = snext();
            while (isSpaceChar(c))
                c = snext();
            StringBuilder res = new StringBuilder();
            do
            {
                res.appendCodePoint(c);
                c = snext();
            } while (!isEndOfLine(c));
            return res.toString();
        }

        public boolean isSpaceChar(int c)
        {
            if (filter != null)
                return filter.isSpaceChar(c);
            return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
        }

        private boolean isEndOfLine(int c)
        {
            return c == '\n' || c == '\r' || c == -1;
        }

        public interface SpaceCharFilter
        {
            public boolean isSpaceChar(int ch);
        }
    }
   public static long modularExponentiation(long x,long n,long M)
   {
       long result=1;
       while(n>0)
       {
           if(n % 2 ==1)
               result=(result%M * x%M)%M;
           x=(x%M * x%M)%M;
           n=n/2;
       }
       return result;
   }

   public static long modInverse(int A,int M)
   {
       return modularExponentiation(A,M-2,M);
   }

   public static long modInverse(long A,long M)
   {
       return modularExponentiation(A,M-2,M);
   }
    static class pair implements Comparable<pair>{
        Integer x;
        Integer y;

        pair(int x,int w){
            this.x=x;
            this.y=w;
        }

        public int compareTo(pair o) {
                int result = x.compareTo(o.x);
                if(result==0)
                    result = y.compareTo(o.y);

            return result;
            }
         public String toString(){
            return (x+" "+y);
        }
  }
    public static long GCD(long a,long b)
    {
        if(b==0)
            return a;
        else
            return GCD(b,a%b);
    }
  static class query{
      Integer x;
      Integer y;
      Integer z;
      query(int x,int y,int z){
          this.x=x;
          this.y=y;
          this.z=z;
      }
      public String toString() {
    	  return ((x+" "+y+" "+z));
      }
  }

}

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.InputMismatchException;

public class Quiz {

	static int mod = 1000000009;

	static long modPow(long x, long y, long m) {
		long exp = y;
		long base = x % m;
		long ans = 1;
		while (exp > 0) {
			if (exp % 2 == 1) {
				ans = (ans * base) % m;
			}
			base = (base * base) % m;
			exp = exp >> 1;
		}
		return ans;
	}

	public static void main(String[] args) {
		InputReader in = new InputReader(System.in);
		OutputWriter out = new OutputWriter(System.out);
		long n = in.readInt();
		long m = in.readInt();
		long k = in.readInt();
		long ans = 0;
		long cuts = m / (k - 1);
		if (n - m >= cuts) {
			ans = m;
		} else {
			cuts = n - m;
			ans += ((cuts) * (k - 1)) % mod;
			ans += ((m - (cuts) * (k - 1)) % k) % mod;
			int j = 1;
			long pow = (m - (cuts * (k - 1)) - (m - (cuts) * (k - 1)) % k) / k;
			long temp = modPow(2, pow + 1, mod);
			ans += ((temp - 2) * k) % mod;
			ans %= mod;
		}
		System.out.println(ans);
		out.close();
	}

	private static 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 long readLong() {
			int c = read();
			while (isSpaceChar(c))
				c = read();
			long 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 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 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();
		}

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

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

	private static 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.io.*;
import java.util.*;

public class first
{

	public static void main(String arr[])
	{
		Scanner sc= new Scanner(System.in);
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int j = 1000000009;
		if(n==0)
		{
			System.out.println(0);return;
		}
		int todo = (n/k)*(k-1)+n%k;
		long score = m;
		if((score-(long)todo)>0)
		{
			score=score+(score-(long)todo)*2;
		}
		System.out.println(score%j);

	}
}

import java.util.*;

public class Quiz{
	static int MOD = (int)1e9 + 9;
	public static void main(String[] args){
		Scanner reader = new Scanner(System.in);
		long n = reader.nextInt();
		long m = reader.nextInt();
		long k = reader.nextInt();

		long r = (n + k - 1)/k;
		long d = m - (r * (k-1));

		if(d <= 0){
			System.out.println(m);
			return;
		}

		long sum = (fastExpo(2,d+1)-2) * k + (m - d*k);
		System.out.println(sum);
	}

	public static long fastExpo(long b, long p){
		if(p == 0)
			return 1;
		if(p % 2 == 1)
			return (b * fastExpo(b, p-1))%MOD;
		long x = fastExpo(b, p/2);
		return (x * x)%MOD;
	}
}

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

public class Main {

    FastScanner in;
    PrintWriter out;

    static class FastScanner {

        BufferedReader br;
        StringTokenizer st;

        FastScanner(InputStream in) {
            br = new BufferedReader(new InputStreamReader(in));
            st = null;
        }

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

        String nextLine() throws IOException {
            if (st == null || !st.hasMoreTokens())
                return br.readLine();
            StringBuilder result = new StringBuilder(st.nextToken());
            while (st.hasMoreTokens()) {
                result.append(" ");
                result.append(st.nextToken());
            }
            return result.toString();
        }

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

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

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

    }

    void run() throws IOException {
        in = new FastScanner(System.in);
        out = new PrintWriter(System.out, false);
        solve();
        out.close();
    }

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

    public void printArr(int[] arr){
        for(int i = 0; i < arr.length; i++){
            out.print(arr[i] + " ");
        }
        out.println();
    }

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

    int mod = 1000000009;

    public long exp_by_square(long x, long e){
        if(e == 0) return 1;
        else if(e == 1) return x % mod;
        else if(e % 2 == 0) return exp_by_square(x * x % mod, e / 2) % mod;
        else if(e % 2 == 1) return (x * exp_by_square(x * x % mod, (x - 1) / 2)) % mod;

        return 1;
    }

    public void solve() throws IOException{

        int n = in.nextInt(), m = in.nextInt(), k = in.nextInt();
        int x = Math.max(0, m - n / k * (k - 1) - n % k);
        long ans = (exp_by_square(2, x + 1) - 2) * k % mod;
        ans = ans + (m - x * k) % mod;
        out.println(ans);

        return;
    }

}

import java.util.Scanner;

public class C {

    private static final int mod = 1000000009;

    public void solve() {
        Scanner s = new Scanner(System.in);
//        Scanner s = new Scanner("5 4 2");
//        Scanner s = new Scanner("5 3 2");

        int n = s.nextInt();
        int m = s.nextInt();
        int k = s.nextInt();

        int incorrect = n - m;
        int head = Math.max(n - incorrect * k, 0);
        int tail = m - head;

        int a = head / k;
        int b = head % k;

        long sum = ((pow(2, a+1, mod) - 2) * k) % mod;

        System.out.println(sum + tail + b);
    }

    public static long pow(long a, int n, long m) {
        if (n == 0) return 1;
        if (n % 2 == 0) {
            long r = pow(a, n / 2, m);
            return (r * r) % m;
        }
        return (a * pow(a, n - 1, m)) % m;
    }

    public static void main(String[] args) {
        C solver = new C();
        solver.solve();
    }

}

/*
 * 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.
 */

/**
 *
 * @author dipankar12
 */
import java.io.*;
import java.util.*;
public class r196c {
    static long fastpower(long x,long y)
    {
        long r=1;
        while(y>0)
        {
            if((y&1)==1)
                r=(r*x)%1000000009;
            x=(x*x)%1000000009;
            y>>=1;
        }
        //System.out.println("returning "+r);
        return r;
    }
    public static void main(String args[])
    {
        fastio in=new fastio(System.in);
        PrintWriter pw=new PrintWriter(System.out);

        long n=in.nextLong();
        long m=in.nextLong();
        long k=in.nextLong();
        long grps=Math.floorDiv(m - 1l *(n - m + 1) * (k - 1) + k - 1, k);
        if(grps<=0)
            pw.println(m);
        else
        {
            long score= m + (fastpower(2, grps + 1) - (grps + 2)) * k;;
            pw.println(score);
        }
        pw.close();
    }

    static class fastio {

            private final InputStream stream;
            private final byte[] buf = new byte[8192];
            private int cchar, snchar;
            private SpaceCharFilter filter;

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

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

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

            public long nextLong() {
                int c = nxt();
                while (isSpaceChar(c)) {
                    c = nxt();
                }
                int sgn = 1;
                if (c == '-') {
                    sgn = -1;
                    c = nxt();
                }
                long res = 0;
                do {
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    res *= 10;
                    res += c - '0';
                    c = nxt();
                } 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 = nxt();
                while (isSpaceChar(c)) {
                    c = nxt();
                }
                StringBuilder res = new StringBuilder();
                do {
                    res.appendCodePoint(c);
                    c = nxt();
                } while (!isSpaceChar(c));
                return res.toString();
            }

            public String nextLine() {
                int c = nxt();
                while (isSpaceChar(c))
                    c = nxt();
                StringBuilder res = new StringBuilder();
                do {
                    res.appendCodePoint(c);
                    c = nxt();
                } while (!isEndOfLine(c));
                return res.toString();
            }

            public boolean isSpaceChar(int c) {
                if (filter != null)
                    return filter.isSpaceChar(c);
                return c == ' ' || c == '\n' || c == '\r' || c == '\t' || c == -1;
            }

            private boolean isEndOfLine(int c) {
                return c == '\n' || c == '\r' || c == -1;
            }

            public interface SpaceCharFilter {
                public boolean isSpaceChar(int ch);
            }
        }

}

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

public class Solver {

    StringTokenizer st;
    BufferedReader in;
    PrintWriter out;

    public static void main(String[] args) throws NumberFormatException,
            IOException {
        Solver solver = new Solver();
        long time = System.currentTimeMillis();
        solver.open();
        solver.solve();
        //System.out.println("Spend time:" + (System.currentTimeMillis() - time));
        solver.close();
    }

    public void open() throws IOException {
        in = new BufferedReader(new InputStreamReader(System.in));
        out = new PrintWriter(new OutputStreamWriter(System.out));
    }

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

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

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

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

    long MOD = 1000000009l;

    long pow(long a, long n) {
        if (n==0) return 1;
        if ((n&1)==1){
            return a*pow(a,n-1)%MOD;
        }else{
            long b = pow(a,n/2);
            return b*b%MOD;
        }
    }

    public void solve() throws NumberFormatException, IOException {
        int n = nextInt();
        int m = nextInt();
        int k = nextInt();

        long maxComboCount = n / k;
        long needCombos = Math.max(maxComboCount - (n - m), 0);

        long result = (k*(pow(2, needCombos+1)-2) + (m-k*needCombos)) % MOD;

        out.println(result);
    }

    public void close() {
        out.flush();
        out.close();
    }
}

import java.io.BufferedOutputStream;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStream;
import java.io.OutputStreamWriter;
import java.io.PrintWriter;
import java.io.Reader;
import java.io.UnsupportedEncodingException;
import java.io.Writer;
import java.text.DecimalFormat;
import java.util.StringTokenizer;

public class C implements Runnable {
    private final static long START_TIME=System.currentTimeMillis();
    private final static boolean LOG_ENABLED=true;
    private final static boolean ONLINE_JUDGE = LOG_ENABLED && (System.getProperty("ONLINE_JUDGE") != null);
    private final static String SYSTEM_ENCODING="utf-8";
    private final static int DEFAULT_BUFFER_SIZE=100000;

    private static class Logger{
        private final PrintWriter logWriter=Util.newPrintWriter(System.err,true);
        private final DecimalFormat df=new DecimalFormat("0.000");
        private void message(String type, String message, Object ... params){
            if(ONLINE_JUDGE){
                return;
            }
            logWriter.printf("["+type+"] "+df.format((System.currentTimeMillis()-START_TIME)/1000.0)+": "+message+"\r\n", params);
        }
        public void debug(String message, Object ... params){
            message("DEBUG", message, params);
        }
    }

    public final static class Util{
        public final static String LINE_SEPARATOR=System.getProperty("line.separator");
        public static PrintWriter newPrintWriter(OutputStream out, boolean autoFlush){
            try {
                return new PrintWriter(new OutputStreamWriter(new BufferedOutputStream(out), SYSTEM_ENCODING),autoFlush);
            } catch (UnsupportedEncodingException e) {
                throw new IllegalStateException(e);
            }
        }

        public static PrintWriter newPrintWriter(Writer writer, boolean autoFlush){
            return new PrintWriter(writer,autoFlush);
        }

        private static void flushStringBuilder(Writer writer, StringBuilder sb) throws IOException {
            if(sb.length()>DEFAULT_BUFFER_SIZE){
                writer.append(sb);
                sb.setLength(0);
            }
        }

        public static void printArray(Writer writer, Object ... elements) throws IOException{
            StringBuilder sb = new StringBuilder();
            boolean first=true;
            for(Object o:elements){
                if(first){
                    first=false;
                }else{
                    sb.append(" ");
                }
                sb.append(o);
                flushStringBuilder(writer, sb);
            }
            sb.append(LINE_SEPARATOR);
            writer.append(sb);
        }
        public static void printArray(Writer writer, int ... elements) throws IOException{
            StringBuilder sb = new StringBuilder();
            boolean first=true;
            for(Object o:elements){
                if(first){
                    first=false;
                }else{
                    sb.append(" ");
                }
                sb.append(o);
                flushStringBuilder(writer, sb);
            }
            sb.append(LINE_SEPARATOR);
            writer.append(sb);
        }

    }

    public final static class FastScanner{
        private BufferedReader reader;
        private StringTokenizer currentTokenizer;
        public FastScanner(Reader reader) {
            if(reader instanceof BufferedReader){
                this.reader=(BufferedReader) reader;
            }else{
                this.reader=new BufferedReader(reader);
            }
        }

        public String next(){
            if(currentTokenizer==null || !currentTokenizer.hasMoreTokens()){
                try {
                    currentTokenizer=new  StringTokenizer(reader.readLine());
                } catch (IOException e) {
                    throw new IllegalStateException(e);
                }
            }

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

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

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

    }

    private final static Logger log=new Logger();
    private final BufferedReader reader;
    private final FastScanner in;
    private final PrintWriter out;

    public C(Reader reader, Writer writer){
        this.reader=new BufferedReader(reader);
        this.out=new PrintWriter(writer,false);
        in=new FastScanner(this.reader);
    }

    public static void main(String[] args) throws IOException {
        new C(new InputStreamReader(System.in, SYSTEM_ENCODING),new OutputStreamWriter(new BufferedOutputStream(System.out), SYSTEM_ENCODING)).run();
    }

    public void run(){
        log.debug("Started");
        try{
            solve();
            out.flush();
        }finally{
            log.debug("Stopped");
        }
    }

    private void solve(){
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();
        int endCount=(n-m)/(k-1);
        int beginCount=m-endCount;

        if(beginCount<0){
            beginCount=0;
        }
        int div=1000000009;
        long score=getScore2(k,div,beginCount);
        score+=endCount*(k-1);

        out.println(score%div);
    }

    /**
     * @return
     */
    private long getScore(int k, int div, int beginCount) {
        long score=0;

        for(int i=0;i<beginCount/k;i++){
            score=(score+k)*2;
            if(score>div){
                score=score%div;
            }
        }
        return (score+beginCount%k)%div;
    }

    private long getScore2(int k, int div, int beginCount) {
        long result = (exponentiationBySquaring(2,(beginCount/k)+1,div)-2)*k+beginCount%k;
        return result;
    }
    long pow(long value, long pow, long div){
        long result=1;
        for(int i=0;i<pow;i++){
            result=(result*value)%div;
        }
        return result;
    }
    private static long exponentiationBySquaring(long number, long pow, long mod) {
        final int MAX_BIT=62;
        long mask=1l<<MAX_BIT;
        long result=1l;
        boolean modEnabled=mod>0;
        while(mask>0){
            result*=result;
            if(modEnabled){
                result%=mod;
            }
            if((mask&pow)!=0){
                result*=number;
            }
            if(modEnabled){
                result%=mod;
            }
            mask>>=1;
        }
        return result;
    }

}

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

public class A {

	static final int mod = (int)1e9 + 7;

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

		int n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
		int delta = -1, lo = 0, hi = m / k;
		while(lo <= hi)
		{
			int mid = lo + hi >> 1;
			if((m - k * mid + k - 2) / (k - 1) <= (n - m + 1))
			{
				delta = mid;
				hi = mid - 1;
			}
			else
				lo = mid + 1;
		}
		if(delta == 0)
			out.println(m);
		else
		{
			long score = m + (powMod(2, delta + 1) - (delta + 2)) * k;
			out.println((score % mod + mod) % mod);
		}
		out.flush();
		out.close();
	}

	static long powMod(long b, long e)
	{
		long r = 1;
		while(e > 0)
		{
			if((e & 1) == 1)
				r = r * b % mod;
			b = b * b % mod;
			e >>= 1;
		}
		return r;
	}

	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 double nextDouble() throws IOException { return Double.parseDouble(next()); }

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

import static java.lang.System.in;
import static java.lang.System.out;

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

public class C337quiz {
	static final double EPS = 1e-10;
	static final double INF = 1 << 31;
	static final double PI = Math.PI;

	public static Scanner sc = new Scanner(in);
	StringBuilder sb = new StringBuilder();
	BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
	int MAX = 1000000009;

	int pow (int n, int k){
		if (k==0) return 1;
		long res = pow(n, k/2);
		res = (res*res)%MAX;
		if (k%2==1) res = (res*n)%MAX;
		return (int)res;
	}

	public void run() throws IOException {
		String input;
		String[] inputArray;
		input = br.readLine();
		inputArray = input.split(" ");

		int n = Integer.valueOf(inputArray[0]);
		int m = Integer.valueOf(inputArray[1]);
		int k = Integer.valueOf(inputArray[2]);
		int t = n/k;
		int ans = m;
		if (m>(t*(k-1) + n%k)){
			int r = m - (t*(k-1) + n%k);
			ans = (ans + (pow(2,r+1)-r-2)*k) %MAX;
		}
		sb.append(ans);
		ln(sb);
	}

	public static void main(String[] args) throws IOException {
		new C337quiz().run();
	}
	public static void ln(Object obj) {
		out.println(obj);
	}
}

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

public class Main implements Runnable {

	public void _main() throws IOException {
		long n = nextLong();
		long m = nextLong();
		long k = nextLong();
		long numBlocks = Math.min(n / k, n - m);
		n -= numBlocks * k;
		m -= numBlocks * (k - 1);
		long numFullBlocks = m / k;
		long rem = m % k;
		long res = 0;
		res = (res + ((p2(numFullBlocks + 1) + MOD - 2) % MOD) * k) % MOD;
		res = (res + rem) % MOD;
		res = (res + numBlocks * (k - 1)) % MOD;
		out.println(res);
	}

	final int MOD = 1000000009;
	private long p2(long s) {
		long res = 1;
		long x = 2;
		while (s > 0) {
			if (s % 2 == 1) {
				res = res * x % MOD;
			}
			x = x * x % MOD;
			s /= 2;
		}
		return res;
	}

	private BufferedReader in;
	private PrintWriter out;
	private StringTokenizer st;

	private String next() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String rl = in.readLine();
			if (rl == null)
				return null;
			st = new StringTokenizer(rl);
		}
		return st.nextToken();
	}

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

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

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

	public static void main(String[] args) {
		Locale.setDefault(Locale.UK);
		new Thread(new Main()).start();
	}

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);
			//in = new BufferedReader(new FileReader("a.in"));
			//out = new PrintWriter(new FileWriter("a.out"));

			_main();

			out.close();
		} catch (Exception e) {
			e.printStackTrace();
			System.exit(202);
		}
	}

}

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

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

class TaskA {
    private static final long MOD = 1000000009;

    public void solve(int testNumber, Reader in, OutputWriter out) {
        long answer = 0;
        int n = in.nextInt();
        int m = in.nextInt();
        int k = in.nextInt();

        int l = -1;
        int r = n + 1;

        while (l + 1 < r) {
            int c = (l + r) / 2;
            if(n < c * k || canAchieve(n - c * k, k) >= m - c * k) {
                r = c;
            }
            else
                l = c;
        }

        //out.println(r);

        int c = r;

        answer = ((IntegerUtils.power(2, c + 1, MOD) - 2 + MOD) % MOD) * k % MOD;

        n -= k * c;
        m -= k * c;
        answer += m;
        answer %= MOD;

        out.println(answer);
    }

    private int canAchieve(int n, int k) {
        return n - n / k;
    }
}

class Reader {
    private BufferedReader reader;
    private StringTokenizer tokenizer;

    public Reader(BufferedReader reader) {
        this.reader = reader;
    }

    public Reader(InputStream stream) {
        this(new BufferedReader(new InputStreamReader(stream)));
    }

    public String nextString() {
        while (tokenizer == null || !tokenizer.hasMoreTokens()) {
            tokenizer = new StringTokenizer(readLine());
        }
        return tokenizer.nextToken();
    }

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

    private String readLine() {
        try {
            return reader.readLine();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }
}

class OutputWriter extends PrintWriter {

	public OutputWriter(OutputStream out) {
		super(out);
	}

	public OutputWriter(java.io.Writer writer){
		super(writer);
	}

	}

class IntegerUtils {

	public static long power(long base, long power, long mod) {
		long result = 1 % mod;
		base %= mod;
		while (power > 0) {
			if (power % 2 == 1) {
				result *= base;
				result %= mod;
			}
			base *= base;
			base %= mod;
			power >>= 1;
		}
		return result;
	}

	}

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
    public long MOD = (long)1e9 + 9;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long N = in.nextLong();
        long M = in.nextLong();
        long K = in.nextLong();

        long left = M - (N / K * (K - 1) + N % K);
        if (left <= 0) {
            out.println(M);
            return;
        }

        long single = M - left * K;
        long res = (powMod(2, left) * K % MOD + single) % MOD;
        out.println(res);
    }

    private long powMod(long a, long b) {
        if(b == 0) return 1;
        long res = powMod(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1)
            res = res * a % MOD;
        return res;
    }
}

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

public class Solution {

    public static void solve(InputReader in, PrintWriter out, DebugWriter debug) throws IOException {
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();

        long x = Math.max(0, m - (n - n % k) / k * (k-1) - n % k);

        long scoreNoSerial = m-x*k;
        long scoreSerial = ((pow2(x)-1)*k*2) % mod ;

        debug.println(x);
        debug.println(scoreNoSerial);
        debug.println(scoreSerial);

        out.println(scoreSerial+scoreNoSerial);
    }

    public static long mod = (long) Math.pow(10, 9)+9;

    public static long pow2(long x){
        long[] array2 = new long[64];
        array2[0] = 2;

        for (int i=1; i<array2.length; i++){
            array2[i] = (array2[i-1]*array2[i-1]) % mod;
            //System.out.println( i + ": " + array2[i]);
        }

        long ans = 1;
        String binary = Long.toBinaryString(x);
        //System.out.println("Bin: " + binary);
        for (int i=binary.length()-1; i>=0; i--){
            if (binary.charAt(i) == '1'){
                ans *= array2[binary.length()-1-i];
                ans %= mod;
            }
        }

        //System.out.println("2^" + x + "=" + ans);
        return ans;
    }

    public static void main(String[] args) throws IOException{
        InputReader in;
        PrintWriter out;
        DebugWriter debug;

        if (args.length > 0 && args[0].equals("file")) {
            in = new InputReader(new BufferedReader(new FileReader("input.txt")));
            out = new PrintWriter(new FileWriter("output.txt"));
            debug = new DebugWriter(true);

            int sampleNumber = 1;
            do {
                String nextSample = "Sample #" + sampleNumber++ + ": ";
                out.println(nextSample);
                debug.println(nextSample);

                solve(in, out, debug);

                out.println("");
                debug.println("");
            } while (in.reader.readLine() != null);
        } else {
            in = new InputReader(new BufferedReader(new InputStreamReader(System.in)));
            out = new PrintWriter(new OutputStreamWriter(System.out));
            debug = new DebugWriter(false);

            solve(in, out, debug);
        }

        in.reader.close();
        out.close();
    }

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

        public InputReader(BufferedReader reader) {
            this.reader = reader;
            tokenizer = null;
        }

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

            return tokenizer.nextToken();
        }

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

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

            return array;
        }
    }

    public static class DebugWriter {
        public boolean enable;

        public DebugWriter(boolean enable){
            this.enable = enable;
        }

        public void print(Object o){
            if (enable) System.out.print(o);
        }

        public void println(Object o){
            if (enable) System.out.println(o);
        }
    }

}

import java.io.*;
import java.util.*;
import java.text.*;
import java.math.*;
import java.util.regex.*;
import java.math.BigInteger;
import java.math.RoundingMode;
public class a {
    public static int vertices=0;
    public static void main(String[] args) {
       Scanner s = new Scanner(System.in);
       long n=s.nextLong();
       long m=s.nextLong();
       long k=s.nextLong();
      if(n*(k-1)>=(long)m*k-1)
          System.out.println(m);
      else{
       BigInteger bi1=new BigInteger(Long.toString((long)(k-1)*(n-m)));
          System.out.println(bi1);
       BigInteger bi2=new BigInteger(Long.toString((long)m*k-(long)n*(k-1)));
          System.out.println(bi2);
       BigInteger bi3=bi2.divide(new BigInteger(Long.toString(k)));
       bi1=bi1.add(bi2.mod(new BigInteger(Long.toString(k))));
       BigInteger bi4=new BigInteger("2");
       BigInteger bi5=bi4.modPow(bi3.add(new BigInteger("1")),new BigInteger("1000000009"));
       bi5=bi5.multiply(new BigInteger(Long.toString(k)));
       bi5=bi5.subtract(new BigInteger(Long.toString(2*k)));
       bi1=bi1.add(bi5);
       bi1=bi1.mod(new BigInteger("1000000009"));
          System.out.println(bi1);
      }
   }
}

import java.util.Scanner;

public class C {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long s=0;
		int n=sc.nextInt(),m=sc.nextInt(),k=sc.nextInt(),c=n/k;
		if(m<=c*(k-1)+(n%k))System.out.println(m);
		else {
			int a=m-c*(k-1)-(n%k);
			long l=0,pase=0;
			for(int i=0;i<a;i++) {
				s+=2*(l+1);
				l=s;
				pase+=k;
			}
			System.out.println(l*k+m-pase);
		}
	}
}

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

public class Quiz {
    public static void main(String[]args)throws IOException{
        BufferedReader f = new BufferedReader(new InputStreamReader(System.in));
        StringTokenizer st = new StringTokenizer(f.readLine());
        int n,m,k, cycles, remainder;
        long result = 0;
        BigInteger ans = new BigInteger("1");
        n = Integer.parseInt(st.nextToken());
        m = Integer.parseInt(st.nextToken());
        k = Integer.parseInt(st.nextToken());
        if(m <= (n - (n/k))){
            System.out.println(m);
        }else{
            cycles = (m - (n - (n/k)));
            remainder = m - (cycles*k);
            System.out.println(cycles + " " + remainder);
            result = power(2,cycles+1,1000000009);
            result *= k;
            result = result%1000000009;
            result -= k*2;
            result += remainder;
            while(result<0){
                result += 1000000009;
            }
            System.out.println(result);
            }

    }
    public static long power(long base, long exponent, long mod) {
        if (base >= mod)
            base %= mod;
        if (exponent == 0)
            return 1 % mod;
        long result = power(base, exponent >> 1, mod);
        result = result * result % mod;
        if ((exponent & 1) != 0)
            result = result * base % mod;
        return result;
    }
}

import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.PrintWriter;
import java.io.Writer;
import java.util.InputMismatchException;

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 = (long)(N - M) * (long)(K - 1);
				long x = (M - ans);
				long y = x / K;
				long z = x % K;
				val = (int) (pow(2, y, bigMod) % bigMod);
				//System.out.println(val);
				ans += ((((2 * (long)(val - 1)) % bigMod) * K) % bigMod + z)
						% bigMod;
				System.out.println(ans);
			}
		}

		out.close();
	}

	public static long pow(long a, long b, long 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();
    }

}

//package CF;

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

public class B {

	public static void main(String[] args) throws Exception {
		Scanner sc = new Scanner(System.in);
		PrintWriter out = new PrintWriter(System.out);
		long n = sc.nextInt(), m = sc.nextInt(), k = sc.nextInt();
		int mod = (int) 1e9 + 7;
		long res = m;
		if (n - m < (m + k - 2) / (k - 1) - 1) {
			long tmp = m - ((n/ k)*(k-1)+n%k);
//			System.out.println(tmp);
			res = (modPow(2, tmp + 1, mod) - 2 + mod) % mod * k % mod;
			res = (res + (m-tmp*k+mod)%mod) % mod;
		}
		out.println(res);
		out.flush();
		out.close();
	}

	static long modPow(long a, long e, int mod) // O(log e)
	{
		a %= mod;
		long res = 1;
		while (e > 0) {
			if ((e & 1) == 1)
				res = (res * a) % mod;
			a = (a * a) % mod;
			e >>= 1;
		}
		return res;
	}

	static class Scanner {
		BufferedReader bf;
		StringTokenizer st;

		public Scanner(InputStream i) {
			bf = new BufferedReader(new InputStreamReader(i));

		}

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

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

		public double nextDouble() throws IOException {
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double 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 long nextLong() throws NumberFormatException, IOException {
			return Long.parseLong(next());
		}
	}
}

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

public class Solution {

    public static void solve(InputReader in, PrintWriter out, DebugWriter debug) throws IOException {
        long n = in.nextInt();
        long m = in.nextInt();
        long k = in.nextInt();

        long x = Math.max(0, m - (n - n % k) / k * (k-1) - n % k);

        long scoreNoSerial = m-x*k;
        long scoreSerial = 0;
        for (int i=0; i<x; i++){
            scoreSerial += k;
            scoreSerial *= 2;
        }

        debug.println(x);
        debug.println(scoreNoSerial);
        debug.println(scoreSerial);

        out.println(scoreSerial+scoreNoSerial);
    }

    public static void main(String[] args) throws IOException{
        InputReader in;
        PrintWriter out;
        DebugWriter debug;

        if (args.length > 0 && args[0].equals("file")) {
            in = new InputReader(new BufferedReader(new FileReader("input.txt")));
            out = new PrintWriter(new FileWriter("output.txt"));
            debug = new DebugWriter(true);

            int sampleNumber = 1;
            do {
                String nextSample = "Sample #" + sampleNumber++ + ": ";
                out.println(nextSample);
                debug.println(nextSample);

                solve(in, out, debug);

                out.println("");
                debug.println("");
            } while (in.reader.readLine() != null);
        } else {
            in = new InputReader(new BufferedReader(new InputStreamReader(System.in)));
            out = new PrintWriter(new OutputStreamWriter(System.out));
            debug = new DebugWriter(false);

            solve(in, out, debug);
        }

        in.reader.close();
        out.close();
    }

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

        public InputReader(BufferedReader reader) {
            this.reader = reader;
            tokenizer = null;
        }

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

            return tokenizer.nextToken();
        }

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

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

            return array;
        }
    }

    public static class DebugWriter {
        public boolean enable;

        public DebugWriter(boolean enable){
            this.enable = enable;
        }

        public void print(Object o){
            if (enable) System.out.print(o);
        }

        public void println(Object o){
            if (enable) System.out.println(o);
        }
    }

}

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

public class Template {
	public static void main(String[] args) throws IOException {
		st = new StringTokenizer(rd.readLine());
		n = Long.parseLong(st.nextToken());
		m = Long.parseLong(st.nextToken());
		k = Long.parseLong(st.nextToken());
		long s = n - m;
		s = Math.min(s, m / (k - 1));
		s = Math.min(s, n / k);
		long score = 0;
		score = s * (k - 1);
		long n1 = n - k * s, m1 = m - (k - 1) * s;
		if (m1 == n1) {
			score = (score + full(m1)) % P;
			System.out.println(score);
			return;
		}
		if (n1 <= k) {
			score = (score + m1) % P;
			System.out.println(score);
			return;
		}
	}

	static long full(long N) {
		long x = N / k, r = N - x * k;
		long powTwo = powMod(2, x + 1) - 2 - x;
		powTwo = (powTwo * 2) % P;
		powTwo = (powTwo * k) % P;
		powTwo = (powTwo + r) % P;
		return powTwo;
	}

	static long powMod(long a, long p) {
		if (p == 0)
			return 1L;
		long h = powMod(a, (p >> 1));
		h = (h * h) % P;
		return p % 2 == 0 ? h : (a * h) % P;
	}

	static long n, m, k;

	static long P = 1000000009;

	static StringTokenizer st;
	static BufferedReader rd = new BufferedReader(new InputStreamReader(
			System.in));
	static PrintWriter pw = new PrintWriter(System.out);

}

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

public class Problem2 {

	public static void main(String[] args){
		// TODO Auto-generated method stub
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		InputReader in = new InputReader(inputStream);
		PrintWriter out = new PrintWriter(outputStream);
		long MOD = 1000000009;
		long n = in.nextLong(), m= in.nextLong(), k = in.nextLong();
		long x = Math.max(0, m - (n/k)*(k-1) - n%k);
		long a = modExp(2, x + 1, MOD);
		out.println(a);
		long ans = ( (a - 2) * (k % MOD) + m % MOD - (x%MOD) * (k%MOD) ) % MOD;
		if(ans < 0)
		{
			ans = ans + MOD;
		}
		out.println(ans);
		out.close();

	}

	static long modExp( long a, long b,  long MOD)
	{
		long ans = 1;
		String s = Long.toBinaryString(b);
		for(int i = 0; i < s.length(); ++i)
		{
			ans = (ans * ans) % MOD;
			if(s.charAt(i) == '1')
			{
				ans = (ans * a) % MOD;
			}
		}
		return ans;
	}

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

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

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

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

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

	}

}

import java.util.*;

public class ProblemC {
    public static void main(String[] args) {
        game G=new game();
        G.input();
        G.solve();
    }
}

class game {
    long n,m,k;
    long modulo=1000000009;

    public long mu(long a,long b) {
        if (b==1) return a;
        if (b==0) return 1;
        else {
            long k=mu(a,b/2);
            if (b%2==0) return ((k%modulo)*(k%modulo))%modulo;
            else return (a*((k%modulo)*(k%modulo))%modulo)%modulo;
        }
    }

    public void input() {
        Scanner in = new Scanner(System.in);
        n=in.nextLong();
        m=in.nextLong();
        k=in.nextLong();
        in.close();
    }

    public void solve() {
        long mod=n%k,div=n/k,so=div*(k-1)+mod,con=m-so;
        if (con==0) {
            System.out.println(so%modulo);
        }
        else {
            long no = so-(con*(k-1));
            long diem = k*2*mu(3,con-1);
            long kq=(no+diem)%modulo;
            System.out.println(kq);
        }
    }
}

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

public class P337C {

	/**
	 * @param args
	 * @throws IOException
	 */
	public static void main(String[] args) throws IOException {
		BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
		String[] info = br.readLine().split(" ");
		long questions = Long.parseLong(info[0]);
		long correctQts = Long.parseLong(info[1]);
		long consCorrQts = Long.parseLong(info[2]);
		long minScore = getMinimumScore(questions, correctQts, consCorrQts);
		System.out.println(minScore);
	}

	private static long getMinimumScore(long questions, long correctQts,
			long consCorrQts) {
		long by = 1000000009;
		long div = questions/consCorrQts;
		long blocks = questions - div;
		long missing = correctQts - blocks;
		long dupliScore = ((missing%by)*(2*consCorrQts))%by;
		long normalScore = ((blocks-missing)%by) * (consCorrQts-1);
		long minScore = (dupliScore + normalScore)%by;
		return minScore;
	}

}

import java.io.*;
import java.util.*;
import java.math.*;
import static java.lang.Math.*;
import static java.lang.Integer.parseInt;
import static java.lang.Long.parseLong;
import static java.lang.Double.parseDouble;
import static java.lang.String.*;

public class Main {

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

    public static void main(String[] args) throws IOException {

        BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
                                            //(new FileReader("input.in"));
        StringBuilder out = new StringBuilder();
        StringTokenizer tk;
        //PrintWriter pw = new PrintWriter("output.out", "UTF-8");

        tk = new StringTokenizer(in.readLine());
        long n = parseLong(tk.nextToken()),m = parseLong(tk.nextToken()),k = parseLong(tk.nextToken());

        long mn = Integer.MAX_VALUE;
        long l=0,r=m,mid;

        while(l <= r) {
            mid = (l+r)/2;

            if(mid*k<=m && mid*k + ((n-mid*k)/k)*(k-1) + n%k >=m) {
                if(mid < mn)
                    mn = mid;
                r = mid-1;
            } else if(mid*k > m) r = mid-1;
            else l = mid+1;
        }
        if(mn==Integer.MAX_VALUE) mn = 0;

        long ans = ((((pow(2,mn+1)-2)%MOD*k)%MOD+m)%MOD-(mn*k)%MOD)%MOD;

        System.out.println(ans);
    }

    static long pow(long n,long p) {
        if(p==0) return 1;
        if(p%2!=0) return (pow(n,p-1)*n)%MOD;
        long res = pow(n,p/2);
        return (res*res)%MOD;
    }

}

import java.util.Scanner;
import java.io.OutputStream;
import java.io.IOException;
import java.io.PrintWriter;
import java.io.InputStream;

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

class TaskC {
    public long MOD = (long)1e9 + 9;

    public void solve(int testNumber, Scanner in, PrintWriter out) {
        long N = in.nextLong();
        long M = in.nextLong();
        long K = in.nextLong();

        long left = M - (N / K * (K - 1) + N % K);
        if (left <= 0) {
            out.println(M);
            return;
        }

        long single = M - left * K;
        long res = (powMod(2, left) * K % MOD + single) % MOD;
        out.println(res);
    }

    private long powMod(long a, long b) {
        if(b == 0) return 1;
        long res = powMod(a, b / 2);
        res = res * res % MOD;
        if (b % 2 == 1)
            res = res * a % MOD;
        return res;
    }
}

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

 public class Main {
     static long arr[], N, K,x1,x2,y1,y2;
     static boolean adj[][];
     static BigInteger dp[][];
     static boolean reach[][];
     static String str1[];
     static String str2[];
     static int mod =(int) (1e9 + 7);
     public static void main(String[] args) throws IOException {
       Scanner sc = new Scanner(System.in);
       long n = sc.nextLong();
       long m = sc.nextLong();
        long k = sc.nextLong();
        if(n - (n/k) >= m) {
            System.out.println(m);
        }

        long s =m-n+(n/k);
        long rem = n - s*k;
        long ans = rem - rem/k;
        ans += 2*s*k;
         System.out.println(ans% (long)(1e9+9));
     }

     static class Point
     {
         long x;
         long y;
         long dist;
         long r1;
         long r2;
         public Point(long x, long y)
         {
             this.dist =  (x - x1)*(x - x1) + (y - y1)* (y - y1) + (x - x2)*(x - x2) + (y - y2)* (y - y2);
             this.r1 = (x - x1)*(x - x1) + (y - y1)* (y - y1);
             this.r2 = (x - x2)*(x - x2) + (y - y2)* (y - y2);
             this.x = x;
             this.y = y;
         }
     };

     static class Scanner
     {
         StringTokenizer st;
         BufferedReader br;

         public Scanner(InputStream s){	br = new BufferedReader(new InputStreamReader(s));}
         public Scanner(String s) throws FileNotFoundException {
             br = new BufferedReader(new FileReader(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 String nextLine() throws IOException {return br.readLine();}

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

         public boolean ready() throws IOException {return br.ready();}
         public double nextDouble() throws IOException
		{
			String x = next();
			StringBuilder sb = new StringBuilder("0");
			double 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 = Integer.parseInt(sb.toString());
					sb = new StringBuilder("0");
					dec = true;
				}
				else
				{
					sb.append(x.charAt(i));
					if(dec)
						f *= 10;
				}
			res += Integer.parseInt(sb.toString()) / f;
			return res * (neg?-1:1);
		}
     }

 }

/**
 * DA-IICT
 * Author : PARTH PATEL
 */
import java.io.*;
import java.math.*;
import java.util.*;

import static java.util.Arrays.fill;
import static java.lang.Math.*;
import static java.util.Arrays.sort;
import static java.util.Collections.sort;

public class C337
{

	public static long mod = 1000000009;
	public static long INF = (1L << 60);
	static FastScanner2 in = new FastScanner2();
	static OutputWriter out = new OutputWriter(System.out);
	static int n,m,k;
	public static boolean func(int x)
	{
		//x consecutive true
		//n-x-1 remains and true has to be m-x
		int blocksize=(n-x)/k;
		if(blocksize<0)
			blocksize=0;
		int trueinother=blocksize*(k-1)+(n-x)%k;
		if(trueinother<0)
			trueinother=0;
		return (trueinother+x)>=m;
	}
	public static void main(String[] args)
	{

		n=in.nextInt();
		m=in.nextInt();
		k=in.nextInt();
		int l=1;
		int r=m;
		int answer=m;
		while(l<r)
		{
			int mid=(l+r)/2;
			if(func(mid))
			{
				answer=mid;
				r=mid;
			}
			else
			{
				l=mid+1;
			}
		}
		answer/=k;
		long ans=m+(pow(2, answer+1, mod)-(answer+2))*k;
		out.println((ans%mod+mod)%mod);
		out.close();

	}

	public static long pow(long x, long n)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p))
		{
			if ((n & 1) != 0)
			{
				res = (res * p);
			}
		}
		return res;
	}

	public static long pow(long x, long n, long mod)
	{
		long res = 1;
		for (long p = x; n > 0; n >>= 1, p = (p * p) % mod)
		{
			if ((n & 1) != 0)
			{
				res = (res * p % mod);
			}
		}
		return res;
	}

	public static long gcd(long n1, long n2)
	{
		long r;
		while (n2 != 0)
		{
			r = n1 % n2;
			n1 = n2;
			n2 = r;
		}
		return n1;
	}

	public static long lcm(long n1, long n2)
	{
		long answer = (n1 * n2) / (gcd(n1, n2));
		return answer;
	}

	static class FastScanner2
	{
		private byte[] buf = new byte[1024];
		private int curChar;
		private int snumChars;

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

		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 String nextString()
		{
			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 long nextLong()
		{
			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 int nextInt()
		{
			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 int[] nextIntArray(int n)
		{
			int[] arr = new int[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextInt();
			}
			return arr;
		}

		public long[] nextLongArray(int n)
		{
			long[] arr = new long[n];
			for (int i = 0; i < n; i++)
			{
				arr[i] = nextLong();
			}
			return arr;
		}

		private 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 InputReader
	{
		public BufferedReader reader;
		public StringTokenizer tokenizer;

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

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

		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[] nextIntArray(int n)
		{
			int a[] = new int[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextInt();
			}
			return a;
		}

		public long[] nextLongArray(int n)
		{
			long a[] = new long[n];
			for (int i = 0; i < n; i++)
			{
				a[i] = nextLong();
			}
			return a;
		}

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

	static class OutputWriter
	{
		private final PrintWriter writer;

		public OutputWriter(OutputStream outputStream)
		{
			writer = new PrintWriter(new BufferedWriter(new OutputStreamWriter(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 println(Object... objects)
		{
			print(objects);
			writer.println();
		}

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

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

}

import java.util.*;
import java.io.*;
import java.lang.*;
import java.math.*;
public class C {
    public static void main(String[] args) throws Exception {
        BufferedReader bf = new BufferedReader(new InputStreamReader(System.in));
        // PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
        // StringTokenizer st = new StringTokenizer(bf.readLine());
        // int n = Integer.parseInt(st.nextToken);
        // int n = Integer.parseInt(bf.readLine());
        Scanner scan = new Scanner(System.in);
        long n = scan.nextLong();
        long m = scan.nextLong();
        long k = scan.nextLong();
        long x = n-m;
        long noofones = n-k*(n-m);
        long intblocks = noofones/k;
        long remainder = noofones % k;
        long valones = (long)(pow(intblocks) - 1)*k;
        long totval = valones * 2 + remainder;
        long ans = totval + (k-1)*x;
        ans = ans % 1000000009;
        System.out.println(ans);
    }
    public static long pow(long n) {
        long ans = 1;
        n = n % 1000000008;
        long div = n/63;
        long rem = n % 63;
        for(int i=0; i<div; i++) {
            ans = ans * 844428231;
            ans = ans % 1000000009;
        }
        long mult = (long) (Math.pow(2, rem) % 1000000009);
        ans *= mult;
        return ans;
    }

}

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

public class cf196 {
	public static int max = 1000000009;

	public static void main(String[] args) throws IOException {
		BufferedReader in = new BufferedReader(new InputStreamReader(System.in));
		StringBuilder q = new StringBuilder();
		PrintWriter out = new PrintWriter(new OutputStreamWriter(System.out));
		String u[] = in.readLine().split(" ");
		int one = Integer.parseInt(u[0]);
		int two = Integer.parseInt(u[1]);
		int three = Integer.parseInt(u[2]);
		int ans1 = one - two;
		int ans2 = ans1 * 2;

		long count = 0;
		int rem = one - ans2;
		if (rem < 0)
			rem = 0;
		int ans4 = rem / three;
		count = (count % max + (two % max - rem % max) % max) % max;
		if (count < 0)
			count = 0;

		count = (count % max + (three % max * 2 % max * ans4 % max) % max)
				% max;
		count = (count % max + (rem % three) % max) % max;
		if(count<two)
			count=two;
		out.println(count);
		out.close();

	}

}