#include"testlib.h"
#include<bits/stdc++.h>
#define all(v) v.begin(), v.end()
 
using namespace std;
 
struct Dsu {
int n;
vector <int> par, cnt;
Dsu (int n_) {
    n = n_;
    par.resize(n + 1);
    cnt.resize(n + 1, 1);
    iota(all(par), 0);
}   
int root(int u) {
    if (par[u] == u) {
        return u;
    }
    else {
        return par[u] = root(par[u]);                
    }
}   
void mergefast(int u, int v) {
    if (cnt[v] < cnt[u]) {
        swap(u, v);
    }
    par[u] = v;
    cnt[v] += cnt[u];
}
bool merge(int u, int v) {
    u = root(u);
    v = root(v);
    if (u == v) {
        return 0;
    }
    if (cnt[v] < cnt[u]) {
        swap(u, v);
    }
    par[u] = v;
    cnt[v] += cnt[u];
    return 1;
}
};  
 
int32_t main(int argc, char *argv[]) {
    registerGen(argc, argv, 1);
    int T = opt<int>(1);
    int id = opt<int>(2);
 
    vector<pair<int, vector<pair<int, int>>>> tests;
    int cc = 0;
    for (int n = 2; n <= 6; n++) {
      for (int t = 0; t < (1 << (n * (n - 1) / 2)); t++) {
        Dsu d(n);
        vector<pair<int, int>> edges;
        int ptr = 0;
        int comps = n;
        for (int i = 0; i < n; i++) {
          for (int j = i + 1; j < n; j++) {
            if (t & (1 << ptr)) {
              int x = i, y = j;
              if (rnd.next(0, 1) == 0) swap(x, y);
              edges.emplace_back(x, y);
              comps -= d.merge(i, j);
            }
            ptr += 1;
          }
        }
        if (comps == 1) {
          tests.emplace_back(n, edges);
        }
      }
    }

    tests.erase(tests.begin(), tests.begin() + id * T);
    tests.resize(min(int(tests.size()), T));
    cout << tests.size() << '\n';
    for (auto& [n, edges] : tests) {
      shuffle(edges.begin(), edges.end());
      cout << n << " " << edges.size() << '\n';
      for (auto& [x, y] : edges) {
        cout << x + 1 << " " << y + 1 << '\n';
      }
    }
    return 0;
 
}
