#include <bits/stdc++.h>
using namespace std;
inline int rei() {
  int x;
  cin >> x;
  return x;
}
inline long long rel() {
  long long x;
  cin >> x;
  return x;
}
inline string res() {
  string x;
  cin >> x;
  return x;
}
struct PrimeFactor {
  vector<int> LowestPrimeFactor;
  vector<int> Prime;
  int N;
  PrimeFactor(int N0) : LowestPrimeFactor(N0 + 1) {
    N = N0;
    N++;
    LowestPrimeFactor.resize(N);
    for (int i = 1; i < N; i++) {
      LowestPrimeFactor[i] = i;
    }
    for (int i = 2; i < N; i++) {
      if (LowestPrimeFactor[i] == i) {
        Prime.push_back(i);
      }
      for (int j = 0; j < Prime.size(); j++) {
        if (Prime[j] * i < N && Prime[j] <= LowestPrimeFactor[i]) {
          LowestPrimeFactor[Prime[j] * i] = Prime[j];
        } else {
          break;
        }
      }
    }
  }
  vector<int> PrimeDivide(int X) {
    vector<int> ans;
    while (X != 1) {
      ans.push_back(LowestPrimeFactor[X]);
      X /= LowestPrimeFactor[X];
    }
    return ans;
  }
  vector<long long> PrimeDivide(long long X0) {
    vector<long long> ans;
    int X = (int)X0;
    int i = 0;
    while (X >= N) {
      if (X % Prime[i] == 0) {
        ans.push_back(Prime[i]);
        X /= Prime[i];
      } else {
        i++;
        if (i == Prime.size() || 1LL * Prime[i] * Prime[i] > X) {
          ans.push_back(X);
          X = 1;
        }
      }
    }
    while (X != 1) {
      ans.push_back(LowestPrimeFactor[X]);
      X /= LowestPrimeFactor[X];
    }
    return ans;
  }
  vector<int> Divisor(int X) {
    vector<int> ans;
    ans.push_back(1);
    while (X != 1) {
      int p = LowestPrimeFactor[X];
      int c = 0;
      while (X % p == 0) {
        X /= p;
        c++;
      }
      int l = ans.size();
      int d = p;
      for (int i = 1; i <= c; i++) {
        for (int j = 0; j < l; j++) {
          ans.push_back(d * ans[j]);
        }
        d *= p;
      }
    }
    return ans;
  }
  vector<long long> Divisor(long long X0) {
    vector<long long> ans;
    int X = (int)X0;
    ans.push_back(1);
    int i = 0;
    while (X >= N) {
      if (X % Prime[i] == 0) {
        int p = Prime[i];
        int c = 0;
        while (X % p == 0) {
          X /= p;
          c++;
        }
        int l = ans.size();
        int d = p;
        for (int k = 1; k <= c; k++) {
          for (int j = 0; j < l; j++) {
            ans.push_back(d * ans[j]);
          }
          d *= p;
        }
      } else {
        i++;
        if (i == Prime.size() || 1LL * Prime[i] * Prime[i] > X) {
          int l = ans.size();
          for (int j = 0; j < l; j++) {
            ans.push_back(X * ans[j]);
          }
          X = 1;
        }
      }
    }
    while (X != 1) {
      int p = LowestPrimeFactor[X];
      int c = 0;
      while (X % p == 0) {
        X /= p;
        c++;
      }
      int l = ans.size();
      int d = p;
      for (int k = 1; k <= c; k++) {
        for (int j = 0; j < l; j++) {
          ans.push_back(d * ans[j]);
        }
        d *= p;
      }
    }
    return ans;
  }
  int Phi(int X) {
    int ans = X;
    while (X != 1) {
      int p = LowestPrimeFactor[X];
      while (X % p == 0) {
        X /= p;
      }
      ans /= p;
      ans *= p - 1;
    }
    return ans;
  }
  long long Phi(long long X0) {
    int ans = (int)X0;
    int X = (int)X0;
    int i = 0;
    while (X >= N) {
      if (X % Prime[i] == 0) {
        int p = Prime[i];
        while (X % p == 0) {
          X /= p;
        }
        ans /= p;
        ans *= p - 1;
      } else {
        i++;
        if (i == Prime.size() || 1LL * Prime[i] * Prime[i] > X) {
          int p = X;
          ans /= p;
          ans *= p - 1;
          X = 1;
        }
      }
    }
    while (X != 1) {
      int p = LowestPrimeFactor[X];
      while (X % p == 0) {
        X /= p;
      }
      ans /= p;
      ans *= p - 1;
    }
    return ans;
  }
};
bool used[100001];
void Calc() {
  int N = rei();
  PrimeFactor PF(N);
  vector<pair<int, int>> ans;
  for (int i = PF.Prime.size() - 1; i > 0; i--) {
    int pr = PF.Prime[i];
    if (pr * 2 > N) {
      continue;
    }
    int before = pr;
    for (int i = 3; i * pr <= N; i++) {
      if (used[i * pr]) {
        continue;
      }
      if (before == 0) {
        before = i * pr;
        used[i * pr] = true;
      } else {
        ans.push_back({i * pr, before});
        used[i * pr] = true;
        before = 0;
      }
    }
    if (before != 0) {
      ans.push_back({before, pr * 2});
      used[2 * pr] = true;
    }
  }
  {
    int before = 0;
    for (int i = 2; i <= N; i += 2) {
      if (!used[i]) {
        if (before == 0) {
          before = i;
        } else {
          ans.push_back({before, i});
          before = 0;
        }
      }
    }
  }
  cout << ans.size() << '\n';
  for (pair<int, int> X : ans) {
    cout << X.first << " " << X.second << endl;
  }
}
int main(int argc, char** argv) {
  ios::sync_with_stdio(false), cin.tie(0);
  cout.tie(0);
  Calc();
  return 0;
}
