#include <bits/stdc++.h>
using namespace std;
int main() {
  int n;
  scanf("%d", &n);
  map<int, vector<int> > pos;
  set<pair<int, int> > info;
  int top = 0;
  for (int i = 0; i < n; i++) {
    int v = top++;
    info.insert(make_pair(1, v));
    pos[v].push_back(i);
  }
  vector<pair<int, int> > res;
  auto mergeSets = [&](int a, int b) {
    assert(a != b);
    int nset = top++;
    pos[nset] = vector<int>();
    vector<int>& va = pos[a];
    vector<int>& vb = pos[b];
    while (!va.empty() && !vb.empty()) {
      res.emplace_back(va.back(), vb.back());
      pos[nset].push_back(va.back());
      pos[nset].push_back(vb.back());
      va.pop_back();
      vb.pop_back();
    }
    return nset;
  };
  while (true) {
    vector<pair<int, int> > cur(info.rbegin(), info.rend());
    info.clear();
    int i = 0;
    bool any = false;
    while (i + 1 < cur.size()) {
      if (cur[i].first == cur[i + 1].first) {
        int nid = mergeSets(cur[i].second, cur[i + 1].second);
        info.insert(make_pair(pos[nid].size(), nid));
        i += 2;
        any = true;
      } else {
        info.insert(cur[i]);
        i++;
      }
    }
    while (i < cur.size()) info.insert(cur[i++]);
    if (!any) break;
  }
  pair<int, int> largest = *info.rbegin();
  info.erase(largest);
  while (info.size() > 1) {
    set<pair<int, int> >::iterator it = info.begin();
    pair<int, int> s1 = *it;
    it++;
    pair<int, int> s2 = *it;
    if (s1.first == s2.first) {
      info.erase(s1);
      info.erase(s2);
      int nid = mergeSets(s1.second, s2.second);
      info.insert(make_pair(pos[nid].size(), nid));
    } else {
      info.erase(s1);
      int nid = mergeSets(largest.second, s1.second);
      info.insert(make_pair(pos[nid].size(), nid));
    }
  }
  printf("%d\n", (int)res.size());
  for (int i = 0; i < res.size(); i++) {
    printf("%d %d\n", res[i].first + 1, res[i].second + 1);
  }
  return 0;
}
