#include <bits/stdc++.h>
using namespace std;
int tot, n, prime[100010], tot2, vis[100010], a[100010], b[100010], cnt1, cnt2,
    tot3, notuse[100010];
bool use[100010];
struct node {
  int x, y;
} e[100010];
void init() {
  for (int i = 2; i <= n; i++) {
    if (!vis[i]) prime[++tot2] = i;
    for (int j = 1; j <= tot2; j++) {
      int t = prime[j] * i;
      if (t > n) break;
      vis[t] = 1;
      if (i % prime[j] == 0) break;
    }
  }
}
int main() {
  scanf("%d", &n);
  init();
  for (int i = 2; i <= tot2; i++) {
    memset(a, 0, sizeof(a));
    cnt1 = 0;
    a[++cnt1] = prime[i];
    for (int j = 3; j * prime[i] <= n; j++)
      if (!use[j * prime[i]]) a[++cnt1] = j * prime[i];
    if (2 * prime[i] <= n && !use[2 * prime[i]]) {
      if (cnt1 % 2 == 1)
        a[++cnt1] = 2 * prime[i];
      else {
        use[2 * prime[i]] = 1;
        notuse[++tot3] = 2 * prime[i];
      }
    }
    for (int j = 1; j + 1 <= cnt1; j += 2) {
      e[++tot].x = a[j];
      e[tot].y = a[j + 1];
      use[a[j]] = use[a[j + 1]] = 1;
    }
  }
  for (int i = 1; i * 2 <= n; i++)
    if (!use[i * 2]) notuse[++tot3] = i * 2;
  for (int i = 1; i + 1 <= tot3; i += 2) {
    e[++tot].x = notuse[i];
    e[tot].y = notuse[i + 1];
  }
  printf("%d\n", tot);
  for (int i = 1; i <= tot; i++) printf("%d %d\n", e[i].x, e[i].y);
  return 0;
}
