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

public class C {

  private static final String REGEX = " ";
  private static final Boolean DEBUG = false;
  private static final String FILE_NAME = "input.txt";

  public static void main(String[] args) throws IOException {
    if (DEBUG) {
      generate();
    }
    Solver solver = new Solver();
    solver.readData();
    solver.solveAndPrint();
  }

  private static void generate() throws IOException {
//    FileWriter writer = new FileWriter("input.txt");
//    writer.close();
  }

  private static class Solver {

    long n, s;

    void readData() throws IOException {
      InputStream in = DEBUG ? new FileInputStream(FILE_NAME) : System.in;
      Scanner scanner = new Scanner(in);
      n = scanner.nextLong();
      s = scanner.nextLong();
      scanner.close();
    }

    void solveAndPrint() {
      long cur = s + 1;
      long sum = getSum(cur);
      long res = 0;
      while (cur <= n) {
        if (cur - sum >= s) {
          System.out.println(n - cur + 1);
          return;
        }
        cur++;
        if (cur % 10 != 0) {
          sum++;
        } else {
          sum = getSum(cur);
        }
      }
      System.out.println(0);
    }

    long getSum(long cur) {
      long res = 0;
      while (cur > 0) {
        res += cur % 10;
        cur /= 10;
      }
      return res;
    }

    @SuppressWarnings("SameParameterValue")
    int[] splitInteger(String string, int n) {
      final String[] split = string.split(REGEX, n);
      int[] result = new int[split.length];
      for (int i = 0; i < n; ++i) {
        result[i] = Integer.parseInt(split[i]);
      }
      return result;
    }

    public int[] splitInteger(String string) {
      return splitInteger(string, 0);
    }

    @SuppressWarnings("SameParameterValue")
    long[] splitLong(String string, int n) {
      final String[] split = string.split(REGEX, n);
      long[] result = new long[split.length];
      for (int i = 0; i < n; ++i) {
        result[i] = Long.parseLong(split[i]);
      }
      return result;
    }

    public long[] splitLong(String string) {
      return splitLong(string, 0);
    }

    @SuppressWarnings("SameParameterValue")
    double[] splitDouble(String string, int n) {
      final String[] split = string.split(REGEX, n);
      double[] result = new double[split.length];
      for (int i = 0; i < n; ++i) {
        result[i] = Double.parseDouble(split[i]);
      }
      return result;
    }

    public double[] splitDouble(String string) {
      return splitDouble(string, 0);
    }

    @SuppressWarnings("SameParameterValue")
    String[] splitString(String string, int n) {
      return string.split(REGEX, n);
    }

    public String[] splitString(String string) {
      return splitString(string, 0);
    }

    public int max(int a, int b) {
      return Math.max(a, b);
    }

    public long max(long a, long b) {
      return Math.max(a, b);
    }

    public int min(int a, int b) {
      return Math.min(a, b);
    }

    public long min(long a, long b) {
      return Math.min(a, b);
    }

    public double max(double a, double b) {
      return Math.max(a, b);
    }

    public double min(double a, double b) {
      return Math.min(a, b);
    }

    private final static int MOD = 1000000009;

    int multMod(int a, int b) {
      return ((a % MOD) * (b % MOD)) % MOD;
    }

    int sumMod(int a, int b) {
      return ((a % MOD) + (b % MOD)) % MOD;
    }

    long multMod(long a, long b) {
      return ((a % MOD) * (b % MOD)) % MOD;
    }

    long sumMod(long a, long b) {
      return ((a % MOD) + (b % MOD)) % MOD;
    }
  }

}


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.math.BigInteger;
import java.util.Scanner;

public class C {
	public static void main(String[] args) {
		Scanner sc=new Scanner(System.in);
		long s=0,mod=1000000009;
		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;
			//System.out.println(a);
			long pot=BigInteger.valueOf(2).modPow(BigInteger.valueOf(a), BigInteger.valueOf(mod)).longValue();
			pot=(2*(pot-1))%mod;
			/*System.out.println(pot);
			System.out.println(k);*/
			System.out.println(((pot*k)%mod+(m-a*k))%mod);
		}
	}
}


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

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

class TaskC {

	static final long mod=1000000009;

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

		int l=0,r=m/k;
		while(l<r) {
			int mid=(l+r)>>>1;
			if(good(n,m,k,mid)){
				r=mid;
			}
			else{
				l=mid+1;
			}
		}
		Mat u=new Mat();
		u.set(k,1,0,0);
		Mat v=new Mat();
		v.set(2,0,k,1);
		u=u.mul(v.powMat(l));
		out.println((u.e[0][0]-k+(m-l*k)+mod)%mod);
	}

	private boolean good(int n, int m, int k, int mid) {
		n-=mid*k;
		m-=mid*k;
		int ans=n/k*(k-1)+n%k;
		if(ans>=m)
			return true;
		return false;
	}

	private static class Mat {
		long[][] e=new long[2][2];

		Mat mul(Mat u) {
			Mat s=new Mat();
			s.set(0,0,0,0);
			for(int i=0;i<2;i++) {
				for(int j=0;j<2;j++) {
					for(int k=0;k<2;k++){
						s.e[i][j]=(s.e[i][j]+e[i][k]*u.e[k][j])%mod;
					}
				}
			}
			return s;
		}

		Mat powMat(int k) {
			Mat u=this;
			Mat s=new Mat();
			s.set(1,0,0,1);
			while(k!=0) {
				if(k%2==1) {
					s=s.mul(u);
				}
				u=u.mul(u);
				k/=2;
			}
			return s;
		}

		void set(long i, long j, long k, long l) {
			e[0][0]=i;
			e[0][1]=j;
			e[1][0]=k;
			e[1][1]=l;
		}
	}

}

class InputReader {
    public BufferedReader reader;
    public StringTokenizer tokenizer;

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

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

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

}


import java.io.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.util.Scanner;

/**
 * @author pvasilyev
 * @since 8/16/13
 */
public class ProblemC {

    public static final String FILE_IN = "std.in";
    public static final String FILE_OUT = "std.out";
    private static boolean debugMode = true;
    private static final long MOD = 1000 * 1000 * 1000 + 9;

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

        final Scanner reader = new Scanner(new InputStreamReader(debugMode ? System.in : new FileInputStream(FILE_IN)));
        final PrintWriter writer = new PrintWriter(debugMode ? System.out : new FileOutputStream(FILE_OUT));

//        final long start = System.currentTimeMillis();
        solveTheProblem(reader, writer);
//        System.out.println(System.currentTimeMillis() - start);

        reader.close();
        writer.close();
    }

    private static void solveTheProblem(final Scanner reader, final PrintWriter writer) {

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

        if (n - n/k >= m) {
            writer.println(m);
            return;
        } else {
            long sum = 1;
            long maxK = m - n + n/k;
            sum = fastPow(2, maxK);
            sum = 2 * (sum - 1);
            sum = sum % MOD;
            sum *= k;
            sum += m - maxK * k;
            writer.println(sum % MOD);
        }

    }

    private static long fastPow(final int exp, final long deg) {
        if (deg == 0) {
            return 1;
        } else if (deg == 1) {
            return exp;
        } else if (deg % 2 == 0) {
            long temp = fastPow(exp, deg / 2);
            temp = (temp * temp) % MOD;
            return temp;
        } else {
            long temp = fastPow(exp, deg / 2);
            temp = (temp * temp) % MOD;
            return (temp * exp) % MOD;
        }
    }

}


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

    boolean ok(long n, long m, long x) {
        long u = k * x;
        long val = u;
        val += (m - u) / (k - 1) * k;

        if((m - u) % (k - 1) == 0) val -= 1;
        else val += (m - u) % (k - 1);

        return val <= n;
    }

    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(ok(n, m, 0)) { return (m + cur) % mod; }
            if(!ok(n - p * k, m - p * k, p)) {
                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;

            if(!ok(n, m, mid)) {
                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.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.*;

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

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

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

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

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

		out.println( ans );
	}

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

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

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

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

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

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

}


import java.io.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.*;
import java.math.*;

public class A implements Runnable {
	static BufferedReader in;
	static PrintWriter out;
	static StringTokenizer st;
	static Random rnd;

	final long MODULO = 1000000009;

	private void solve() throws IOException {
		int moves = nextInt(), rightMoves = nextInt(), sequence = nextInt();
		long answer = solveSmart(moves, rightMoves, sequence);
		out.println(answer);
		// for (int moves = 2; moves <= 50; moves++) {
		// for (int rightMoves = 2; rightMoves <= moves; rightMoves++) {
		// for (int sequence = 2; sequence <= moves; sequence++) {
		// if (solveDumb(moves, rightMoves, sequence) != solveSmart(
		// moves, rightMoves, sequence)) {
		// out.println(moves + " " + rightMoves + " " + sequence);
		// out.flush();
		// }
		// }
		// }
		// }
	}

	// private long solveDumb(int moves, int rightMoves, int sequence) {
	// long[][][] d = new long[moves + 1][rightMoves + 1][sequence];
	// long inf = Integer.MAX_VALUE;
	// for (int i = 0; i <= moves; i++)
	// for (int j = 0; j <= rightMoves; j++)
	// Arrays.fill(d[i][j], inf);
	// d[0][0][0] = 0;
	//
	// for (int i = 0; i < moves; i++) {
	// for (int j = 0; j <= rightMoves; j++) {
	// for (int k = 0; k < sequence; k++) {
	// // right move
	// if (j < rightMoves) {
	// // last move
	// if (k + 1 == sequence) {
	// d[i + 1][j + 1][0] = Math.min(d[i + 1][j + 1][0],
	// (d[i][j][k] + 1) * 2);
	// } else {
	// d[i + 1][j + 1][k + 1] = Math.min(
	// d[i + 1][j + 1][k + 1], d[i][j][k] + 1);
	// }
	// }
	//
	// // bad move
	// d[i + 1][j][0] = Math.min(d[i + 1][j][0], d[i][j][k]);
	// }
	//
	// }
	// }
	//
	// long result = inf;
	// for (int i = 0; i < sequence; i++)
	// result = Math.min(result, d[moves][rightMoves][i]);
	// return result;
	// }

	private long solveSmart(long moves, long rightMoves, long sequence) {
		long fullSequences = moves / sequence;
		long canReset = Math.min(fullSequences, moves - rightMoves);
		long remainSequences = fullSequences - canReset;
		long answer = (rightMoves - remainSequences * sequence)
				+ getAnswerSequences(remainSequences, sequence);
		answer %= MODULO;
		return answer;
	}

	private long getAnswerSequences(long count, long length) {
		long first = (getPow(2, count + 1) - 2) % MODULO;
		long result = first * length;
		result %= MODULO;
		result += MODULO;
		result %= MODULO;
		return result;
	}

	private int getPow(int n, long p) {
		return BigInteger.valueOf(2)
				.modPow(BigInteger.valueOf(p), BigInteger.valueOf(MODULO))
				.intValue();
	}

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

	public void run() {
		try {
			in = new BufferedReader(new InputStreamReader(System.in));
			out = new PrintWriter(System.out);

			rnd = new Random();

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
			System.exit(1);
		}
	}

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

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

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

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


import java.util.*;
import java.io.*;
public class Quiz
{
	public static final int MOD = 1000000009;

	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 low = Math.min(n - (k * (n - m)), m);

		if(low < 0)
		{
			low = 0;
		}

		long result = 0;
		if(low >= k)
		{
			long b = low / k;

			result += fastExp(2, b + 1);
			result -= 2;
			if(result < 0)
			{
				result += MOD;
			}

			result *= k;
			result %= MOD;
		}

		result += low % k;
		result %= MOD;

		result += m - low;
		result %= MOD;

//		System.out.println(low);

		System.out.println(result);
	}

	public static long fastExp(int x, long pow)
	{
		if(pow == 0)
		{
			return 1;
		}

		long result = fastExp(x, pow / 2);
		result *= result;
		result %= MOD;

		if(pow % 2 == 1)
		{
			result *= x;
			result %= MOD;
		}

		return result;
	}
}


import java.io.OutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.io.IOException;
import java.io.UncheckedIOException;
import java.io.Closeable;
import java.io.Writer;
import java.io.OutputStreamWriter;
import java.io.InputStream;

/**
 * Built using CHelper plug-in
 * Actual solution is at the top
 */
public class Main {
    public static void main(String[] args) throws Exception {
        Thread thread = new Thread(null, new TaskAdapter(), "", 1 << 29);
        thread.start();
        thread.join();
    }

    static class TaskAdapter implements Runnable {
        @Override
        public void run() {
            InputStream inputStream = System.in;
            OutputStream outputStream = System.out;
            FastInput in = new FastInput(inputStream);
            FastOutput out = new FastOutput(outputStream);
            AQuiz solver = new AQuiz();
            solver.solve(1, in, out);
            out.close();
        }
    }

    static class AQuiz {
        int mod = (int) 1e9 + 9;
        Power pow = new Power(mod);

        public void solve(int testNumber, FastInput in, FastOutput out) {
            int n = in.ri();
            int m = in.ri();
            int k = in.ri();
            long mayPut = (long) (n - m) * (k - 1);
            if (mayPut >= m) {
                out.println(m);
                return;
            }

            long ans = dup(m - mayPut, k);
            ans += mayPut;
            ans %= mod;
            out.println(ans);
        }

        public long dup(long n, long k) {
            long r = n % k;
            n -= r;
            long m = n / k;
            long ans = k * (pow.pow(2, m + 1) - 2);
            ans += r;
            ans = DigitUtils.mod(ans, mod);
            return ans;
        }

    }

    static class FastOutput implements AutoCloseable, Closeable, Appendable {
        private static final int THRESHOLD = 32 << 10;
        private final Writer os;
        private StringBuilder cache = new StringBuilder(THRESHOLD * 2);

        public FastOutput append(CharSequence csq) {
            cache.append(csq);
            return this;
        }

        public FastOutput append(CharSequence csq, int start, int end) {
            cache.append(csq, start, end);
            return this;
        }

        private void afterWrite() {
            if (cache.length() < THRESHOLD) {
                return;
            }
            flush();
        }

        public FastOutput(Writer os) {
            this.os = os;
        }

        public FastOutput(OutputStream os) {
            this(new OutputStreamWriter(os));
        }

        public FastOutput append(char c) {
            cache.append(c);
            afterWrite();
            return this;
        }

        public FastOutput append(int c) {
            cache.append(c);
            afterWrite();
            return this;
        }

        public FastOutput append(long c) {
            cache.append(c);
            afterWrite();
            return this;
        }

        public FastOutput println(int c) {
            return append(c).println();
        }

        public FastOutput println(long c) {
            return append(c).println();
        }

        public FastOutput println() {
            return append('\n');
        }

        public FastOutput flush() {
            try {
//            boolean success = false;
//            if (stringBuilderValueField != null) {
//                try {
//                    char[] value = (char[]) stringBuilderValueField.get(cache);
//                    os.write(value, 0, cache.length());
//                    success = true;
//                } catch (Exception e) {
//                }
//            }
//            if (!success) {
                os.append(cache);
//            }
                os.flush();
                cache.setLength(0);
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
            return this;
        }

        public void close() {
            flush();
            try {
                os.close();
            } catch (IOException e) {
                throw new UncheckedIOException(e);
            }
        }

        public String toString() {
            return cache.toString();
        }

    }

    static class FastInput {
        private final InputStream is;
        private byte[] buf = new byte[1 << 13];
        private int bufLen;
        private int bufOffset;
        private int next;

        public FastInput(InputStream is) {
            this.is = is;
        }

        private int read() {
            while (bufLen == bufOffset) {
                bufOffset = 0;
                try {
                    bufLen = is.read(buf);
                } catch (IOException e) {
                    bufLen = -1;
                }
                if (bufLen == -1) {
                    return -1;
                }
            }
            return buf[bufOffset++];
        }

        public void skipBlank() {
            while (next >= 0 && next <= 32) {
                next = read();
            }
        }

        public int ri() {
            return readInt();
        }

        public int readInt() {
            int sign = 1;

            skipBlank();
            if (next == '+' || next == '-') {
                sign = next == '+' ? 1 : -1;
                next = read();
            }

            int val = 0;
            if (sign == 1) {
                while (next >= '0' && next <= '9') {
                    val = val * 10 + next - '0';
                    next = read();
                }
            } else {
                while (next >= '0' && next <= '9') {
                    val = val * 10 - next + '0';
                    next = read();
                }
            }

            return val;
        }

    }

    static interface InverseNumber {
    }

    static class DigitUtils {
        private DigitUtils() {
        }

        public static int mod(long x, int mod) {
            if (x < -mod || x >= mod) {
                x %= mod;
            }
            if (x < 0) {
                x += mod;
            }
            return (int) x;
        }

    }

    static class Power implements InverseNumber {
        int mod;

        public Power(int mod) {
            this.mod = mod;
        }

        public int pow(int x, long n) {
            if (n == 0) {
                return 1 % mod;
            }
            long r = pow(x, n >> 1);
            r = r * r % mod;
            if ((n & 1) == 1) {
                r = r * x % mod;
            }
            return (int) r;
        }

    }
}


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

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

class TaskA {
    public static long MOD = 1000000009L;

    public long pow(long n, long p) {
        if (p == 0)
            return 1L;
        if (p == 1)
            return n;
        long ret = 1L;
        if (p % 2L != 0)
            ret = n;
        long tmp = pow(n, p / 2L);
        ret = (ret * tmp) % MOD;
        ret = (ret * tmp) % MOD;
        return ret;
    }

    public long func(long n, long k) {
        long times = n / k;
        long ret = n - times * k;
        ret += ((pow(2L, times + 1L) + MOD - 2L) % MOD) * k % MOD;
        return ret;
    }

    public void solve(int testNumber, InputReader in, OutputWriter out) {
        long n = in.readLong();
        long m = in.readLong();
        long k = in.readLong();
        long wrong = n - m;
        long wow = n / k;
        long ans;
        if (wrong >= wow)
            ans = m;
        else
            ans = (func(n - wrong * k, k) + (k - 1L) * wrong % MOD) % MOD;

        out.printLine(ans);
    }
}

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

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

    }

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.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.*;
import java.math.BigInteger;
import java.util.*;

public class Main {

    public static void main(String[] args) throws Exception {
        InputReader in = new InputReader(System.in);
        int n = in.readInt();
        int m = in.readInt();
        int k = in.readInt();
        long wrong = n - m;
        long c = wrong * (k) + k - 1;
        long xk = n - c;
        if (xk <= 0)
            System.out.println((n - wrong) % 1000000009);
        else {
            long x = (long) Math.ceil(xk / (k * 1.0));
            long power = Long.parseLong((BigInteger.valueOf(2).modPow(
                    BigInteger.valueOf(x + 1), BigInteger.valueOf(1000000009))
                    .subtract(BigInteger.valueOf(2))) + "");
            power += 1000000009;
            power %= 1000000009;
            long first = (power * k) % 1000000009;
            // System.out.println(first);
            first += (n - x * k - wrong);
            System.out.println(first % 1000000009);
        }
    }

    static class InputReader {
        private InputStream stream;
        private byte[] buf = new byte[1000];
        private int curChar, numChars;

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

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

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

        private String readLine0() {
            StringBuffer buf = new StringBuffer();
            int c = read();
            while (c != '\n' && c != -1) {
                buf.appendCodePoint(c);
                c = read();
            }
            return buf.toString();
        }

        public String readLine() {
            String s = readLine0();
            while (s.trim().length() == 0)
                s = readLine0();
            return s;
        }

        public String readLine(boolean ignoreEmptyLines) {
            if (ignoreEmptyLines)
                return readLine();
            else
                return readLine0();
        }

        public char readCharacter() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            return (char) c;
        }

        public double readDouble() {
            int c = read();
            while (isSpaceChar(c))
                c = read();
            int sgn = 1;
            if (c == '-') {
                sgn = -1;
                c = read();
            }
            double res = 0;
            while (!isSpaceChar(c) && c != '.') {
                if (c == 'e' || c == 'E')
                    return res * Math.pow(10, readInt());
                if (c < '0' || c > '9')
                    throw new InputMismatchException();
                res *= 10;
                res += c - '0';
                c = read();
            }
            if (c == '.') {
                c = read();
                double m = 1;
                while (!isSpaceChar(c)) {
                    if (c == 'e' || c == 'E')
                        return res * Math.pow(10, readInt());
                    if (c < '0' || c > '9')
                        throw new InputMismatchException();
                    m /= 10;
                    res += (c - '0') * m;
                    c = read();
                }
            }
            return res * sgn;
        }
    }
}


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; }
            long val = u;
            val += (m - u) / (k - 1) * k;
            if((m - u) % (k - 1) == 0) val -= 1;
            else val += (m - u) % (k - 1);

            if(val > 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());
        }

    }

}


//package cf196;

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

public class A {
	FastScanner in;
	PrintWriter out;
	final long mod = (long) 1e9 + 9 ;
	public void solve() throws IOException {
		long n = in.nextInt();
		long m = in.nextInt();
		long k = in.nextInt();
		long l = n / k;
		long c = n - m;
		long mul2 = Math.max(0, l - c);
		if (mul2 == 0) {
			out.println(m);
			return;
		}
		long ans = power(2, mul2 + 1, mod);
		ans = (ans + mod - 2) % mod;
		ans = (ans * k) % mod;
		long z = mul2 * k;
		long r = m - z;
		ans = (ans + r) % mod;
		out.print(ans);
	}
	public long power(long x, long pow, long mod) {
		if (pow == 0) {
			return 1;
		}
		if ((pow % 2) == 0) {
			return power(((x * x) % mod), pow / 2, mod);
		} else {
			return (power(x, pow - 1, mod) * x) % mod;
		}
	}
	public void run() {
		try {
			in = new FastScanner(System.in);
			out = new PrintWriter(System.out);

			solve();

			out.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
	}

	class FastScanner {
		BufferedReader br;
		StringTokenizer st;

		FastScanner(File f) {
			try {
				br = new BufferedReader(new FileReader(f));
			} catch (FileNotFoundException e) {
				e.printStackTrace();
			}
		}

		public FastScanner(InputStream in) {
			br = new BufferedReader(new InputStreamReader(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());
		}
	}

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


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

    }
}


// practice with rainboy
import java.io.*;
import java.util.*;

public class CF338A extends PrintWriter {
	CF338A() { super(System.out, true); }
	Scanner sc = new Scanner(System.in);
	public static void main(String[] $) {
		CF338A o = new CF338A(); o.main(); o.flush();
	}

	static final int MD = 1000000009;
	long power(int a, int k) {
		if (k == 0)
			return 1;
		long p = power(a, k / 2);
		p = p * p % MD;
		if (k % 2 == 1)
			p = p * a % MD;
		return p;
	}
	void main() {
		int n = sc.nextInt();
		int m = sc.nextInt();
		int k = sc.nextInt();
		int z = n - m;
		if (z >= (n + k - 1) / k) {
			println(m);
			return;
		}
		int d = (n - z * k) / k;
		println(((power(2, d + 1) - 2 + MD) * k + m - d * k) % MD);
	}
}


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.FileReader;
import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.math.BigInteger;
import java.util.StringTokenizer;

public class Quiz {
    public static long pow(long base, long power) {
        if (power == 0)
            return 1;
        long half = pow(base, power / 2) % mod;
        half *= half;
        half %= mod;
        if (power % 2 == 1)
            half *= base;
        return half % mod;
    }

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

    public static void main(String[] args) {
        InputReader r = new InputReader(System.in);
        int n = r.nextInt();
        int m = r.nextInt();
        int k = r.nextInt();
        int buckets = n / k;
        int rem = n - buckets * k;
        long low = 0, high = buckets, itr = 30;
        while (itr-- > 0) {
            long mid = (low + high) / 2;
            long correct = mid * k + rem + (buckets - mid) * (k - 1);
            if (correct < m)
                low = mid;
            else
                high = mid;
        }
        long pow = (pow(2, high + 1) - 2 + mod) % mod;
        pow *= k;
        pow %= mod;
        long res = m - (high * k) + pow + 10 * mod;
        res %= mod;
        System.out.println(res);
    }

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

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

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

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

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

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

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


import java.util.*;
import java.io.*;
public class a {
    static long mod = 1000000009;
    static ArrayList<Integer>[] g;
public static void main(String[] args) throws IOException
{
    //Scanner input = new Scanner(new File("input.txt"));
    //PrintWriter out = new PrintWriter(new File("output.txt"));
  input.init(System.in);
  PrintWriter out  = new PrintWriter((System.out));

  int n = input.nextInt(), m = input.nextInt(), k = input.nextInt();
  long border = n-n/k;
  if(m<=border) out.println(m);
  else
  {
      long count = m- border;
      long first = ((pow(2, count+1) + mod - 2)*k)%mod;
      first += m - k*count;
      out.println(first%mod);
  }

  out.close();
}
static long pow(long x, long p)
{
    if(p==0) return 1;
    if((p&1) > 0)
    {
        return (x*pow(x, p-1))%mod;
    }
    long sqrt = pow(x, p/2);
    return (sqrt*sqrt)%mod;
}
static long gcd(long a, long b)
{
    if(b==0) return a;
    return gcd(b, a%b);
}
static class input {
  static BufferedReader reader;
  static StringTokenizer tokenizer;

  /** call this method to initialize reader for InputStream */
  static void init(InputStream input) {
      reader = new BufferedReader(
                   new InputStreamReader(input) );
      tokenizer = new StringTokenizer("");
  }

  /** get next word */
  static String next() throws IOException {
      while ( ! tokenizer.hasMoreTokens() ) {
          //TODO add check for eof if necessary
          tokenizer = new StringTokenizer(
                 reader.readLine() );
      }
      return tokenizer.nextToken();
  }

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

  static double nextDouble() throws IOException {
      return Double.parseDouble( next() );
  }
  static long nextLong() throws IOException {
      return Long.parseLong( next() );
  }
  static String nextLine() throws IOException {
    return reader.readLine();
  }
}
}


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();

        long l = -1;
        long r = n + 1;

        while (l + 1 < r) {
            long c = (l + r) / 2;
            if(n < c * k || canAchieve(n - c * k, k) >= m - c * k) {
                r = c;
            }
            else
                l = c;
        }

        //out.println(r);

        long 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 long canAchieve(long n, long 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.io.BufferedReader;
import java.io.FileReader;
import java.io.InputStreamReader;
import java.io.PrintWriter;
import java.util.StringTokenizer;

/**
 * Date: 23.06.13 at 15:29
 *
 * @author Nickolay Polyarniy aka PolarNick
 */
public class ProblemA {

    private static long MOD = 1000000009;

    public void solve() throws Exception {
        long n = nextInt();
        long m = nextInt();
        long k = nextInt();
        long tmp = 1024 * 1024;
        long res = 0;

        long nTmp = n;
        long mTmp = m;
        while (tmp > 0) {
            while (mTmp >= (k - 1) * tmp && nTmp - k * tmp >= mTmp - (k - 1) * tmp) {
                nTmp -= k * tmp;
                mTmp -= (k - 1) * tmp;
//                res = (res + (k - 1) * tmp) % MOD;
            }
            tmp /= 2;
        }
        long fullC = mTmp / k;
//        out.println("mTmp=" + mTmp + "Full: " + fullC);

        long pow2 = getPow(2, fullC + 1, MOD);
        res = (((res + pow2 + MOD - 2) % MOD) * k) % MOD;

//        out.println("After full: " + res);

        mTmp = mTmp % k;
        res = (res + mTmp) % MOD;

        nTmp = n;
        mTmp = m - fullC * k - mTmp;
        tmp = 1024 * 1024;
        while (tmp > 0) {
            while (mTmp >= (k - 1) * tmp && nTmp - k * tmp >= mTmp - (k - 1) * tmp) {
                nTmp -= k * tmp;
                mTmp -= (k - 1) * tmp;
                res = (res + (k - 1) * tmp) % MOD;
            }
            tmp /= 2;
        }
        out.println(res);
    }

    static long[] pows = new long[1000000];

    public static long getPow(long base, long pow, long mod) {
        if (pow < pows.length && pows[(int) pow] != 0) {
            return pows[(int) pow];
        }
        if (pow == 0) {
            pows[0] = 1;
            return 1;
        }
        if (pow == 1) {
            pows[1] = base;
            return base;
        }
        long res = getPow(base, pow / 2, mod);
        res = (res * res) % mod;
        res = (res * getPow(base, pow % 2, mod)) % mod;
        if (pow < pows.length) {
            pows[(int) pow] = res;
        }
        return res;
    }

    public static void main(String[] args) throws Exception {
        ProblemA problem = new ProblemA();
        problem.solve();
        problem.close();
    }

    BufferedReader in;
    PrintWriter out;
    String curLine;
    StringTokenizer tok;
    final String delimeter = " ";
    final String endOfFile = "";

    public ProblemA(BufferedReader in, PrintWriter out) throws Exception {
        this.in = in;
        this.out = out;
        curLine = in.readLine();
        if (curLine == null || curLine == endOfFile) {
            tok = null;
        } else {
            tok = new StringTokenizer(curLine, delimeter);
        }
    }

    public ProblemA() throws Exception {
        this(new BufferedReader(new InputStreamReader(System.in)),
                new PrintWriter(System.out));
    }

    public ProblemA(String filename) throws Exception {
        this(new BufferedReader(new FileReader(filename + ".in")),
                new PrintWriter(filename + ".out"));
    }

    public boolean hasMore() throws Exception {
        if (tok == null || curLine == null) {
            return false;
        } else {
            while (!tok.hasMoreTokens()) {
                curLine = in.readLine();
                if (curLine == null || curLine.equalsIgnoreCase(endOfFile)) {
                    tok = null;
                    return false;
                } else {
                    tok = new StringTokenizer(curLine);
                }
            }
            return true;
        }
    }

    public String nextWord() throws Exception {
        if (!hasMore()) {
            return null;
        } else {
            return tok.nextToken();
        }
    }

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

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

    public int[] readIntArray(int n) throws Exception {
        int[] res = new int[n];
        for (int i = 0; i < n; i++) {
            res[i] = nextInt();
        }
        return res;
    }

    public void close() throws Exception {
        in.close();
        out.close();
    }

}


import java.io.*;
import java.util.Arrays;
import java.util.Scanner;
import java.util.StringTokenizer;
import java.util.TreeMap;

public class A
{
	private static final long MOD = 1000000009L;
	public static void main(String [] args) throws IOException
	{
		Scanner in = new Scanner(System.in);
	    long n = in.nextInt();
		long m = in.nextInt();
		long k = in.nextInt();

		long w = n-m;

		long c = w*k;
		if(c >= n)
		{
			System.out.println(m);
			return;
		}

		long rem = n-c;
		long h = rem/k;

		long p = power(2, h+1);
		p -= 2;
		p += MOD;
		p %= MOD;
		p *= k;
		p %= MOD;

		long point = p + m - (h*k) % MOD;
		point += MOD;
		point %= MOD;

		System.out.println(point);

	}

	private static long power(int num, long power)
	{
		if(power == 0)
			return 1;
		long res = power(num, power/2);
		res = (res*res)%MOD;
		if(power % 2 != 0)
			res *= num;

		res%=MOD;

		return res;
	}
}


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.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.*;
import java.util.*;

public class A {

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

	void solve() throws IOException {
		int tot = nextInt();
		int ok = nextInt();

		int k = nextInt();

		int maxBad = tot / k;
		if (tot - maxBad >= ok) {
			out.println(ok);
			return;
		}

		int	dbl = ok + tot / k - tot;

		int dblPoints = pow(2, dbl + 1) - 2;
		while (dblPoints < 0)
			dblPoints += MOD;

		dblPoints = (int)((long)dblPoints * k % MOD);

		int rest = ok - dbl * k;

		int ans = dblPoints + rest;

		if (ans >= MOD)
			ans -= MOD;

		out.println(ans);
	}

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

	static final int MOD = 1000000009;

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

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

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

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

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

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

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


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

public class A {
	long mod = (long)(1e+9+9);
	long pow(long a,long b) {
		long mul = a;
		long res = 1;
		while (b > 0) {
			if (b %2 == 1) {
				res = (res*mul)%mod;
			}
			mul = (mul*mul)%mod;
			b/=2;
		}
		return res;
	}

	void solve() throws IOException {
		long n = nextLong();
		long m = nextLong();
		long k = nextLong();
		long l = -1;
		long r = m / k;
		while (l < r - 1) {
			long mid = (l+r)/2;
			long leftOk = m - mid*k;
			long leftPos = n - mid*k;
			long cgroups = (leftOk + (k-2)) / (k-1);
			long positions = leftOk+cgroups-1;
			if (positions <= leftPos) {
				r = mid;
			} else {
				l = mid;
			}
		}
		long res = pow(2,r+1);
		res = (res - 2 + mod) %mod;
		res = (res*k) % mod;
		res = (res+m-r*k) %mod;
		out.println(res);

	}

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

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

	BufferedReader in;
	PrintWriter out;
	StringTokenizer st;

	String next() throws IOException {
		while (st == null || !st.hasMoreTokens()) {
			String temp = in.readLine();
			if (temp == null) {
				return null;
			}
			st = new StringTokenizer(temp);
		}
		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());
	}

}


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

public class ProblemA {
    InputReader in; PrintWriter out;

    long power(long a, long b, long mod) {
        long ret = 1;
        long mul = a;
        while (b > 0) {
            if (b % 2 == 1) {
                ret = (ret * mul % mod);
            }
            mul = (mul * mul) % mod;
            b = b / 2;
        }
        return ret;
    }

    void solve() {
        long n = in.nextLong();
        long m = in.nextLong();
        long k = in.nextLong();
        long mod = 1000000009;
        long x = m - (n - n / k);
        if (x <= 0) {
            out.println(m);
        }
        else {
            long score = 1;
            score = power(2, x + 1, mod);
            score = (score + mod - 2) % mod;
//          out.println(score);
            long ans = ((score * k) + m - x * k + mod) % mod;
            out.println(ans);
        }
    }

    ProblemA(){
        boolean oj = System.getProperty("ONLINE_JUDGE") != null;
        try {
            if (oj) {
                in = new InputReader(System.in);
                out = new PrintWriter(System.out);
            }
            else {
                Writer w = new FileWriter("output.txt");
                in = new InputReader(new FileReader("input.txt"));
                out = new PrintWriter(w);
            }
        } catch(Exception e) {
            throw new RuntimeException(e);
        }
        solve();
        out.close();
    }
    public static void main(String[] args){
        new ProblemA();
    }
}

class InputReader {
    private BufferedReader reader;
    private StringTokenizer tokenizer;

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

    public InputReader(FileReader fr) {
        reader = new BufferedReader(fr);
        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 double nextDouble() {
        return Double.parseDouble(next());
    }

}


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.awt.Rectangle;
import java.awt.geom.Rectangle2D;
import java.io.*;
import java.math.BigInteger;
import java.util.*;

public class C
{
	String line;
	StringTokenizer inputParser;
	BufferedReader is;
	FileInputStream fstream;
	DataInputStream in;
	String FInput="";

	void openInput(String file)
	{

		if(file==null)is = new BufferedReader(new InputStreamReader(System.in));//stdin
		else
		{
			try{

			fstream = new FileInputStream(file);
			in = new DataInputStream(fstream);
			is = new BufferedReader(new InputStreamReader(in));
			}catch(Exception e)
			{
				System.err.println(e);
			}
		}

	}

	void readNextLine()
	{
		try {
			line = is.readLine();
			inputParser = new StringTokenizer(line, " ");
			//System.err.println("Input: " + line);
		} catch (IOException e) {
			System.err.println("Unexpected IO ERROR: " + e);
		}

	}

	int NextInt()
	{
		String n = inputParser.nextToken();
		int val = Integer.parseInt(n);

		//System.out.println("I read this number: " + val);
		return val;
	}

	String NextString()
	{
		String n = inputParser.nextToken();
		return n;
	}

	void closeInput()
	{
		try {
			is.close();
		} catch (IOException e) {
			System.err.println("Unexpected IO ERROR: " + e);
		}

	}

	public void readFInput()
	{
		for(;;)
		{
			try
			{
				readNextLine();
				FInput+=line+" ";
			}
			catch(Exception e)
			{
				break;
			}
		}
		inputParser = new StringTokenizer(FInput, " ");
	}

	long NextLong()
    {
            String n = inputParser.nextToken();

            long val = Long.parseLong(n);

            return val;
    }

	public static void main(String [] argv)
	{
		//String filePath="input.txt";
        String filePath=null;
        if(argv.length>0)filePath=argv[0];
		new C(filePath);
	}
	final int MOD = 1000000009;
	public C(String inputFile)
	{
		openInput(inputFile);
		StringBuilder sb = new StringBuilder();
		readNextLine();
    	int N=NextInt(), M=NextInt(), K=NextInt();

    	if((N/K)<=(N-M))
    	{
    		sb.append(M);
    	}
    	else
    	{
    		int x=(N/K)-(N-M);
    		long ret=(pow(2, x) -1 );

    		ret *=K;
    		ret%=MOD;
    		ret *= 2;
    		ret%=MOD;
    		/*
    		ret+=pow(K, x+1);
    		ret%=MOD;*/
    		ret+=(M-x*K);
    		ret%=MOD;
    		sb.append(ret+"\n");

    	}

    	System.out.println(sb);
		closeInput();
	}

	long pow(long b, long exponent)
	{
	    long ret = 1;
	    while(exponent > 0)
	    {
	        if (exponent%2 == 1)
	           ret = (ret * b) % MOD;
	        exponent = exponent >> 1;
	        b = (b * b) % MOD;
	    }
	    return ret;
	}

}


import java.io.IOException;
import java.io.OutputStreamWriter;
import java.math.BigDecimal;
import java.io.BufferedWriter;
import java.util.InputMismatchException;
import java.io.OutputStream;
import java.math.MathContext;
import java.io.PrintWriter;
import java.io.Writer;
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);
        OutputWriter out = new OutputWriter(outputStream);
        TaskA solver = new TaskA();
        solver.solve(1, in, out);
        out.close();
    }
}

class TaskA {

    public static final long mod = 1000L * 1000L * 1000L + 9L;

    public void solve(int testNumber, InputReader in, OutputWriter out) {
        long n = in.nextLong();
        long m = in.nextLong();
        long k = in.nextLong();
        long z = n - m;
        long left = m - z * (k - 1L);
        if (left < 0) left = 0;
        long res = IntegerUtlis.pow(2L, left / k, mod) - 1L;
        res *= 2L * k;
        res %= mod;
        res += left % k;
        res %= mod;
        res += m - left;
        res %= mod;
        res += mod;
        res %= mod;
        out.printLine(res);
    }
}

class InputReader {
    private InputStream stream;
    private byte[] buffer = new byte[10000];
    private int cur;
    private int count;

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

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

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

    public int readSkipSpace() {
        int c;
        do {
            c = read();
        } while (isSpace(c));
        return c;
    }

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

    }

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

    }

class IntegerUtlis {

    public static long pow(long x, long y, long mod) {
        x %= mod;
        long res = 1;
        while (y > 0) {
            if (y % 2 == 1) {
                --y;
                res = BigInteger.valueOf(res).multiply(BigInteger.valueOf(x)).mod(BigInteger.valueOf(mod)).longValue();
            } else {
                y /= 2;
                x = BigInteger.valueOf(x).multiply(BigInteger.valueOf(x)).mod(BigInteger.valueOf(mod)).longValue();
            }
        }
        return res % mod;
    }

    }


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


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

}