#pragma GCC optimize("O3")

#include "bits/stdc++.h"
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>

using namespace std;
using namespace __gnu_pbds;

typedef long long ll;
tree<int,int,greater<int>,rb_tree_tag,tree_order_statistics_node_update> map_t;
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define F0R(i, a) for(int i = 0; i < (a); ++i)
#define sz(x) (int)x.size()
#define SORT(x) sort(x.begin(),x.end())
#define ERASE(x) x.erase(unique(x.begin(),x.end()),x.end())
#define POSL(x,v) (lower_bound(x.begin(),x.end(),v)-x.begin())
#define POSU(x,v) (upper_bound(x.begin(),x.end(),v)-x.begin())
#define REV(x) reverse(x.begin(),x.end())
int dx[]={-1,0,1,0};
int dy[]={0,-1,0,1};
int n,d,k;
vector<pair<int,int>> res;
int cur;

void construct(int prev,int dep,int mxd) {
    if(dep==mxd)
        return;
    F0R(i,k-1-(dep==0)) {
        if(cur>=n)
            return;
        int v=++cur;
        res.push_back({prev,v});
        construct(v,dep+1,mxd);
    }
}

int main() {
    // freopen("input.txt", "r", stdin);
    // freopen("output.txt", "w", stdout);
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    
    cin >> n >> d >> k;
    if(n<=d) {
        cout << "NO\n";
        return 0;
    }
    F0R(i,d)
        res.push_back({i+1,i+2});
    cur=d+1;
    FOR(i,2,d+1) {
        int cnt=min(i-1,d-i+1);
        construct(i,0,cnt);
    }
    if(sz(res)==n-1) {
        cout << "YES\n";
        F0R(i,sz(res))
            cout << res[i].first << " " << res[i].second << "\n";
    }
    else
        cout << "NO\n";

    return 0;
}
