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;
        ans%=MOD;
        long add=(K*((pow(2,(int)(1+a/K))-2+MOD)%MOD)%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.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.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.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.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.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.*;
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());
	}

}

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

}

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.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.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.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.*;
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.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.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.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();
    }
}

//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.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.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;
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);
    }
}

//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.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 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.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.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.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.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.*;
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.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.*;
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.*;

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

/* 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.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.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.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;
        }
    }
}

/**
 * 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.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);
        }
    }
}

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.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 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.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.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.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.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);
    }
}

//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.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.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.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.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.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.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);
		}
	}
}

/*
[ ( ^ _ ^ ) ]
*/
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.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();

	}

}