#include using namespace std; int N, M, K; vector> keep; void print_no() { cout << "No\n"; } void print_yes() { cout << "Yes\n"; for (int u = 1; u <= N; ++u) { for (int v = u + 1; v <= N; ++v) { if (!keep[u][v]) { cout << u << ' ' << v << '\n'; } } } } int main() { cin >> N >> M >> K; int T = N * (N - 1) / 2; int E = T - M; // number of edges to keep keep.assign(N + 1, vector(N + 1, false)); // Very rough feasibility check. if (E <= 0) { print_no(); return 0; } // WRONG IDEA: // Split vertices 2..N-1 into about (K-1)/2 layers, // then make each layer a clique. int L = max(1, (K - 1) / 2); vector> layer(L); for (int v = 2; v <= N - 1; ++v) { int id = (v - 2) % L; layer[id].push_back(v); } // Connect 1 to the first layer. for (int v : layer[0]) { keep[1][v] = true; } // Connect N to the last layer. for (int v : layer[L - 1]) { int a = min(v, N); int b = max(v, N); keep[a][b] = true; } // Make each layer a complete graph. // This is suspicious because edges inside a layer do not necessarily help create distance K, // and may create many unintended short paths. for (int i = 0; i < L; ++i) { for (int a = 0; a < (int)layer[i].size(); ++a) { for (int b = a + 1; b < (int)layer[i].size(); ++b) { int u = layer[i][a]; int v = layer[i][b]; if (u > v) swap(u, v); keep[u][v] = true; } } } // Connect consecutive layers completely. // This also does not correspond to the correct shortest-distance construction. for (int i = 0; i + 1 < L; ++i) { for (int u : layer[i]) { for (int v : layer[i + 1]) { if (u > v) swap(u, v); keep[u][v] = true; } } } // If K is odd/even, try to adjust by adding direct-ish edges. // This is arbitrary and wrong. if (K % 2 == 0 && L > 0) { for (int v : layer[0]) { int u = min(1, v); int w = max(1, v); keep[u][w] = true; } } // Count kept edges. vector> kept_edges; vector> not_kept_edges; for (int u = 1; u <= N; ++u) { for (int v = u + 1; v <= N; ++v) { if (keep[u][v]) kept_edges.push_back({u, v}); else not_kept_edges.push_back({u, v}); } } // If too many edges are kept, remove arbitrary kept edges. // This may destroy the intended connection. while ((int)kept_edges.size() > E) { auto [u, v] = kept_edges.back(); kept_edges.pop_back(); keep[u][v] = false; } // If too few edges are kept, add arbitrary missing edges. // This may create a shortcut and make the shortest distance smaller than K. int ptr = 0; while ((int)kept_edges.size() < E && ptr < (int)not_kept_edges.size()) { auto [u, v] = not_kept_edges[ptr++]; keep[u][v] = true; kept_edges.push_back({u, v}); } if ((int)kept_edges.size() != E) { print_no(); return 0; } // WRONG: // Does not verify that dist(1,N) is exactly K. print_yes(); return 0; }