#include <bits/stdc++.h>
using namespace std;
using LL = long long;
const double PI = 2 * asin(1);
const double EPS = 1e-8;
const int INF = 0x3fffffff;
const int MX = 10000 + 10;
int g_n;
vector<int> vi_prime;
vector<bool> vb_prime, vb_num;
map<int, set<int>> misti_ans;
bool input() {
  cin >> g_n;
  if (cin.eof()) return false;
  vb_num.clear(), misti_ans.clear();
  vb_num.resize(g_n + 1);
  return true;
}
int get_prime(int n) {
  int prime_num = 0;
  vi_prime.clear();
  vb_prime.clear();
  vb_prime.resize(n + 1);
  fill(vb_prime.begin(), vb_prime.end(), true);
  vb_prime[0] = false, vb_prime[1] = false;
  for (int i = 2; i <= n; i++) {
    if (vb_prime[i]) {
      ++prime_num;
      vi_prime.push_back(i);
    }
    for (int j = 1; ((j <= prime_num) && (i * vi_prime[j - 1] <= n)); j++) {
      vb_prime[i * vi_prime[j - 1]] = false;
      if (i % vi_prime[j - 1] == 0) break;
    }
  }
  return prime_num;
}
void solve() {
  if (g_n <= 3) {
    puts("0");
    return;
  }
  int prime_num = get_prime(g_n);
  int pi;
  for (pi = prime_num - 1; pi >= 0; --pi) {
    if (g_n / vi_prime[pi] >= 2) break;
  }
  for (int i = pi; i >= 0; --i) {
    int k = vi_prime[i];
    for (int j = 1; k * j <= g_n; ++j) {
      if (!vb_num[k * j]) {
        vb_num[k * j] = true;
        misti_ans[k].emplace(k * j);
      }
    }
    if (misti_ans[k].size() % 2 != 0) {
      misti_ans[k].erase(k * 2);
      misti_ans[2].emplace(2 * k);
    }
  }
  if (misti_ans.find(2) != misti_ans.end() && misti_ans[2].size() % 2 != 0)
    misti_ans[2].erase(2);
  int ans = 0;
  for (int i = pi; i >= 0; --i) ans += misti_ans[vi_prime[i]].size() / 2;
  cout << ans << endl;
  for (int i = pi; i >= 0; --i) {
    int k = vi_prime[i];
    for (auto it = misti_ans[k].begin(); it != misti_ans[k].end(); ++it)
      printf("%d %d\n", *it, *(it++));
  }
}
int main() {
  while (input()) {
    solve();
  }
  return 0;
}
