#include <bits/stdc++.h>
using namespace std;
inline void readInt(int &x) {
  int neg = 1;
  char ch;
  while (!isdigit(ch = getchar())) {
    if (ch == '-') {
      neg = -1;
    }
  }
  x = ch - '0';
  while (isdigit(ch = getchar())) {
    x = x * 10 + ch - '0';
  }
  x *= neg;
}
int N;
vector<bool> visited;
vector<bool> isprime;
vector<pair<int, int> > groups;
vector<int> rejected;
void solve(int X);
int main() {
  int i, j;
  readInt(N);
  isprime.resize(N + 1, true);
  visited.resize(N + 1);
  for (i = 2; i <= (N >> 1); ++i) {
    if (isprime[i]) {
      for (j = i << 1; j <= (N >> 1); j += i) {
        isprime[j] = false;
      }
    }
  }
  for (i = N >> 1; i > 1; --i) {
    if (isprime[i]) {
      solve(i);
    }
  }
  for (i = rejected.size() - 1; i > 0; i -= 2) {
    groups.push_back(make_pair(rejected[i], rejected[i - 1]));
  }
  printf("%d\n", (int)groups.size());
  for (auto x : groups) {
    printf("%d %d\n", x.first, x.second);
  }
  return 0;
}
void solve(int X) {
  int i, aux = 0;
  for (i = X * 3; i <= N; i += X) {
    if (!visited[i]) {
      if (aux == 0) {
        aux = i;
      } else {
        visited[aux] = visited[i] = true;
        groups.push_back(make_pair(aux, i));
        aux = 0;
      }
    }
  }
  visited[X] = visited[aux] = visited[X << 1] = true;
  if (aux != 0) {
    groups.push_back(make_pair(X, aux));
    rejected.push_back(X << 1);
  } else {
    groups.push_back(make_pair(X, X << 1));
  }
}
