import std.algorithm;
import std.array;
import std.conv;
import std.math;
import std.range;
import std.stdio;
import std.string;
import std.typecons;
import std.exception;

void main() {
  int n;
  readf (" %d", &n);
  auto s = new int[n+1];
  immutable int all = (n * (n + 1)) / 2;
  foreach (i; 1 .. n) {
    s[i] = all - i;
  }
  debug stderr.writeln (s[1..n+1]);
  bool[int] block;
  //if (n & 1) {block[ 1 * (n + 1) + ((n + 1) >> 1)] = true;}
  {
    int i = 1, j = n;
    if (j & 1) --j;
    while (i < j) {
      block[ i * (n + 1) + j] = true;
      ++i;
      --j;
    }
  }
  Tuple!(int, int)[] t;
  void addEdge (int i, int j) {
    s[i] += j;
    s[j] += i;
    t ~= tuple (i, j);
  }
  s[] = 0;

  foreach (i; 1 .. n) {
    foreach (j; i+1 .. n + 1) {
      if (i * (n + 1) + j in block) continue;
      addEdge (i, j);
    }
  }
  debug stderr.writeln(s[1 .. n + 1]);
  writeln (t.length);
  foreach (const ref p; t) {
    writeln (p[0], ' ', p[1]);
  }
  foreach (i; 2 .. n + 1) {
    enforce (s[i] == s[i-1]);
  }
}

