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

public class Competitive_1 {	
	
	static LinkedList<Integer> adj[];
	static int remainNodes = 0;
	static boolean ans = true;
	static int n, d, k;
	static boolean visited[];
	static int nextToAdd = 0;
	static int maxAllowedDepth = 0;
	
	public static void main(String[] args){
		Scanner in = new Scanner(System.in);
		n=in.nextInt();
		d=in.nextInt();
		k=in.nextInt();
		adj = new LinkedList[n];
		visited = new boolean[n];
		remainNodes = n-1;
		
		if(k==1 && d>1) {
			System.out.println("NO");
			return;
		}
		
		for(int i=0; i<n; i++)
			adj[i] = new LinkedList<Integer>();
		
		int prev = 0;
		for(int i=1; i<=d/2; i++) {
			if(!ans) {
				System.out.println("NO");
				return;
			}
			
			if(remainNodes <= 0) {
				ans = false;
				break;
			}
			
			adj[i].add(prev);
			adj[prev].add(i);
			prev = i;
			remainNodes--;
		}
		
		prev = 0;
		for(int i=(d/2)+1; i<=d; i++) {
			if(!ans) {
				System.out.println("NO");
				return;
			}
			
			if(remainNodes <= 0) {
				ans = false;
				break;
			}
			
			adj[i].add(prev);
			adj[prev].add(i);
			prev = i;
			
			remainNodes--;
			nextToAdd = i+1;
		}
		
		if(!ans) {
			System.out.println("NO");
			return;
		}
		
		maxAllowedDepth = d/2;
				
		dfs(0, -1, 0, false);
		
		if(remainNodes>0)
			ans = false;
		
		if(!ans) {
			System.out.println("NO");
			return;
		}
		
		StringBuilder print = new StringBuilder("YES\n");
		HashSet<String> set = new HashSet<String>(); 
		
		for(int i=0; i<n; i++)
			for(int x : adj[i])
				if(!set.contains((i+1) + " " + (x+1))) {
					print.append((i+1) + " " + (x+1) + "\n");
					set.add((i+1) + " " + (x+1));
					set.add((x+1) + " " + (i+1));
				}
		
		System.out.println(print);
	}
	
	static void dfs(int current, int prev, int depth, boolean hasExtra) {
		if(visited[current])
			return;
		
		if(d%2==1 && current>=(d/2)+1 && current<=d) {
			hasExtra = true;
		}
		
		visited[current] = true;
		int allowed = maxAllowedDepth + (hasExtra ? 1 : 0);
		
		if(remainNodes<=0 || depth>=allowed)
			return;
				
		int add = k - adj[current].size();
		
		for(int i=0; i<add; i++) {
			adj[current].add(nextToAdd);
			adj[nextToAdd].add(current);
			remainNodes--;
			nextToAdd++;
			
			if(remainNodes<=0)
				return;
		}
		
		for(int x : adj[current]) {
			if(x != prev)
				dfs(x, current, depth+1, hasExtra);
		}
		
	}
	
}