#include <bits/stdc++.h>
using namespace std;
int i, j, k, m, n;
int pm[101000];
bool bo[101000];
map<int, int> t;
set<int> a[10000];
int p = 0;
int prime(int mx, int* pm) {
  int i, j, n = 0;
  memset(bo, 0, sizeof(bo));
  for (i = 2; i <= mx; i++) {
    if (!bo[i]) {
      pm[n++] = i;
      t[i] = n;
      a[n].insert(i);
    }
    for (j = 0; j < n && pm[j] * i <= mx; j++) {
      bo[i * pm[j]] = 1;
      a[t[pm[j]]].insert(i * pm[j]);
      if (i % pm[j] == 0) break;
    }
  }
  return n;
}
vector<int> ans;
set<int>::iterator it;
void add(int p) {
  for (it = a[p].begin(); it != a[p].end();) {
    int p1 = *it;
    if (++it == a[p].end()) break;
    int p2 = *it;
    it++;
    ans.push_back(p1);
    ans.push_back(p2);
  }
}
int main() {
  cin >> n;
  p = prime(n, pm);
  for (i = p; i >= 1; i--) {
    int sz = a[i].size();
    if (sz % 2 == 1) {
      int ok = 0;
      for (j = 1; j < i; j++) {
        if (n < pm[j - 1] * pm[i - 1]) break;
        it = a[j].lower_bound(pm[i - 1] * pm[j - 1]);
        if (it != a[j].end() && *it == pm[i - 1] * pm[j - 1]) {
          ok = *it;
          a[i].insert(ok);
          a[j].erase(ok);
          break;
        }
        if (ok) break;
      }
      add(i);
    } else
      add(i);
  }
  cout << ans.size() / 2 << endl;
  for (i = 0; i + 1 < ans.size(); i += 2)
    cout << ans[i] << " " << ans[i + 1] << endl;
  return 0;
}
