#include <bits/stdc++.h>
using namespace std;
const int maxn = 2e5 + 7, inf = 0x3f3f3f3f, mod = 1e9 + 7;
bool notprime[maxn];
int prime[maxn];
int cnt;
void getprime() {
  notprime[0] = notprime[1] = 1;
  cnt = 0;
  for (int i = 2; i < maxn; ++i) {
    if (!notprime[i]) prime[cnt++] = i;
    for (int j = 0; j < cnt && 1ll * i * prime[j] < maxn; ++j) {
      notprime[i * prime[j]] = 1;
      if (i % prime[j] == 0) break;
    }
  }
}
int main() {
  ios::sync_with_stdio(false);
  cin.tie(0);
  getprime();
  int t;
  t = 1;
  while (t--) {
    int n;
    cin >> n;
    int num = 0;
    vector<int> vis(n + 1);
    vector<pair<int, int> > ans;
    for (int i = cnt - 1; i >= 0; --i) {
      if (prime[i] > n / 2) continue;
      vector<int> tmp;
      for (int j = prime[i]; j <= n; j += prime[i])
        if (!vis[j]) tmp.push_back(j);
      int sz = tmp.size();
      if (sz == 1)
        continue;
      else if (sz % 2 == 0) {
        for (int j = 0; j < sz; j += 2) {
          ans.push_back({tmp[j], tmp[j + 1]});
          vis[tmp[j]] = 1;
          vis[tmp[j + 1]] = 1;
        }
      } else if (sz % 2) {
        ans.push_back({tmp[0], tmp[2]});
        vis[tmp[0]] = 1, vis[tmp[2]] = 1;
        for (int j = 3; j < sz; j += 2) {
          ans.push_back({tmp[j], tmp[j + 1]});
          vis[tmp[j]] = 1;
          vis[tmp[j + 1]] = 1;
        }
      }
    }
    cout << ans.size() << '\n';
    for (auto &u : ans) cout << u.first << ' ' << u.second << '\n';
  }
  return 0;
}
