#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#define forn(i,n) for(int (i)=0;(i)<(n);(i)++)
#define F first
#define S second
#define pi pair<int,int>
#define pll pair<ll,ll>
#define all(x) (x).begin(),(x).end()
#define fill(x,a) fill((x).begin(),(x).end(),(a))
#define setbitcount __builtin_popcount
#define isodd __builtin_parity
#define clz __builtin_clz
#define ctz __builtin_ctz
#define pque priority_queue
#define vi vector<int>
#define vvi vector<vector<int>>
#define vll vector<ll>
#define vvll vector<vector<ll>>
#define vpi vector<pi>
#define vvpi vector<vector<pi>>
#define vpll vector<pll>
#define vvpll vector<vector<pll>>
#define pb push_back
#define mp make_pair
#define pln cout<<"\n";
#define endl "\n"
#define OPTIMISED ios_base::sync_with_stdio(false);cin.tie(NULL);cout.tie(NULL);
using namespace std;
using namespace __gnu_pbds;
mt19937 rng32(chrono::steady_clock::now().time_since_epoch().count());
typedef tree<int, null_type, less<int>, rb_tree_tag,tree_order_statistics_node_update> pbds;
typedef  long long ll;
typedef unsigned long long ull;
typedef unsigned int uint;
const ll inf9=1e9,inf18=1e18,inf6=1e6,inf14=1e14;
const ll mod7=inf9+7,mod9=inf9+9;
const int modi=998244353;
clock_t time_p=clock();
void clk()
{
    time_p=clock()-time_p;
    cerr<<"Time Taken : "<<(float)(time_p)/CLOCKS_PER_SEC<<"\n";
}
int n,d,k;
vpi edges;
int add(int v,int last,int rem,int deg)
{
	if(rem==0 || deg<=0)return last;
	forn(i,deg)
	{
		edges.pb(mp(v,last+1));
		last++;
		last=add(last,last,rem-1,k-1);
	}
	return last;
}
int main()
{
	OPTIMISED
	cin>>n>>d>>k;
	if(n==1)
	{
		if(d==0)cout<<"YES"<<endl;
		else cout<<"NO"<<endl;
		return 0;
	}
	if(n==2)
	{
		if(k>=1 && d==1){cout<<"YES"<<endl;cout<<"1 2"<<endl;}
		else cout<<"NO"<<endl;
		return 0;
	}
	if(1ll*n*k<1ll*(2*(n-1)))
	{
		cout<<"NO"<<endl;
		return 0;
	}
	if(d>n-1)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	for(int i=1;i<=d;i++)
	{
		edges.pb(mp(i,i+1));
	}
	int last=d+1;
	for(int i=2;i<=d;i++)
	{
		if(last>n)break;
		int maxlevel=min(i-1,d+1-i);
		last=add(i,last,maxlevel,k-2);
	}
	if(last<n)
	{
		cout<<"NO"<<endl;
		return 0;
	}
	cout<<"YES"<<endl;
	for(auto it:edges){if(it.F<=n && it.S<=n)cout<<it.F<<" "<<it.S<<endl;}
	clk();
    return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>=n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	if(k==1&&n>2)
	{
		cout<<"NO\n";
		return 0;
	}

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n&&i<l;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";
		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n&&i<l;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";
		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>=n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n&&i<l;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";
		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>=n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	if(k==1||n==1)
	{
		cout<<"0\n";
		return 0;
	}

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n&&i<l;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";
		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";

		if(l<=i)
			break;

		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>=n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	if(k==1)
	{
		cout<<"0\n";
		return 0;
	}

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n&&i<l;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";
		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ms(s, n) memset(s, n, sizeof(s))
#define FOR(i, a, b) for (int i = (a); i < (b); i++)
#define FORd(i, a, b) for (int i = (a) - 1; i >= (b); i--)
#define FORall(it, a) for (__typeof((a).begin()) it = (a).begin(); it != (a).end(); it++)
#define sz(a) int((a).size())
#define all(a) (a).begin(), (a).end()
#define uni(a) (a).erase(unique(all(a)), (a).end())
#define pb push_back
#define pf push_front
#define mp make_pair
#define fi first
#define se second
#define prec(n) fixed<<setprecision(n)
#define bit(n, i) (((n) >> (i)) & 1)
#define bitcount(n) __builtin_popcount(n)
typedef long long ll;
typedef unsigned long long ull;
typedef long double ld;
typedef pair<int, int> pi;
typedef vector<int> vi;
typedef vector<pi> vii;
const int MOD = (int) 1e9 + 7;
const int INF = (int) 1e9;
const ll LINF = (ll) 1e18;
const ld PI = acos((ld) -1);
const ld EPS = 1e-9;
ll gcd(ll a, ll b) {ll r; while (b) {r = a % b; a = b; b = r;} return a;}
ll lcm(ll a, ll b) {return a / gcd(a, b) * b;}
ll fpow(ll n, ll k, int p = MOD) {ll r = 1; for (; k; k >>= 1) {if (k & 1) r = r * n % p; n = n * n % p;} return r;}
template<class T> void setmin(T& a, T val) {if (a > val) a = val;}
template<class T> void setmax(T& a, T val) {if (a < val) a = val;}
void addmod(int& a, int val, int p = MOD) {if ((a = (a + val)) >= p) a -= p;}
void submod(int& a, int val, int p = MOD) {if ((a = (a - val)) < 0) a += p;}
int mult(int a, int b, int p = MOD) {return (ll) a * b % p;}
int inv(int a, int p = MOD) {return fpow(a, p - 2, p);}

const int N=400005;
vector<int> a[N];

int deg[N],dis[N];

void dfs(int u,int par)
{
	for(int i=0;i<a[u].size();i++)
	{
		if(a[u][i]!=par)
		{
			cout<<u<<" "<<a[u][i]<<"\n";
			dfs(a[u][i],u);
		}
	}
}

int main()
{
	int d,n,k;
	cin>>n>>d>>k;

	if(d>=n)
	{
		cout<<"NO\n";
		return 0;
	}

	for(int i=1;i<=d;i++)
	{
		dis[i]=max(i-1,d+1-i);
		a[i].pb(i+1);
		a[i+1].pb(i);
		deg[i]=2;
	}

	deg[1]=1;
	dis[d+1]=dis[d]+1;
	deg[d+1]=1;

	if(k==1&&n>2)
	{
		cout<<"0\n";
		return 0;
	}

	/*for(int i=1;i<=k;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	int l=d+2;

	for(int i=1;i<=n&&i<l;i++)
	{
		//cout<<l<<" "<<i<<" "<<dis[i]<<" "<<deg[i]<<"\n";
		while(dis[i]<d&&deg[i]<k&&l<=n)
		{
			a[i].pb(l);
			a[l].pb(i);
			deg[i]++;
			deg[l]=1;
			dis[l]=dis[i]+1;
			l++;
		}
	}

	/*cout<<l<<"\n";
	for(int i=1;i<=n;i++)
		cout<<i<<" "<<deg[i]<<" "<<dis[i]<<"\n";*/

	if(l<=n)
		cout<<"NO\n";
	else
	{
		cout<<"YES\n";
		dfs(1,0);
	}

	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[2000010],y[2000010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	if (d>=n){
		printf("NO");
		return 0;
	}
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd==n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt>=n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%lld %lld\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[400010],y[400010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd==n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt==n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%lld %lld\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[400010],y[400010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd==n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt>=n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%lld %lld\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[2000010],y[2000010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	if (d>=n){
		printf("NO");
		return 0;
	}
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd>=n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt>=n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%lld %lld\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[2000010],y[2000010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	if (d>=n){
		printf("NO");
		return 0;
	}
	if (k==1&&n>2){
		printf("NO");
		return 0;
	}
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd>=n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt>=n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%lld %lld\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[400010],y[400010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd==n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt==n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%d %d\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include <bits/stdc++.h>
using namespace std;
#define int long long
int n,d,k,cnt=0;
int x[400010],y[400010];
struct node {
	int id,mx,nd,si;
};
bool operator <(node x,node y){
	return x.mx>y.mx;
}
priority_queue<node> q;
signed main () {
	scanf("%lld%lld%lld",&n,&d,&k);
	if (d>=n){
		printf("NO");
		return 0;
	}
	for (register int i = 1; i <= d; i++){
		x[++cnt] = i;
		y[cnt] = i+1;
		//q.push(node{i+1,min(i,d-i),max(i,d-i)});
	}
	for (register int i = 2; i <= d; i++){
		q.push(node{i,min(i-1,d-i+1),0,2});
	}
	int nnd = d+2;
	while(!q.empty()){
		node now = q.top();
		q.pop();
		//cout << "now.id=" << now.id << endl;
		if (now.mx==now.nd)continue;
		while(now.si<k){
			//printf("can:%d \n",nnd);
			x[++cnt] = nnd;
			y[cnt] = now.id;
			q.push(node{nnd,now.mx,now.nd+1,1});
			nnd++;now.si++;
			if (nnd==n+1)goto end;
		}
	}
	//cout << cnt << endl;
	end:;
	if (cnt>=n-1){
		printf("YES\n");
		for (register int i = 1; i <= n-1; i++){
			printf("%lld %lld\n",x[i],y[i]);
		}
	}else {
		printf("NO");
	}
	return 0;
}


#include<bits/stdc++.h>
using namespace std;

struct xy
{
    int a, b;
};

vector<xy> ans;
int n, d, k, K;
int N;
vector<int> arc[400001];
int node[400001];
int next_[400001];
vector<xy> Ans;

int dfs(int v, int s)
{
    if (s <= 1)
        return 0;

    int m = 0;
    int i;
    if (s-1 <= K)
    {
        xy t;
        t.a = v;
        for(i=1; i<=s-1; i++)
        {
            t.b = ++N;
            ans.push_back(t);
        }
        return 1;
    }
    else
    {
        xy t;
        t.a = v;
        t.b = ++N;
        ans.push_back(t);
        m = 1 + dfs(N, (s-1)/K + (s-1) % K);
        for(i=1; i<K; i++)
        {
            t.b = ++N;
            ans.push_back(t);
            m = max(m, 1 + dfs(N, (s-1)/K));
        }
        return m;
    }
}

void dfs2(int v, int l)
{
    if (l <= 0)
    {
        node[v] = 0;
        return;
    }

    xy tmp;
    node[v] = l;
    tmp.a = v;
    next_[v] = ++N;
    tmp.b = N;
    Ans.push_back(tmp);
    dfs2(N, l-1);
}

void dfs4(int v, int l)
{
    if (l <= 0)
        return;
    xy t;
    t.a = v;
    for(int i=1; i<=k-1; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, l-1);
        }
    }
}

void dfs3(int v)
{
    if (node[v] == 0)
        return;

    xy t;
    t.a = v;
    for(int i=1; i<= k-2; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, node[v]-1);
        }
    }
    if (N < n)
    {
        dfs3(next_[v]);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d >> k;

    N=1;
    int i;
    xy tmp;
    tmp.a = 1;
    K = k-1;
    if(n == 1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if ((n-1 <= k) && (d ==2))
    {
        cout << "YES" << endl;
        for(i=2; i<=n; i++)
        {
            cout << 1 << " " << i << endl;
        }
        return 0;
    }
    if(k==1)
    {
        if (n==2 && d==1)
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }
        else
        {cout << "NO" << endl;
        return 0;
        }
    }

    if (n==2 && d==1)
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }

    for(i=1; i<=k; i++)
    {
        tmp.b = ++N;
        ans.push_back(tmp);
    }
    int max_ = 1 + dfs(2, (n-1) / k + (n-1) % k);
    int m2=0;
    for(i=3; i<=k+1; i++)
    {
        m2 = max(m2, 1 + dfs(i, (n-1)/k));
    }

    //cout << max_ + m2 << endl;
    if (d > n-1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if (max_ + m2 <= d)
    {
        if (max_+m2 == d)
        {
        cout << "YES" << endl;
        for(i=0; i < ans.size(); i++)
        {
            cout << ans[i].a << " " << ans[i].b << endl;
        }
        }
        else
        {
            N=1;
            node[1] = d/2;
            tmp.a=1;
            tmp.b=++N;
            Ans.push_back(tmp);
            tmp.b=++N;
            Ans.push_back(tmp);
            dfs2(2, d/2 -1);
            if (d % 2 == 1)
                dfs2(3, d/2);
            else
                dfs2(3, d/2 -1);

            if (N < n)
            {
                dfs3(2);
            }
            if (N < n)
            {
                dfs3(3);
            }
            next_[1] = 0;
            node[0] = 0;
            if (N<n)
            {
                dfs3(1);
            }

            if (N < n)
            {
                cout << "NO" << endl;
            }
            else
            {
                cout << "YES" << endl;
                for(i=0; i<Ans.size(); i++)
                {
                    cout << Ans[i].a << " " << Ans[i].b << endl;
                }
            }

        }
    }
    else
    {
        cout << "NO" << endl;
    }

}


#include<bits/stdc++.h>
using namespace std;

struct xy
{
    int a, b;
};

vector<xy> ans;
int n, d, k, K;
int N;

int dfs(int v, int s)
{
    if (s <= 1)
        return 0;

    int m = 0;
    int i;
    if (s-1 <= K)
    {
        xy t;
        t.a = v;
        for(i=1; i<=s-1; i++)
        {
            t.b = ++N;
            ans.push_back(t);
        }
        return 1;
    }
    else
    {
        xy t;
        t.a = v;
        t.b = ++N;
        ans.push_back(t);
        m = 1 + dfs(N, (s-1)/K + (s-1) % K);
        for(i=1; i<K; i++)
        {
            t.b = ++N;
            ans.push_back(t);
            m = max(m, 1 + dfs(N, (s-1)/K));
        }
        return m;
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d >> k;

    N=1;
    int i;
    xy tmp;
    tmp.a = 1;
    K = k-1;
    if(n == 1)
    {
        cout << "YES" << endl;
        return 0;
    }

    if (n-1 <= k)
    {
        cout << "YES" << endl;
        for(i=2; i<=n; i++)
        {
            cout << 1 << " " << i << endl;
        }
        return 0;
    }

    for(i=1; i<=k; i++)
    {
        tmp.b = ++N;
        ans.push_back(tmp);
    }
    int max_ = 1 + dfs(2, (n-1) / k + (n-1) % k);
    int m2=0;
    for(i=3; i<=k+1; i++)
    {
        m2 = max(m2, 1 + dfs(i, (n-1)/k));
    }

    if (max_ + m2 <= d)
    {
        cout << "YES" << endl;
        for(i=0; i < ans.size(); i++)
        {
            cout << ans[i].a << " " << ans[i].b << endl;
        }
    }
    else
    {
        cout << "NO" << endl;
    }

}


#include<bits/stdc++.h>
using namespace std;

struct xy
{
    int a, b;
};

vector<xy> ans;
int n, d, k, K;
int N;
vector<int> arc[400001];
int node[400001];
int next_[400001];
vector<xy> Ans;

int dfs(int v, int s)
{
    if (s <= 1)
        return 0;

    int m = 0;
    int i;
    if (s-1 <= K)
    {
        xy t;
        t.a = v;
        for(i=1; i<=s-1; i++)
        {
            t.b = ++N;
            ans.push_back(t);
        }
        return 1;
    }
    else
    {
        xy t;
        t.a = v;
        t.b = ++N;
        ans.push_back(t);
        m = 1 + dfs(N, (s-1)/K + (s-1) % K);
        for(i=1; i<K; i++)
        {
            t.b = ++N;
            ans.push_back(t);
            m = max(m, 1 + dfs(N, (s-1)/K));
        }
        return m;
    }
}

void print()
{
    if ((N < n) || (N > n))
    {
        cout << "NO" << endl;
    }
    else
    {
        cout << "YES" << endl;
        for(int i=0; i<Ans.size(); i++)
        {
            cout << Ans[i].a << " " << Ans[i].b << endl;
        }
    }
}

void dfs2(int v, int l)
{
    if (l <= 0)
    {
        node[v] = 0;
        return;
    }

    xy tmp;
    node[v] = l;
    tmp.a = v;
    next_[v] = ++N;
    tmp.b = N;
    Ans.push_back(tmp);
    dfs2(N, l-1);
}

void dfs4(int v, int l)
{
    if (l <= 0)
        return;
    xy t;
    t.a = v;
    for(int i=1; i<=k-1; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, l-1);
        }
        else
        {
            print();
            exit(0);
        }
    }
}

void dfs3(int v)
{
    if (node[v] == 0)
        return;

    xy t;
    t.a = v;
    for(int i=1; i<= k-2; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, node[v]-1);
        }
        else
        {
            print();
            exit(0);
        }
    }
    if (N < n)
    {
        dfs3(next_[v]);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d >> k;

    N=1;
    int i;
    xy tmp;
    tmp.a = 1;
    K = k-1;
    if(n == 1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if(k==1)
    {
        if ((n==2) && (d==1))
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }
        else
        {cout << "NO" << endl;
        return 0;
        }
    }

    if (d==1)
        {
            if (n == 2)
            {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
            }
            else
            {
                cout << "NO" << endl;
        return 0;
            }
        }

    /*for(i=1; i<=k; i++)
    {
        tmp.b = ++N;
        ans.push_back(tmp);
    }
    int max_ = 1 + dfs(2, (n-1) / k + (n-1) % k);
    int m2=0;
    for(i=3; i<=k+1; i++)
    {
        m2 = max(m2, 1 + dfs(i, (n-1)/k));
    }

    cout << max_ + m2 << endl;
    if (d > n-1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if (max_ + m2 <= d)
    {
        if (max_+m2 == d)
        {
        cout << "YES" << endl;
        for(i=0; i < ans.size(); i++)
        {
            cout << ans[i].a << " " << ans[i].b << endl;
        }
        }
        else
        {*/
            N=1;
            node[1] = d/2;
            tmp.a=1;
            tmp.b=++N;
            Ans.push_back(tmp);
            tmp.b=++N;
            Ans.push_back(tmp);
            dfs2(2, d/2 -1);
            if (d % 2 == 1)
                dfs2(3, d/2);
            else
                dfs2(3, d/2 -1);

            if (N < n)
            {
                dfs3(2);
            }
            if (N < n)
            {
                dfs3(3);
            }
            next_[1] = 0;
            node[0] = 0;
            if (N<n)
            {
                dfs3(1);
            }

            print();

  //      }
  //  }
  //  else
  //  {
  //      cout << "NO" << endl;
  //  }

}


#include<bits/stdc++.h>
using namespace std;

struct xy
{
    int a, b;
};

vector<xy> ans;
int n, d, k, K;
int N;
vector<int> arc[400001];
int node[400001];
int next_[400001];
vector<xy> Ans;

int dfs(int v, int s)
{
    if (s <= 1)
        return 0;

    int m = 0;
    int i;
    if (s-1 <= K)
    {
        xy t;
        t.a = v;
        for(i=1; i<=s-1; i++)
        {
            t.b = ++N;
            ans.push_back(t);
        }
        return 1;
    }
    else
    {
        xy t;
        t.a = v;
        t.b = ++N;
        ans.push_back(t);
        m = 1 + dfs(N, (s-1)/K + (s-1) % K);
        for(i=1; i<K; i++)
        {
            t.b = ++N;
            ans.push_back(t);
            m = max(m, 1 + dfs(N, (s-1)/K));
        }
        return m;
    }
}

void print()
{
    if ((N < n) || (N > n))
    {
        cout << "NO" << endl;
    }
    else
    {
        cout << "YES" << endl;
        for(int i=0; i<Ans.size(); i++)
        {
            cout << Ans[i].a << " " << Ans[i].b << endl;
        }
    }
}

void dfs2(int v, int l)
{
    if (l <= 0)
    {
        node[v] = 0;
        return;
    }

    xy tmp;
    node[v] = l;
    tmp.a = v;
    next_[v] = ++N;
    tmp.b = N;
    Ans.push_back(tmp);
    dfs2(N, l-1);
}

void dfs4(int v, int l)
{
    if (l <= 0)
        return;
    xy t;
    t.a = v;
    for(int i=1; i<=k-1; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, l-1);
        }
        else
        {
            print();
            exit(0);
        }
    }
}

void dfs3(int v)
{
    if (node[v] == 0)
        return;

    xy t;
    t.a = v;
    for(int i=1; i<= k-2; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, node[v]-1);
        }
        else
        {
            print();
            exit(0);
        }
    }
    if (N < n)
    {
        dfs3(next_[v]);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d >> k;

    N=1;
    int i;
    xy tmp;
    tmp.a = 1;
    K = k-1;
    if(n == 1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if ((n-1 <= k) && (d ==2))
    {
        cout << "YES" << endl;
        for(i=2; i<=n; i++)
        {
            cout << 1 << " " << i << endl;
        }
        return 0;
    }
    if(k==1)
    {
        if (n==2 && d==1)
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }
        else
        {cout << "NO" << endl;
        return 0;
        }
    }

    if (d==1)
        {
            if (n == 2)
            {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
            }
            else
            {
                cout << "NO" << endl;
        return 0;
            }
        }

    /*for(i=1; i<=k; i++)
    {
        tmp.b = ++N;
        ans.push_back(tmp);
    }
    int max_ = 1 + dfs(2, (n-1) / k + (n-1) % k);
    int m2=0;
    for(i=3; i<=k+1; i++)
    {
        m2 = max(m2, 1 + dfs(i, (n-1)/k));
    }

    cout << max_ + m2 << endl;
    if (d > n-1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if (max_ + m2 <= d)
    {
        if (max_+m2 == d)
        {
        cout << "YES" << endl;
        for(i=0; i < ans.size(); i++)
        {
            cout << ans[i].a << " " << ans[i].b << endl;
        }
        }
        else
        {*/
            N=1;
            node[1] = d/2;
            tmp.a=1;
            tmp.b=++N;
            Ans.push_back(tmp);
            tmp.b=++N;
            Ans.push_back(tmp);
            dfs2(2, d/2 -1);
            if (d % 2 == 1)
                dfs2(3, d/2);
            else
                dfs2(3, d/2 -1);

            if (N < n)
            {
                dfs3(2);
            }
            if (N < n)
            {
                dfs3(3);
            }
            next_[1] = 0;
            node[0] = 0;
            if (N<n)
            {
                dfs3(1);
            }

            print();

  //      }
  //  }
  //  else
  //  {
  //      cout << "NO" << endl;
  //  }

}


#include<bits/stdc++.h>
using namespace std;

struct xy
{
    int a, b;
};

vector<xy> ans;
int n, d, k, K;
int N;
vector<int> arc[400001];
int node[400001];
int next_[400001];
vector<xy> Ans;

int dfs(int v, int s)
{
    if (s <= 1)
        return 0;

    int m = 0;
    int i;
    if (s-1 <= K)
    {
        xy t;
        t.a = v;
        for(i=1; i<=s-1; i++)
        {
            t.b = ++N;
            ans.push_back(t);
        }
        return 1;
    }
    else
    {
        xy t;
        t.a = v;
        t.b = ++N;
        ans.push_back(t);
        m = 1 + dfs(N, (s-1)/K + (s-1) % K);
        for(i=1; i<K; i++)
        {
            t.b = ++N;
            ans.push_back(t);
            m = max(m, 1 + dfs(N, (s-1)/K));
        }
        return m;
    }
}

void dfs2(int v, int l)
{
    if (l <= 0)
    {
        node[v] = 0;
        return;
    }

    xy tmp;
    node[v] = l;
    tmp.a = v;
    next_[v] = ++N;
    tmp.b = N;
    Ans.push_back(tmp);
    dfs2(N, l-1);
}

void dfs4(int v, int l)
{
    if (l <= 0)
        return;
    xy t;
    t.a = v;
    for(int i=1; i<=k-1; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, l-1);
        }
    }
}

void dfs3(int v)
{
    if (node[v] == 0)
        return;

    xy t;
    t.a = v;
    for(int i=1; i<= k-2; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, node[v]-1);
        }
    }
    if (N < n)
    {
        dfs3(next_[v]);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d >> k;

    N=1;
    int i;
    xy tmp;
    tmp.a = 1;
    K = k-1;
    if(n == 1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if ((n-1 <= k) && (d ==2))
    {
        cout << "YES" << endl;
        for(i=2; i<=n; i++)
        {
            cout << 1 << " " << i << endl;
        }
        return 0;
    }
    if(k==1)
    {
        if (n==2 && d==1)
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }
        else
        {cout << "NO" << endl;
        return 0;
        }
    }

    if (d==1)
        {
            if (n == 2)
            {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
            }
            else
            {
                cout << "NO" << endl;
        return 0;
            }
        }

    /*for(i=1; i<=k; i++)
    {
        tmp.b = ++N;
        ans.push_back(tmp);
    }
    int max_ = 1 + dfs(2, (n-1) / k + (n-1) % k);
    int m2=0;
    for(i=3; i<=k+1; i++)
    {
        m2 = max(m2, 1 + dfs(i, (n-1)/k));
    }

    cout << max_ + m2 << endl;
    if (d > n-1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if (max_ + m2 <= d)
    {
        if (max_+m2 == d)
        {
        cout << "YES" << endl;
        for(i=0; i < ans.size(); i++)
        {
            cout << ans[i].a << " " << ans[i].b << endl;
        }
        }
        else
        {*/
            N=1;
            node[1] = d/2;
            tmp.a=1;
            tmp.b=++N;
            Ans.push_back(tmp);
            tmp.b=++N;
            Ans.push_back(tmp);
            dfs2(2, d/2 -1);
            if (d % 2 == 1)
                dfs2(3, d/2);
            else
                dfs2(3, d/2 -1);

            if (N < n)
            {
                dfs3(2);
            }
            if (N < n)
            {
                dfs3(3);
            }
            next_[1] = 0;
            node[0] = 0;
            if (N<n)
            {
                dfs3(1);
            }

            if ((N < n) || (N > n))
            {
                cout << "NO" << endl;
            }
            else
            {
                cout << "YES" << endl;
                for(i=0; i<Ans.size(); i++)
                {
                    cout << Ans[i].a << " " << Ans[i].b << endl;
                }
            }

  //      }
  //  }
  //  else
  //  {
  //      cout << "NO" << endl;
  //  }

}


#include<bits/stdc++.h>
using namespace std;

struct xy
{
    int a, b;
};

vector<xy> ans;
int n, d, k, K;
int N;
vector<int> arc[400001];
int node[400001];
int next_[400001];
vector<xy> Ans;

int dfs(int v, int s)
{
    if (s <= 1)
        return 0;

    int m = 0;
    int i;
    if (s-1 <= K)
    {
        xy t;
        t.a = v;
        for(i=1; i<=s-1; i++)
        {
            t.b = ++N;
            ans.push_back(t);
        }
        return 1;
    }
    else
    {
        xy t;
        t.a = v;
        t.b = ++N;
        ans.push_back(t);
        m = 1 + dfs(N, (s-1)/K + (s-1) % K);
        for(i=1; i<K; i++)
        {
            t.b = ++N;
            ans.push_back(t);
            m = max(m, 1 + dfs(N, (s-1)/K));
        }
        return m;
    }
}

void dfs2(int v, int l)
{
    if (l <= 0)
    {
        node[v] = 0;
        return;
    }

    xy tmp;
    node[v] = l;
    tmp.a = v;
    next_[v] = ++N;
    tmp.b = N;
    Ans.push_back(tmp);
    dfs2(N, l-1);
}

void dfs4(int v, int l)
{
    if (l <= 0)
        return;
    xy t;
    t.a = v;
    for(int i=1; i<=k-1; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, l-1);
        }
    }
}

void dfs3(int v)
{
    if (node[v] == 0)
        return;

    xy t;
    t.a = v;
    for(int i=1; i<= k-2; i++)
    {
        if (N < n)
        {
            t.b = ++N;
            Ans.push_back(t);
            dfs4(N, node[v]-1);
        }
    }
    if (N < n)
    {
        dfs3(next_[v]);
    }
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cin >> n >> d >> k;

    N=1;
    int i;
    xy tmp;
    tmp.a = 1;
    K = k-1;
    if(n == 1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if ((n-1 <= k) && (d ==2))
    {
        cout << "YES" << endl;
        for(i=2; i<=n; i++)
        {
            cout << 1 << " " << i << endl;
        }
        return 0;
    }
    if(k==1)
    {
        if (n==2 && d==1)
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }
        else
        {cout << "NO" << endl;
        return 0;
        }
    }

    if (n==2 && d==1)
        {
            cout << "YES" << endl;
            cout << "1 2" << endl;
            return 0;
        }

    /*for(i=1; i<=k; i++)
    {
        tmp.b = ++N;
        ans.push_back(tmp);
    }
    int max_ = 1 + dfs(2, (n-1) / k + (n-1) % k);
    int m2=0;
    for(i=3; i<=k+1; i++)
    {
        m2 = max(m2, 1 + dfs(i, (n-1)/k));
    }

    cout << max_ + m2 << endl;
    if (d > n-1)
    {
        cout << "NO" << endl;
        return 0;
    }

    if (max_ + m2 <= d)
    {
        if (max_+m2 == d)
        {
        cout << "YES" << endl;
        for(i=0; i < ans.size(); i++)
        {
            cout << ans[i].a << " " << ans[i].b << endl;
        }
        }
        else
        {*/
            N=1;
            node[1] = d/2;
            tmp.a=1;
            tmp.b=++N;
            Ans.push_back(tmp);
            tmp.b=++N;
            Ans.push_back(tmp);
            dfs2(2, d/2 -1);
            if (d % 2 == 1)
                dfs2(3, d/2);
            else
                dfs2(3, d/2 -1);

            if (N < n)
            {
                dfs3(2);
            }
            if (N < n)
            {
                dfs3(3);
            }
            next_[1] = 0;
            node[0] = 0;
            if (N<n)
            {
                dfs3(1);
            }

            if ((N < n) || (N > n))
            {
                cout << "NO" << endl;
            }
            else
            {
                cout << "YES" << endl;
                for(i=0; i<Ans.size(); i++)
                {
                    cout << Ans[i].a << " " << Ans[i].b << endl;
                }
            }

  //      }
  //  }
  //  else
  //  {
  //      cout << "NO" << endl;
  //  }

}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil,int num){
  if(ceil==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n-1) return;
    linkline(now,ceil-1,num);
    if(now==n-1) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) printf("YES\n");
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  for(int i = 1;i<=n;i++){
    int tmp=k-1;
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=n-1;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  int mid=(d/2)-1;
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d;
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n-1) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n-1) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n-1) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil1,int num){
  if(ceil1==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n) return;
    linkline(now,ceil1-1,num);
    if(now==n) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) printf("YES\n");
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  int tmp=(k-1)*(k-2);
  for(int i = 2;i<=n;i++){
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  //for(int i = 1;i<=6;i++) printf("%d ",f[i]);
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=d;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d+1;
  //printf("OK");
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil1,int num){
  if(ceil1==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n) return;
    linkline(now,ceil1-1,num);
    if(now==n) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) {
      printf("YES\n");
      printf("1 2\n");
    }
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  int tmp=(k-1)*(k-2);
  for(int i = 2;i<=n;i++){
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  //for(int i = 1;i<=6;i++) printf("%d ",f[i]);
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=d;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d+1;
  //printf("OK");
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil,int num){
  if(ceil==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n) return;
    linkline(now,ceil-1,num);
    if(now==n) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) printf("YES\n");
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  int tmp=k-1;
  for(int i = 1;i<=n;i++){
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  //for(int i = 1;i<=6;i++) printf("%d ",f[i]);
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=n-1;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d+1;
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil,int num){
  if(ceil==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n) return;
    linkline(now,ceil-1,num);
    if(now==n) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) printf("YES\n");
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  for(int i = 1;i<=n;i++){
    int tmp=k-1;
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=n-1;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  int mid=(d/2)-1;
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d+1;
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil1,int num){
  if(ceil1==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n) return;
    linkline(now,ceil1-1,num);
    if(now==n) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) printf("YES\n");
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  int tmp=k-2;
  for(int i = 2;i<=n;i++){
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  //for(int i = 1;i<=6;i++) printf("%d ",f[i]);
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=d;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d+1;
  //printf("OK");
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<cstdio>
#include<iostream>
using namespace std;
#define ll long long
const int N=4e5+7;
int n,d,k,now;
ll f[N];
ll sum;
void linkline(int x,int ceil1,int num){
  if(ceil1==0) return;
  for(int i = 1;i<=num;i++){
    now++;
    printf("%d %d\n",x,now);
    //printf("%d\n",now);
    if(now==n) return;
    linkline(now,ceil1-1,num);
    if(now==n) return;
  }
}

int main(){
  scanf("%d%d%d",&n,&d,&k);
  if(d>=n){
    printf("NO\n");
    return 0;
  }
  if(k==1){
    if(n==2&&d==1) printf("YES\n");
    else printf("NO\n");
    return 0;
  }
  f[1]=k-2;
  int tmp=k-1;
  for(int i = 2;i<=n;i++){
    f[i]=f[i-1]+tmp;
    tmp=tmp*(k-1);
    if(f[i]>n) break;
  }
  //for(int i = 1;i<=6;i++) printf("%d ",f[i]);
  int N=n;
  N=N-d-1;
  if(N==0){
    printf("YES\n");
    for(int i = 1;i<=d;i++){
      printf("%d %d\n",i,i+1);
    }
    return 0;
  }
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    sum+=f[tmp];
  }
  if(sum<N){
    printf("NO\n");
    return 0;
  }
  printf("YES\n");
  for(int i = 1;i<=d;i++){
    printf("%d %d\n",i,i+1);
  }
  now=d+1;
  //printf("OK");
  for(int i = 1;i<=d+1;i++){
    int tmp=min(i-1,d+1-i);
    if(tmp==0) continue;
    if(now==n) return 0;
    for(int j = 1;j<=k-2;j++){
      now++;
      printf("%d %d\n",i,now);
      if(now==n) return 0;
      linkline(now,tmp-1,k-1);
      if(now==n) return 0;
    }
    //linkline(i,tmp,k-2);
  }
}


#include<bits/stdc++.h>
using namespace std;
const long long N=1e5+5;
int inp[N];
int dp[N];
signed main(){
	ios_base::sync_with_stdio(0);
	cin.tie(0);
	cout.tie(0);
	long long n;
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> inp[i];
		dp[i]=0;
	}
	dp[0]=0;
	dp[1]=1;
	int ans=0;
	for(int i=2;i<=n;i++){
		for(int j=1;j<i;j++){
			if(inp[i]>inp[j]){
				dp[i] = max(dp[i],dp[j]);
			}
		}
		dp[i]++;
		ans = max(ans,dp[i]);
	}
	cout << ans;
}


#include<bits/stdc++.h>
using namespace std;
const long long N=1e5+5;
int inp[N];
int dp[N];
signed main(){
	long long n;
	cin >> n;
	for(int i=1;i<=n;i++){
		cin >> inp[i];
		dp[i]=0;
	}
	dp[0]=0;
	dp[1]=1;
	int ans=0;
	for(int i=2;i<=n;i++){
		for(int j=1;j<i;j++){
			if(inp[i]>inp[j]){
				dp[i] = max(dp[i],dp[j]);
			}
		}
		dp[i]++;
		ans = max(ans,dp[i]);
	}
	cout << ans;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

lli bs(vector <lli> end, lli l, lli r, lli key)
{
    while(r - l > 1)
    {
        lli mid = (r+l)/2;
        if(end[mid] < key)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    return r;
}

lli LIS(vector <lli> v)
{
    vector <lli> end(v.size(),0);
    lli length = 1;
    end[0] = v[0];
    for(int i = 0; i<v.size(); i++)
    {
        if(v[i] < end[0])
        {
            end[0] = v[i];
        }
        else if(v[i] > end[length-1])
        {
            length++;
            end[length] = v[i];
        }
        else
        {
            end[bs(end,-1,length-1,v[i])] = v[i];
        }
    }
    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli n;
    cin >> n;
    vector <lli> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LIS(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

lli bs(vector <lli> end, lli l, lli r, lli key)
{
    while(r - l > 1)
    {
        lli mid = (r+l)/2;
        if(end[mid] < key)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    return r;
}

lli LIS(vector <lli> v)
{
    if(v.size() == 0)
    {
        return 0;
    }
    vector <lli> end(v.size(),0);
    lli length = 1;
    end[0] = v[0];
    for(int i = 0; i<v.size(); i++)
    {
        if(v[i] < end[0])
        {
            end[0] = v[i];
        }
        else if(v[i] > end[length-1])
        {
            end[length++] = v[i];
        }
        else
        {
            end[bs(end,-1,length-1,v[i])] = v[i];
        }
    }
    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli n;
    cin >> n;
    vector <lli> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LIS(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

// Binary search (note boundaries in the caller)
int CeilIndex(std::vector<int> &v, int l, int r, int key) {
    while (r-l > 1) {
    int m = l + (r-l)/2;
    if (v[m] >= key)
        r = m;
    else
        l = m;
    }

    return r;
}

int LongestIncreasingSubsequenceLength(std::vector<int> &v) {
    if (v.size() == 0)
        return 0;

    std::vector<int> tail(v.size(), 0);
    int length = 1; // always points empty slot in tail

    tail[0] = v[0];
    for (size_t i = 1; i < v.size(); i++) {
        if (v[i] < tail[0])
            // new smallest value
            tail[0] = v[i];
        else if (v[i] > tail[length-1])
            // v[i] extends largest subsequence
            tail[length++] = v[i];
        else
            // v[i] will become end candidate of an existing subsequence or
            // Throw away larger elements in all LIS, to make room for upcoming grater elements than v[i]
            // (and also, v[i] would have already appeared in one of LIS, identify the location and replace it)
            tail[CeilIndex(tail, -1, length-1, v[i])] = v[i];
    }

    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    int n;
    cin >> n;
    vector <int> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LongestIncreasingSubsequenceLength(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

lli bs(vector <lli> end, lli l, lli r, lli key)
{
    while(r >= l)
    {
        lli mid = (r+l)/2;
        if(end[mid] < key)
        {
            l = mid+1;
        }
        else
        {
            r = mid-1;
        }
    }
    return r+1;
}

lli LIS(vector <lli> v)
{
    if(v.size() == 0)
    {
        return 0;
    }
    vector <lli> end(v.size(),0);
    lli length = 1;
    end[0] = v[0];
    for(int i = 0; i<v.size(); i++)
    {
        if(v[i] < end[0])
        {
            end[0] = v[i];
        }
        else if(v[i] > end[length-1])
        {
            end[length++] = v[i];
        }
        else
        {
            end[bs(end,0,length-1,v[i])] = v[i];
        }
    }
    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli n;
    cin >> n;
    vector <lli> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LIS(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

lli bs(vector <lli> end, lli l, lli r, lli key)
{
    while(r >= l)
    {
        lli mid = (r+l)/2;
        if(end[mid] < key)
        {
            l = mid+1;
        }
        else
        {
            r = mid-1;
        }
    }
    return r+1;
}

lli LIS(vector <lli> v)
{
    vector <lli> end(v.size(),0);
    lli length = 1;
    end[0] = v[0];
    for(int i = 0; i<v.size(); i++)
    {
        if(v[i] < end[0])
        {
            end[0] = v[i];
        }
        if(v[i] > end[length-1])
        {
            length++;
            end[length] = v[i];
        }
        else
        {
            end[bs(end,0,length-1,v[i])] = v[i];
        }
    }
    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli n;
    cin >> n;
    vector <lli> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LIS(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

lli bs(vector <lli> end, lli l, lli r, lli key)
{
    while(r - l > 1)
    {
        lli mid = (r+l)/2;
        if(end[mid] < key)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    return r;
}

lli LIS(vector <lli> v)
{
    vector <lli> end(v.size(),0);
    lli length = 1;
    end[0] = v[0];
    for(int i = 0; i<v.size(); i++)
    {
        if(v[i] < end[0])
        {
            end[0] = v[i];
        }
        if(v[i] > end[length-1])
        {
            length++;
            end[length] = v[i];
        }
        else
        {
            end[bs(end,-1,length-1,v[i])] = v[i];
        }
    }
    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli n;
    cin >> n;
    vector <lli> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LIS(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long int lli;
#define pi 3.141592653589793238
typedef pair<lli,lli> pll;
typedef map<lli,lli> mll;
typedef set<lli> sl;
typedef map<int,int> mii;
typedef set<int> si;
#define x first
#define y second
#define mp make_pair
#define pb push_back
const lli mod = 1e9 + 7;

lli power(lli a, lli p)
{
    lli ans = 1;
    while(p > 0)
    {
        if(p%2)
        {
            ans *= a;
            ans %= mod;
        }
        a*=a;
        a%=mod;
        p/=2;
    }
    return ans%mod;
}

vector <lli> getbinary(lli x)
{
    vector <lli> bin(101,0);
    int iter = 0;
    while(x > 0)
    {
        bin[iter] = x%2;
        iter++;
        x/=2;
    }
    return bin;
}

lli bs(vector <lli> end, lli l, lli r, lli key)
{
    while(r - l > 1)
    {
        lli mid = (r+l)/2;
        if(end[mid] < key)
        {
            l = mid;
        }
        else
        {
            r = mid;
        }
    }
    return r;
}

lli LIS(vector <lli> v)
{
    vector <lli> end(v.size(),0);
    lli length = 1;
    end[0] = v[0];
    for(int i = 0; i<v.size(); i++)
    {
        if(v[i] < end[0])
        {
            end[0] = v[i];
        }
        if(v[i] > end[length-1])
        {
            length++;
            end[length] = v[i];
        }
        else
        {
            end[bs(end,0,length-1,v[i])] = v[i];
        }
    }
    return length;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(NULL);
    cout.tie(NULL);
    //freopen("input.txt", "r", stdin);
    //freopen("output.txt", "w", stdout);
    lli n;
    cin >> n;
    vector <lli> a(n);
    for(int i = 0; i<n; i++)
    {
        cin >> a[i];
    }
    cout << LIS(a) << endl;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, ans = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(a[i] <= i+1)ans++;
    }
    cout << ans << endl;x
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];
int t[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, mx = 0, idx;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }
    t[0] = 0;
    int ans = 0;
    for(int i = 1; i < n; i++){
        if(a[t[0]] > a[i]){
            t[0] = i;
        }
        else if(a[t[ans]] < a[i]){
            ans++;
            t[ans] = i;
        }
        else{
            int start = 0, end = ans;
            while(start < end){
                int mid = (start+(end-start)/2);
                if(a[t[mid]] > a[i])
                    end = mid;
                else
                    start = mid + 1;
            }
            t[start] = i;
        }
    }
    cout << ans+1 << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }

    int ans = 0, cnt = 0;
    for(int i = 1; i < n; i++){
        if(a[i] > a[i-1]){
            cnt++;
        }
        else{
            ans = max(ans, cnt+1);
            cnt = 0;
        }
    }
    if(a[n-1] > a[n-2])
        ans = max(ans, cnt+1);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, ans = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(a[i] > i+1)ans+=(a[i]-i-1);
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];
int t[100001];
int r[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, mx = 0, idx;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        r[i] = -1;
    }
    t[0] = 0;
    int ans = 0;
    for(int i = 1; i < n; i++){
        if(a[t[0]] > a[i]){
            t[0] = i;
        }
        else if(a[t[ans]] < a[i]){
            ans++;
            t[ans] = i;
            r[t[ans]] = t[ans-1];
        }
        else{
            int start = 0, end = ans;
            while(start < end){
                int mid = (start+(end-start)/2);
                if(a[t[mid]] > a[i])
                    end = mid;
                else
                    start = mid + 1;
            }
            t[start] = i;
        }
    }
    cout << ans+1 << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];
int dp[10001][1001];
int n;

int solve(int idx, int prv){
    if(idx == n)
        return 0;
    if(dp[idx][prv] != -1)
        return dp[idx][prv];

    int x1 = solve(idx+1, prv);
    int x2 = 0;
    if(a[idx] > prv)
        x2 = solve(idx+1, a[idx]) + 1;
    return dp[idx][prv] = max(x1, x2);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }
    memset(dp, -1, sizeof dp);
    int ans = solve(0, 0);
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, ans = 0, mx = 0, idx;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(a[i] > mx)mx = a[i], idx = i+1;
    }
    ans = n - idx;
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    int n, ans = 0;
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
        if(a[i] <= i+1)ans++;
    }
    cout << ans << endl;
    return 0;
}


#include <bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;

#define F first
#define S second
#define inf INT_MAX
#define INF LONG_LONG_MAX
#define all(v) v.begin(), v.end()
#define rall(v) v.rbegin(), v.rend()

int a[100001];
map<pair<int, int>, int>dp;
int n;

int solve(int idx, int prv){
    if(idx == n)
        return 0;
    if(dp.find({idx, prv}) != dp.end())
        return dp[{idx, prv}];

    int x1 = solve(idx+1, prv);
    int x2 = 0;
    if(a[idx] > prv)
        x2 = solve(idx+1, a[idx]) + 1;
    return dp[{idx, prv}] = max(x1, x2);
}

int main()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cin >> n;
    for(int i = 0; i < n; i++){
        cin >> a[i];
    }

    int ans = solve(0, 0);
    cout << ans << endl;
    return 0;
}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define vpint vector<pair<pair<ll,ll>,ll>
#define vint vector<ll>
#define pb push_back
#define all(v) v.begin(),v.end()
#define ios cin.sync_with_stdio(false),cin.tie(NULL)
#define f_(i,m,n) for(ll i=m;i<n;i++)
#define x first
#define s second

ll get_sum(ll BIT[], ll index){
	ll sum=0;
	while(index>0){
		sum+=max(sum, BIT[index]);
		index-=index &(-index);
	}
	return sum;
}

void update(ll BIT[], ll index, ll n){
	ll x=get_sum(BIT, index-1);
	x++;
	while(index<=n){
		BIT[index]=max(BIT[index], x);
		index+=(index)&(-index);
	}
}

int main(){
	ll n;
	cin>>n;
	ll BIT[n+1];
	f_(i,0,n+1){
		BIT[i]=0;
	}

	vint v;
	v.pb(0);
	f_(i,1,n+1){
		ll a;
		cin>>a;
		update(BIT, arr[i], n);
		//v.pb(a);
		//if()
	}

	cout<<get_sum(BIT, n)<<endl;
	return 0;

}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define vpint vector<pair<pair<ll,ll>,ll>
#define vint vector<ll>
#define pb push_back
#define all(v) v.begin(),v.end()
#define ios cin.sync_with_stdio(false),cin.tie(NULL)
#define f_(i,m,n) for(ll i=m;i<n;i++)
#define x first
#define s second

ll get_sum(ll BIT[], ll index){
	ll sum=0;
	while(index>0){
		sum=max(sum, BIT[index]);
		index-=index &(-index);
	}
	return sum;
}

void update(ll BIT[], ll index, ll n){
	ll x=get_sum(BIT, index-1);
	x++;
	while(index<=n){
		BIT[index]=max(BIT[index], x);
		index+=(index)&(-index);
	}
}

int main(){
	ll n;
	cin>>n;
	ll BIT[n+1];
	f_(i,0,n+1){
		BIT[i]=0;
	}

	vint v;
	v.pb(0);
	f_(i,1,n+1){
		ll a;
		cin>>a;
		update(BIT, a, n);
		//v.pb(a);
		//if()
	}

	cout<<get_sum(BIT, n)<<endl;
	return 0;

}


#pragma GCC target ("avx2")
#pragma GCC optimization ("O3")
#pragma GCC optimization ("unroll-loops")
#include <iostream>
#include <bits/stdc++.h>
using namespace std;
#define ll long long
#define vpint vector<pair<pair<ll,ll>,ll>
#define vint vector<ll>
#define pb push_back
#define all(v) v.begin(),v.end()
#define ios cin.sync_with_stdio(false),cin.tie(NULL)
#define f_(i,m,n) for(ll i=m;i<n;i++)
#define x first
#define s second

ll get_sum(ll BIT[], ll index){
	ll sum=0;
	while(index>0){
		sum+=max(sum, BIT[index]);
		index-=index &(-index);
	}
	return sum;
}

void update(ll BIT[], ll index, ll n){
	ll x=get_sum(BIT, index-1);
	x++;
	while(index<=n){
		BIT[index]=max(BIT[index], x);
		index+=(index)&(-index);
	}
}

int main(){
	ll n;
	cin>>n;
	ll BIT[n+1];
	f_(i,0,n+1){
		BIT[i]=0;
	}

	vint v;
	v.pb(0);
	f_(i,1,n+1){
		ll a;
		cin>>a;
		update(BIT, a, n);
		//v.pb(a);
		//if()
	}

	cout<<get_sum(BIT, n)<<endl;
	return 0;

}


#pragma comment(linker, "/stack:20000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")

#include<bits/stdc++.h>
/*#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/detail/standard_policies.hpp>*/

#define sz(s) (int)(s.size())
#define all(s) s.begin(), s.end()
#define rep(a, b, c) for(int a = b; a <= c; ++a)
#define per(a, b, c) for(int a = b; a >= c; --a)
#define _ ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;
//using namespace __gnu_pbds;

typedef unsigned long long ull;
typedef long long ll;
/*typedef tree<pair<int, int>,
null_type, less<pair<int, int>>,
rb_tree_tag, tree_order_statistics_node_update>
ordered_set;*/
//find_by_order() order_of_key()

const double eps = 1e-7;
const int mod = 1e9+7, MXN = 5e5+17;
const int dx[] = {0,0,1,-1}, dy[] = {1,-1,0,0};

template<typename T>inline bool updmin(T &a, const T &b) {return a > b ? a = b,1 : 0;}
template<typename T>inline bool updmax(T &a, const T &b) {return a < b ? a = b,1 : 0;}

int n;
vector<int>s;

int32_t main() { _
#ifdef DanQQQQQ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	cin >> n;
	rep(i,1,n) {
		int x; cin >> x;
		auto it = lower_bound(all(s),x);
		if(it == s.end()) s.push_back(x);
		else *it = x;
	}
	cout << sz(s);
	return 0;
}


#pragma comment(linker, "/stack:20000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")

#include<bits/stdc++.h>
/*#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/detail/standard_policies.hpp>*/

#define sz(s) (int)(s.size())
#define all(s) s.begin(), s.end()
#define rep(a, b, c) for(int a = b; a <= c; ++a)
#define per(a, b, c) for(int a = b; a >= c; --a)
#define _ ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;
//using namespace __gnu_pbds;

typedef unsigned long long ull;
typedef long long ll;
/*typedef tree<pair<int, int>,
null_type, less<pair<int, int>>,
rb_tree_tag, tree_order_statistics_node_update>
ordered_set;*/
//find_by_order() order_of_key()

const double eps = 1e-7;
const int mod = 1e9+7, MXN = 5e5+17;
const int dx[] = {0,0,1,-1}, dy[] = {1,-1,0,0};

template<typename T>inline bool updmin(T &a, const T &b) {return a > b ? a = b,1 : 0;}
template<typename T>inline bool updmax(T &a, const T &b) {return a < b ? a = b,1 : 0;}

int n;
stack<int>s;

int32_t main() { _
#ifdef DanQQQQQ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	cin >> n;
	rep(i,1,n) {
		int x; cin >> x;
		while(sz(s) && s.top() < x)
			s.pop();
		s.push(x);
	}
	cout << sz(s);
	return 0;
}


#pragma comment(linker, "/stack:20000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")

#include<bits/stdc++.h>
/*#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/detail/standard_policies.hpp>*/

#define sz(s) (int)(s.size())
#define all(s) s.begin(), s.end()
#define rep(a, b, c) for(int a = b; a <= c; ++a)
#define per(a, b, c) for(int a = b; a >= c; --a)
#define _ ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;
//using namespace __gnu_pbds;

typedef unsigned long long ull;
typedef long long ll;
/*typedef tree<pair<int, int>,
null_type, less<pair<int, int>>,
rb_tree_tag, tree_order_statistics_node_update>
ordered_set;*/
//find_by_order() order_of_key()

const double eps = 1e-7;
const int mod = 1e9+7, MXN = 5e5+17;
const int dx[] = {0,0,1,-1}, dy[] = {1,-1,0,0};

template<typename T>inline bool updmin(T &a, const T &b) {return a > b ? a = b,1 : 0;}
template<typename T>inline bool updmax(T &a, const T &b) {return a < b ? a = b,1 : 0;}

int n;
stack<int>s;

int32_t main() { _
#ifdef DanQQQQQ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	cin >> n;
	rep(i,1,n) {
		int x; cin >> x;
		while(sz(s) && s.top() > x)
			s.pop();
		s.push(x);
	}
	cout << sz(s);
	return 0;
}


#pragma comment(linker, "/stack:20000000")
#pragma GCC optimize("Ofast")
#pragma GCC target("sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx")

#include<bits/stdc++.h>
/*#include<ext/pb_ds/assoc_container.hpp>
#include<ext/pb_ds/tree_policy.hpp>
#include<ext/pb_ds/detail/standard_policies.hpp>*/

#define sz(s) (int)(s.size())
#define all(s) s.begin(), s.end()
#define rep(a, b, c) for(int a = b; a <= c; ++a)
#define per(a, b, c) for(int a = b; a >= c; --a)
#define _ ios_base::sync_with_stdio(0);cin.tie(0);cout.tie(0);

using namespace std;
//using namespace __gnu_pbds;

typedef unsigned long long ull;
typedef long long ll;
/*typedef tree<pair<int, int>,
null_type, less<pair<int, int>>,
rb_tree_tag, tree_order_statistics_node_update>
ordered_set;*/
//find_by_order() order_of_key()

const double eps = 1e-7;
const int mod = 1e9+7, MXN = 5e5+17;
const int dx[] = {0,0,1,-1}, dy[] = {1,-1,0,0};

template<typename T>inline bool updmin(T &a, const T &b) {return a > b ? a = b,1 : 0;}
template<typename T>inline bool updmax(T &a, const T &b) {return a < b ? a = b,1 : 0;}

int n;
stack<int>s;

int32_t main() { _
#ifdef DanQQQQQ
	freopen(".in","r",stdin);
	freopen(".out","w",stdout);
#endif
	cin >> n;
	rep(i,1,n) {
		int x; cin >> x;
		while(sz(s) && s.top() >= x)
			s.pop();
		s.push(x);
	}
	cout << sz(s);
	return 0;
}


/*
 _____ _             _              _           _
|_   _| |__   ___   / \   _ __  ___| |__  _   _| |
  | | | '_ \ / _ \ / _ \ | '_ \/ __| '_ \| | | | |
  | | | | | |  __// ___ \| | | \__ \ | | | |_| | |
  |_| |_| |_|\___/_/   \_\_| |_|___/_| |_|\__,_|_|

*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll          long long
#define pb          push_back
#define ppb         pop_back
#define	endl		'\n'
#define mii         map<ll,ll>
#define msi         map<string,ll>
#define mis         map<ll, string>
#define rep(i,a,b)    for(ll i=a;i<b;i++)
#define repr(i,a,b) for(ll i=b-1;i>=a;i--)
#define trav(a, x) 	for(auto& a : x)
#define pii         pair<ll,ll>
#define vi          vector<ll>
#define vii         vector<pair<ll, ll>>
#define vs          vector<string>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll)x.size()
#define hell        1000000007
#define lbnd        lower_bound
#define ubnd        upper_bound
#define max(a,b)	(a>b?a:b)
#define min(a,b)	(a<b?a:b)

/*	For Debugging	*/
#define DEBUG 		cerr<<"/n>>>I'm Here<<</n"<<endl;
#define display(x) trav(a,x) cout<<a<<" ";cout<<endl;
#define what_is(x)  cerr << #x << " is " << x << endl;

std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define TIME        cerr << "\nTime elapsed: " << setprecision(5) <<1000.0 * clock() / CLOCKS_PER_SEC << "ms\n";
#define DECIMAL(n)  cout << fixed ; cout << setprecision(n);
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace __gnu_pbds;
using namespace std;
#define PI 3.141592653589793
#define N  100005
ll n,q;
vi a(N),seg(4*N),lazy(4*N);
void build(ll cur,ll st,ll end)
{
	if(st==end)
	{
		seg[cur]=-n-1;
		return;
	}
	ll mid=(st+end)>>1;
	build(2*cur,st,mid);
	build(2*cur+1,mid+1,end);
	seg[cur]=max(seg[2*cur],seg[2*cur+1]);					/* 1-change */
}
void updaterange(ll cur,ll st,ll end,ll l,ll r,ll val)
{
	if(lazy[cur]!=0)                                    /* 2-change */
	{
		seg[cur]+=lazy[cur];					/* 3-change */
		if(st!=end)
		{
			lazy[2*cur]+=lazy[cur];						/* 4-change */
			lazy[2*cur+1]+=lazy[cur];                   /* 5-change */
		}
		lazy[cur]=0;                                    /* 6-change */
	}
	if(st>end||st>r||end<l) return;
	if(l<=st&&end<=r)
	{
		seg[cur]+=val;					    /* 7-change */
		if(st!=end)
		{
			lazy[2*cur]+=val;                           /* 8-change */
			lazy[2*cur+1]+=val;                         /* 9-change */
		}
		return;
	}
	ll mid=(st+end)>>1;
	updaterange(2*cur,st,mid,l,r,val);
	updaterange(2*cur+1,mid+1,end,l,r,val);
	seg[cur]=max(seg[2*cur],seg[2*cur+1]);                  /* 10-change */
}
ll query(ll cur,ll st,ll end,ll l,ll r)
{
	if(st>end||st>r||end<l) return 0;
	if(lazy[cur]!=0)
	{
		seg[cur]+=lazy[cur];                /* 11-change */
		if(st!=end)
		{
			lazy[2*cur]+=lazy[cur];                    /* 12-change */
			lazy[2*cur+1]+=lazy[cur];                  /* 13-change */
		}
		lazy[cur]=0;
	}
	if(st>=l&&end<=r) return seg[cur];
	ll mid=(st+end)>>1;
	ll ans1=query(2*cur,st,mid,l,r);
	ll ans2=query(2*cur+1,mid+1,end,l,r);
	return max(ans1,ans2);                                 /* 14-change */
}
void solve()
{
	ll n;
	cin>>n;
	vi v(n);
	rep(i,0,n)
	{
		cin>>v[i];
	}
	build(1,1,n);
	rep(i,0,n)
	{
		ll vl=query(1,1,n,v[i],v[i]);
		updaterange(1,1,n,v[i],v[i],-vl);
		updaterange(1,1,n,1,v[i],1);
	}
	cout<<query(1,1,n,1,n);
	return;
}
int main()
{
	FAST
	int TESTS=1;
	#ifndef ONLINE_JUDGE
	freopen ("input.txt","r",stdin);
	// freopen("output.txt","w",stdout);
	#endif
//	cin>>TESTS;
	while(TESTS--)
	{
		solve();
	}
	TIME
	return 0;
}


/*
 _____ _             _              _           _
|_   _| |__   ___   / \   _ __  ___| |__  _   _| |
  | | | '_ \ / _ \ / _ \ | '_ \/ __| '_ \| | | | |
  | | | | | |  __// ___ \| | | \__ \ | | | |_| | |
  |_| |_| |_|\___/_/   \_\_| |_|___/_| |_|\__,_|_|

*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll          long long
#define pb          push_back
#define ppb         pop_back
#define	endl		'\n'
#define mii         map<ll,ll>
#define msi         map<string,ll>
#define mis         map<ll, string>
#define rep(i,a,b)    for(ll i=a;i<b;i++)
#define repr(i,a,b) for(ll i=b-1;i>=a;i--)
#define trav(a, x) 	for(auto& a : x)
#define pii         pair<ll,ll>
#define vi          vector<ll>
#define vii         vector<pair<ll, ll>>
#define vs          vector<string>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll)x.size()
#define hell        1000000007
#define lbnd        lower_bound
#define ubnd        upper_bound
#define max(a,b)	(a>b?a:b)
#define min(a,b)	(a<b?a:b)

/*	For Debugging	*/
#define DEBUG 		cerr<<"/n>>>I'm Here<<</n"<<endl;
#define display(x) trav(a,x) cout<<a<<" ";cout<<endl;
#define what_is(x)  cerr << #x << " is " << x << endl;

std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define TIME        cerr << "\nTime elapsed: " << setprecision(5) <<1000.0 * clock() / CLOCKS_PER_SEC << "ms\n";
#define DECIMAL(n)  cout << fixed ; cout << setprecision(n);
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace __gnu_pbds;
using namespace std;
#define PI 3.141592653589793
#define N  100005
vi tmp[N];

void solve()
{
	ll n;
	cin>>n;
	vi v(n);
	vi ps(n+1);
	rep(i,0,n)
	{
		cin>>v[i];
		ps[v[i]]=i;
	}
	sort(all(v));
	rep(i,0,n)
	{
		if(ps[v[i]]<=i)
		{
			// cout<<ps[v[i]]<<" "<<i<<endl;
			tmp[ps[v[i]]].pb(0);
			tmp[i].pb(1);
		}
		// else
		// {
		// 	tmp[i].pb(0);
		// 	tmp[ps[v[i]]].pb(1)
		// }
	}
	// if(sz(tmp)==0)
	rep(i,0,n)
		sort(all(tmp[i]));
	ll ans=0,cnt=0,cur=0;
	rep(i,0,n)
	{
		for(auto j:tmp[i])
		{
			if(j==0)
			{
				cnt++;
				if(cnt==1)
					cur=i;
			}
			else
			{
				cnt--;
				if(cnt==0)
				{
					ans+=(i-cur+2)/2;
					cur=-1;
				}
			}
		}
	}
	cout<<ans<<endl;
	return;
}
int main()
{
	FAST
	int TESTS=1;
//	cin>>TESTS;
	while(TESTS--)
	{
		solve();
	}
	TIME
	return 0;
}


/*
 _____ _             _              _           _
|_   _| |__   ___   / \   _ __  ___| |__  _   _| |
  | | | '_ \ / _ \ / _ \ | '_ \/ __| '_ \| | | | |
  | | | | | |  __// ___ \| | | \__ \ | | | |_| | |
  |_| |_| |_|\___/_/   \_\_| |_|___/_| |_|\__,_|_|

*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll          long long
#define pb          push_back
#define ppb         pop_back
#define	endl		'\n'
#define mii         map<ll,ll>
#define msi         map<string,ll>
#define mis         map<ll, string>
#define rep(i,a,b)    for(ll i=a;i<b;i++)
#define repr(i,a,b) for(ll i=b-1;i>=a;i--)
#define trav(a, x) 	for(auto& a : x)
#define pii         pair<ll,ll>
#define vi          vector<ll>
#define vii         vector<pair<ll, ll>>
#define vs          vector<string>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll)x.size()
#define hell        1000000007
#define lbnd        lower_bound
#define ubnd        upper_bound
#define max(a,b)	(a>b?a:b)
#define min(a,b)	(a<b?a:b)

/*	For Debugging	*/
#define DEBUG 		cerr<<"/n>>>I'm Here<<</n"<<endl;
#define display(x) trav(a,x) cout<<a<<" ";cout<<endl;
#define what_is(x)  cerr << #x << " is " << x << endl;

std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define TIME        cerr << "\nTime elapsed: " << setprecision(5) <<1000.0 * clock() / CLOCKS_PER_SEC << "ms\n";
#define DECIMAL(n)  cout << fixed ; cout << setprecision(n);
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace __gnu_pbds;
using namespace std;
#define PI 3.141592653589793
#define N  100005
ll n,l,r;
vi a(N),seg(4*N);
// void build(ll cur,ll st,ll end)
// {
// 	if(st==end)
// 	{
// 		seg[cur]=a[st];
// 		return;
// 	}
// 	ll mid=(st+end)>>1;
// 	build(2*cur,st,mid);
// 	build(2*cur+1,mid+1,end);
// 	seg[cur]=seg[2*cur]+seg[2*cur+1];	/*  1-change here  */
// }
ll query(ll cur,ll st,ll end,ll l,ll r)
{
	if(l<=st&&r>=end)
	return seg[cur];
	if(r<st||l>end)
	return 0;                           /*  2-change here  */
	ll mid=(st+end)>>1;
	ll ans1=query(2*cur,st,mid,l,r);
	ll ans2=query(2*cur+1,mid+1,end,l,r);
	return max(ans1,ans2);                 /*  3-change here  */
}
void update(ll cur,ll st,ll end,ll pos,ll upd)
{
	if(st==end)
	{
		seg[cur]=upd;					/*  5-change here  */
		return;
	}
	ll mid=(st+end)>>1;
	if(st<=pos&&pos<=mid)
		update(2*cur,st,mid,pos,upd);
	else
		update(2*cur+1,mid+1,end,pos,upd);
	seg[cur]=max(seg[2*cur],seg[2*cur+1]);	/*  6-change here  */
}
void solve()
{
	ll n;
	cin>>n;
	vi v(n);
	rep(i,0,n)
	{
		cin>>v[i];
	}
	// build(1,1,n);
	// rep(i,1,n+1)
	// {
	// 	cout<<query(1,1,n,i,i)<<" ";
	// }
	// cout<<endl;
	rep(i,0,n)
	{
		if(v[i]==1)
			update(1,1,n,1,1);
		else
			update(1,1,n,v[i],query(1,1,n,1,v[i]-1)+1);
	}
	cout<<query(1,1,n,1,n);
	return;
}
int main()
{
	FAST
	int TESTS=1;
	#ifndef ONLINE_JUDGE
	freopen ("input.txt","r",stdin);
	// freopen("output.txt","w",stdout);
	#endif
//	cin>>TESTS;
	while(TESTS--)
	{
		solve();
	}
	TIME
	return 0;
}


/*
 _____ _             _              _           _
|_   _| |__   ___   / \   _ __  ___| |__  _   _| |
  | | | '_ \ / _ \ / _ \ | '_ \/ __| '_ \| | | | |
  | | | | | |  __// ___ \| | | \__ \ | | | |_| | |
  |_| |_| |_|\___/_/   \_\_| |_|___/_| |_|\__,_|_|

*/
#include<bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp>
#include <ext/pb_ds/tree_policy.hpp>
#define ll          long long
#define pb          push_back
#define ppb         pop_back
#define	endl		'\n'
#define mii         map<ll,ll>
#define msi         map<string,ll>
#define mis         map<ll, string>
#define rep(i,a,b)    for(ll i=a;i<b;i++)
#define repr(i,a,b) for(ll i=b-1;i>=a;i--)
#define trav(a, x) 	for(auto& a : x)
#define pii         pair<ll,ll>
#define vi          vector<ll>
#define vii         vector<pair<ll, ll>>
#define vs          vector<string>
#define all(a)      (a).begin(),(a).end()
#define F           first
#define S           second
#define sz(x)       (ll)x.size()
#define hell        1000000007
#define lbnd        lower_bound
#define ubnd        upper_bound
#define max(a,b)	(a>b?a:b)
#define min(a,b)	(a<b?a:b)

/*	For Debugging	*/
#define DEBUG 		cerr<<"/n>>>I'm Here<<</n"<<endl;
#define display(x) trav(a,x) cout<<a<<" ";cout<<endl;
#define what_is(x)  cerr << #x << " is " << x << endl;

std::mt19937_64 rng(std::chrono::steady_clock::now().time_since_epoch().count());
#define ordered_set tree<ll, null_type,less<ll>, rb_tree_tag,tree_order_statistics_node_update>
#define TIME        cerr << "\nTime elapsed: " << setprecision(5) <<1000.0 * clock() / CLOCKS_PER_SEC << "ms\n";
#define DECIMAL(n)  cout << fixed ; cout << setprecision(n);
#define FAST ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace __gnu_pbds;
using namespace std;
#define PI 3.141592653589793
#define N  100005
ll dp[N];
void solve()
{
	ll n;
	cin>>n;
	vi v(n);
	rep(i,0,n)
	{
		cin>>v[i];
	}
	dp[0]=-hell;
	rep(i,1,n+1)
	dp[i]=hell;
	rep(i,0,n)
	{
		ll ps=ubnd(dp,dp+n+1,v[i])-dp;
		if(v[i]>dp[ps-1] && v[i]<dp[ps])
			dp[ps]=v[i];
	}
	repr(i,1,n+1)
	{
		if(dp[i]!=hell)
		{
			cout<<i<<endl;
			return;
		}
	}
	// cout<<query(1,1,n,1,n);
	return;
}
int main()
{
	FAST
	int TESTS=1;
	#ifndef ONLINE_JUDGE
	freopen ("input.txt","r",stdin);
	// freopen("output.txt","w",stdout);
	#endif
//	cin>>TESTS;
	while(TESTS--)
	{
		solve();
	}
	TIME
	return 0;
}


#include <bits/stdc++.h>
using namespace std;

#define ll long long
#define FOR(i, st, en) for (int i=st;i<=en;++i)
#define FORD(i, st, en) for (int i=st;i>=en;--i)
#define REP(i, st, en) for (int i=st;i<en;++i)
#define REPD(i, st, en) for (int i=st;i>en;--i)
#define maxn 100005

int n, a[maxn], st[4*maxn];
int ans[maxn], res;

void update(int id, int left, int right, int pos, int val) {
	if (pos < left || pos > right) return ;
	if (left == right) {
		st[id] = val;
		return ;
	}

	int mid = left+(right-left)/2;
	update(2*id, left, mid, pos, val);
	update(2*id+1, mid+1, right, pos, val);
	st[id] = max(st[2*id], st[2*id+1]);
}

int get(int id, int left, int right, int u, int v) {
	if (v < left || u > right) return 0;
	if (u <= left && right <= v) return st[id];

	int mid = left+(right-left)/2;
	return max(
		get(2*id, left, mid, u, v),
		get(2*id+1, mid+1, right, u, v)
	);
}

int main() {
	ios::sync_with_stdio(false);
	cin.tie(nullptr); cout.tie(nullptr);

	cin >> n;
	FOR(i, 1, n) cin >> a[i];
	FOR(i, 1, n) {
		ans[a[i]] = get(1, 1, n, 1, a[i]-1) + 1;
		update(1, 1, n, a[i], ans[a[i]]);
		res = max(res, ans[a[i]]);
	}
	cout << res << endl;
	return 0;
}