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


public class Main {
	public static void main(String[] args) throws IOException {
		InputStream inputStream = System.in;
		OutputStream outputStream = System.out;
		PrintWriter out = new PrintWriter(outputStream);
		InputReader in = new InputReader(inputStream);
		//InputStream uinputStream = new FileInputStream("milkorder.in");
		//InputReader in = new InputReader(uinputStream);
		//PrintWriter out = new PrintWriter(new BufferedWriter(new FileWriter("milkorder.out")));
		Task t = new Task();
		t.solve(in, out);
		out.close();
	}

	static class Task {
		
		class TreeNode {
			 int val;
			 TreeNode left;
			 TreeNode right;
			 TreeNode(int x) { val = x; }
		}
		public class ListNode {
			int val;
			ListNode next;
			ListNode(int x) { val = x; }
		}	
		public void solve(InputReader in, PrintWriter out) throws IOException {
//			long tStart = System.currentTimeMillis();
			int n = in.nextInt();
			int d = in.nextInt();
			int k = in.nextInt();
			int l = 0;
			int cur = 1;
			while(true){
				int tmp = cur*k;
				if(cur+tmp<=n){
					l++;
					cur+=tmp;
				}else{
					if(n-cur>k) l=l*2+2;
					else l=l*2+1;
					break;
				}
			}
			if(l>d){
				out.println("NO");
			}else{
				out.println("YES");
				Queue<Integer> q = new LinkedList<Integer>();
				q.add(1);
				int next = 2;
				while(next<=n){
					int f = q.poll();
					for(int i=0;i<k;i++){
						if(next>n) break;
						out.println(f+" "+next);
						q.add(next);
						next++;
					}
				}
			}
		}
	}

	// default class
	static class InputReader {
		public BufferedReader re;
		public StringTokenizer st;

		public InputReader(InputStream input) {
			re = new BufferedReader(new InputStreamReader(input));
			st = null;
		}

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

		public String nextLine() {
			String tmp = null;
			try {
				tmp = re.readLine();
			} catch (IOException e) {
				throw new RuntimeException(e);
			}
			return tmp;
		}

		public boolean hasNext() {
			String tmp;
			if (st != null && st.hasMoreTokens())
				return true;
			else {
				try {
					tmp = re.readLine();
				} catch (IOException e) {
					throw new RuntimeException(e);
				}
				if (tmp != null) {
					st = new StringTokenizer(tmp);
					return true;
				} else {
					return false;
				}
			}
		}

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

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

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

	static class Dumper {
		static void print_int_arr(int[] arr) {
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + " ");
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_char_arr(char[] arr) {
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + " ");
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_double_arr(double[] arr) {
			for (int i = 0; i < arr.length; i++) {
				System.out.print(arr[i] + " ");
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_2d_arr(int[][] arr, int x, int y) {
			for (int i = 0; i < x; i++) {
				for (int j = 0; j < y; j++) {
					System.out.print(arr[i][j] + " ");
				}
				System.out.println();
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print_2d_arr(boolean[][] arr, int x, int y) {
			for (int i = 0; i < x; i++) {
				for (int j = 0; j < y; j++) {
					System.out.print(arr[i][j] + " ");
				}
				System.out.println();
			}
			System.out.println();
			System.out.println("---------------------");
		}

		static void print(Object o) {
			System.out.println(o.toString());
		}

		static void getc() {
			System.out.println("here");
		}
	}
}
