#include <bits/stdc++.h>
using namespace std;
bool mark[100005] = {0};
bool used[100005] = {0};
vector<long long> prime;
void sieve(long long N) {
  for (long long i = (long long)(2); i <= (long long)(N); i++)
    if (!mark[i]) {
      prime.push_back(i);
      for (long long k = i * i; k <= N; k += i) mark[k] = 1;
    }
}
int main() {
  long long n;
  cin >> n;
  sieve(n);
  if (n == 1) return puts("0");
  prime.erase(prime.begin());
  long long ans = 0;
  vector<pair<long long, long long> > v;
  for (long long x : prime) {
    long long found = 1;
    list<long long> q;
    for (long long k = 2 * x; k <= n; k += x)
      if (!used[k]) q.push_back(k), found += 1;
    if (found % 2) {
      found -= 1;
      if (q.size() > 0) q.pop_front();
    }
    q.push_front(x);
    while (!q.empty()) {
      long long a = *q.begin();
      q.pop_front();
      if (q.empty()) break;
      long long b = *q.begin();
      q.pop_front();
      used[a] = used[b] = 1;
      v.push_back(make_pair(a, b));
    }
    used[x] = 1;
    ans += found / 2;
  }
  long long c = 0;
  vector<long long> left;
  for (long long i = (long long)(2); i <= (long long)(n); i++)
    if (!used[i]) c++, left.push_back(i);
  for (long long i = 0; i < c; i += 2)
    if (i + 1 < c) v.push_back(make_pair(left[i], left[i + 1]));
  cout << v.size() << '\n';
  for (auto p : v) cout << p.first << ' ' << p.second << '\n';
}
