#include <bits/stdc++.h>
const long double eps = 1e-9;
using namespace std;
template <class T>
inline T MAX(const T &_a, const T &_b) {
  return ((_a > _b) ? _a : _b);
}
template <class T>
inline T MIN(const T &_a, const T &_b) {
  return ((_a < _b) ? _a : _b);
}
template <class T>
inline T MAX3(const T &_a, const T &_b, const T &_c) {
  return MAX(MAX(_a, _b), _c);
}
template <class T>
inline T MIN3(const T &_a, const T &_b, const T &_c) {
  return MIN(MIN(_a, _b), _c);
}
template <class T>
inline T MAX4(const T &_a, const T &_b, const T &_c, const T &_d) {
  return MAX(MAX3(_a, _b, _c), _d);
}
template <class T>
inline T MIN4(const T &_a, const T &_b, const T &_c, const T &_d) {
  return MIN(MIN3(_a, _b, _c), _d);
}
template <class T>
inline T ABS(const T &_a) {
  return ((_a < 0) ? -_a : _a);
}
template <class T>
inline T SQR(const T &_a) {
  return _a * _a;
}
template <class T>
inline T gcd(T _a, T _b) {
  for (T _r; (_r = _a % _b); _b = _r) _a = _b;
  return _b;
}
template <class T>
inline T lcm(const T &_a, const T &_b) {
  return (_a / gcd(_a, _b)) * _b;
}
template <class T>
inline bool BETW(const T &_a, const T &_b, const T &_c) {
  return (_a >= MIN(_b, _c) && _a <= MAX(_b, _c));
}
template <class T>
inline bool EXT(const T &_a, const T &_b, const T &_c) {
  return !BETW(_a, _b, _c);
}
const int MAXN = 100010;
int N;
bool used[MAXN];
vector<int> sieve[MAXN], tmp, primes;
vector<pair<int, int> > res;
int main() {
  long long i, j, k;
  scanf("%d", &N);
  if (N == 1) {
    puts("0");
    exit(0);
  }
  for (i = 2; i <= N; i++) {
    for (j = i; j <= N; j += i) sieve[i].push_back(j);
    if (!used[i]) {
      used[i] = true;
      primes.push_back(i);
      for (j = i * i; j <= N; j += i) used[j] = true;
    }
  }
  memset(used, 0, sizeof(used));
  for (k = primes.size() - 1; k >= 0; k--) {
    tmp.clear();
    j = 0;
    i = primes[k];
    for (; j < sieve[i].size(); j++)
      if (!used[sieve[i][j]]) tmp.push_back(sieve[i][j]);
    if (tmp.size() & 1) {
      j = 3;
      if (tmp.size() > 2) {
        used[tmp[0]] = used[tmp[2]] = true;
        res.push_back(make_pair(tmp[0], tmp[2]));
      }
    } else
      j = 0;
    for (; j < tmp.size(); j += 2) {
      used[tmp[j]] = used[tmp[j + 1]] = true;
      res.push_back(make_pair(tmp[j], tmp[j + 1]));
    }
  }
  printf("%d\n", res.size());
  for (i = 0; i < res.size(); i++)
    printf("%d %d\n", res[i].first, res[i].second);
  return 0;
}
