#include #include #include #include #include #include using namespace std; using ll = long long; // Pollard's Rho 法による素因数分解 ll gcd(ll a, ll b) { while (b) { ll t = a % b; a = b; b = t; } return a; } ll pollards_rho(ll n) { if (n % 2 == 0) return 2; random_device rd; mt19937 mt(rd()); uniform_int_distribution dist(1, n - 1); ll x = dist(mt); ll y = x; ll c = dist(mt); ll d = 1; while (d == 1) { x = ( (__int128_t(x) * x) % n + c ) % n; y = ( (__int128_t(y) * y) % n + c ) % n; y = ( (__int128_t(y) * y) % n + c ) % n; d = gcd(abs(x - y), n); if (d == n) return pollards_rho(n); } return d; } bool is_prime(ll n) { if (n <= 1) return false; if (n <= 3) return true; if (n%2 == 0 || n%3 == 0) return false; ll i = 5; while (i*i <= n) { if (n%i == 0 || n%(i+2) == 0) return false; i += 6; } return true; } void factorize(ll n, map &factors) { if (n == 1) return; if (n <= 1e6) { // エラトステネスの篩による素数判定 for (ll i = 2; i * i <= n; ++i) { int cnt = 0; while (n % i == 0) { n /= i; cnt++; } if (cnt > 0) factors[i] += cnt; } if (n > 1) factors[n]++; return; } if (is_prime(n)) { factors[n]++; return; } ll d = pollards_rho(n); factorize(d, factors); factorize(n / d, factors); } int main() { ll X; cin >> X; const int MAX_N = 200000; if (X == 1) { // 特別な場合 cout << -1 << endl; return 0; } map factors; factorize(X, factors); // 素因数を指数の降順で並べる vector> pf(factors.begin(), factors.end()); sort(pf.begin(), pf.end(), [](pair &a, pair &b) { return a.second > b.second; }); // 茶色の頂点数を決定(素因数の個数) int brown_nodes = 0; for (auto &p : pf) { brown_nodes += p.second; } if (brown_nodes + brown_nodes - 1 > MAX_N) { cout << -1 << endl; return 0; } int n = brown_nodes + brown_nodes - 1; // 茶色の頂点 + 緑色の頂点 cout << n << endl; // 茶色の頂点を線状に配置 int node_id = 1; vector brown_ids; for (int i = 0; i < brown_nodes; ++i) { brown_ids.push_back(node_id++); } // 辺の出力 for (int i = 0; i < (int)brown_ids.size() - 1; ++i) { cout << brown_ids[i] << " " << brown_ids[i+1] << endl; } // 緑色の頂点を茶色の頂点に接続 vector colors(n + 1); for (int i = 0; i < (int)pf.size(); ++i) { for (int j = 0; j < pf[i].second; ++j) { int brown_node = brown_ids.back(); brown_ids.pop_back(); colors[brown_node] = 'b'; for (int k = 0; k < pf[i].first - 1; ++k) { int green_node = node_id++; cout << brown_node << " " << green_node << endl; colors[green_node] = 'g'; } } } // 色の出力 for (int i = 1; i <= n; ++i) { if (i != 1) cout << " "; if (colors[i] == 'b') cout << 'b'; else cout << 'g'; } cout << endl; return 0; }