#include <bits/stdc++.h>
using namespace std;
vector<bool> prime(1000001, true);
void sieve(int n) {
  prime[0] = prime[1] = false;
  for (int i = 2; i <= n; i++)
    for (int j = i * i; j <= n && prime[i] && i * 1ll * i <= n; j += i)
      prime[j] = false;
}
bool vis[1000001];
int main() {
  ios::sync_with_stdio(0);
  cin.tie(0);
  ios_base::sync_with_stdio(0);
  sieve(1e6);
  int n, node = 1, N;
  vector<int> t;
  vector<pair<int, int>> ans;
  cin >> n;
  N = n;
  vector<pair<int, pair<int, int>>> v;
  while (n > 5) {
    ans.push_back({node, node + 1});
    ans.push_back({node, node + 2});
    ans.push_back({node + 1, node + 2});
    for (int i = node; i < node + 3; i++) t.push_back(i);
    node += 3;
    n -= 3;
  }
  if (n == 3) {
    vector<pair<int, int>> ve;
    v.push_back({node, {node + 1, node + 2}});
    for (int i = node; i < node + 3; i++) t.push_back(i);
    ans.push_back({node, node + 1});
    ans.push_back({node, node + 2});
    ans.push_back({node + 1, node + 2});
  } else if (n == 4) {
    ans.push_back({node, node + 1});
    ans.push_back({node + 1, node + 2});
    ans.push_back({node + 2, node + 3});
    ans.push_back({node + 3, node});
    ans.push_back({node, node + 2});
    t.push_back(node + 1);
    t.push_back(node + 3);
  } else {
    ans.push_back({node, node + 1});
    ans.push_back({node + 1, node + 2});
    ans.push_back({node + 2, node + 3});
    ans.push_back({node + 3, node + 4});
    ans.push_back({node + 4, node});
    ans.push_back({node + 1, node + 3});
    ans.push_back({node + 4, node + 2});
    t.push_back(node);
  }
  map<pair<int, int>, bool> mp;
  for (auto it : ans)
    mp[{it.first, it.second}] = mp[{it.second, it.first}] = true;
  int x = ans.size();
  while (!prime[x]) x++;
  x -= ans.size();
  int y = 0;
  if (x == 3) {
    for (int i = 0; i < 3; i++) {
      if (!mp[{t[i], t[x]}]) ans.push_back({t[i], t[x]});
    }
    if (!prime[ans.size()]) return cout << -1, 0;
    cout << ans.size() << endl;
    for (auto it : ans) cout << it.first << ' ' << it.second << endl;
    return 0;
  }
  while ((x > 0 || y < t.size()) && !prime[ans.size()]) {
    while (vis[y] && y < t.size()) y++;
    for (int i = y + 1; i < t.size(); i++) {
      if (!vis[i] && !mp[{t[i], t[y]}]) {
        mp[{t[i], t[y]}] = mp[{t[y], t[i]}] = vis[i] = vis[y] = true;
        ans.push_back({t[y], t[i]});
        break;
      }
    }
    x--;
  }
  if (!prime[ans.size()]) return cout << -1, 0;
  cout << ans.size() << endl;
  for (auto it : ans) cout << it.first << ' ' << it.second << endl;
  return 0;
}
