#include <bits/stdc++.h>
using namespace std;
void fre() {
  freopen("c://test//input.in", "r", stdin);
  freopen("c://test//output.out", "w", stdout);
}
template <class T1, class T2>
inline void gmax(T1 &a, T2 b) {
  if (b > a) a = b;
}
template <class T1, class T2>
inline void gmin(T1 &a, T2 b) {
  if (b < a) a = b;
}
const int N = 0, M = 0, Z = 1e9 + 7, ms63 = 0x3f3f3f3f;
int casenum, casei;
const int TOP = 1e5;
int p[TOP + 10], pnum;
bool e[TOP + 10];
vector<int> two, tmp;
vector<pair<int, int> > ans;
int n;
void Prime_Init() {
  ans.clear();
  two.clear();
  for (int i = 2; i <= n; ++i)
    if (e[i] == 0) {
      p[++pnum] = i;
      tmp.clear();
      for (int j = i; j <= n; j += i)
        if (e[j] == 0) e[j] = 1;
    }
  for (int i = pnum; i >= 1; --i) {
    tmp.clear();
    for (int j = p[i]; j <= n; j += p[i])
      if (e[j] == 1) {
        e[j] = 0;
        tmp.push_back(j);
      }
    if (tmp.size() == 1)
      continue;
    else if (tmp.size() & 1) {
      two.push_back(tmp[1]);
      ans.push_back(make_pair(tmp[0], tmp[2]));
      for (int j = 3; j < tmp.size(); j += 2) {
        ans.push_back(make_pair(tmp[j], tmp[j + 1]));
      }
    } else {
      for (int j = 0; j < tmp.size(); j += 2) {
        ans.push_back(make_pair(tmp[j], tmp[j + 1]));
      }
    }
  }
  int sz = two.size();
  for (int i = 0; i <= sz - 2; i += 2) {
    ans.push_back(make_pair(two[i], two[i + 1]));
  }
  printf("%d\n", ans.size());
  for (int i = 0; i < ans.size(); ++i) {
    printf("%d %d\n", ans[i].first, ans[i].second);
  }
}
int main() {
  while (~scanf("%d", &n)) {
    Prime_Init();
  }
  return 0;
}
