#include <bits/stdc++.h>
#pragma GCC optimize("Ofast")
#pragma GCC target( \
    "avx,avx2,fma,sse,sse2,sse3,ssse3,sse4,popcnt,abm,mmx,avx,tune=native")
using namespace std;
long long MOD = 1e9 + 7;
const int N = 2000000;
long long a[N];
vector<bool> prime;
void pr(long long n) {
  prime.resize(n + 1, true);
  prime[0] = prime[1] = false;
  for (int i = 2; i <= n; ++i)
    if (prime[i])
      if (i * 1ll * i <= n)
        for (int j = i * i; j <= n; j += i) prime[j] = false;
}
vector<long long> gr[N];
int main() {
  ios::sync_with_stdio(0), cin.tie(0), cout.tie(0),
      cout << fixed << setprecision(20);
  long long n;
  cin >> n;
  pr(2 * n);
  vector<long long> mems;
  for (int i = 2; i <= n; i++) {
    if (prime[i]) {
      if (2 * i <= n) {
        for (int j = i; j <= n; j += i) {
          a[j] = max(a[j], (long long)i);
        }
      }
    }
  }
  vector<pair<long long, long long> > ans;
  for (int i = 2; i <= n; i++) {
    gr[a[i]].push_back(i);
  }
  for (int i = 2; i <= n; i++) {
    if (gr[i].size() > 1) {
      if (gr[i].size() % 2 == 0) {
        for (int j = 0; j < gr[i].size() - 1; j += 2) {
          ans.push_back({gr[i][j], gr[i][j + 1]});
        }
      } else {
        vector<long long> pis;
        for (auto j : gr[i]) {
          if (j != 2 * i) {
            pis.push_back(j);
          }
        }
        for (int j = 0; j < pis.size() - 1; j += 2) {
          ans.push_back({pis[j], pis[j + 1]});
        }
        mems.push_back(2 * i);
      }
    }
  }
  if (mems.size() > 1) {
    for (int i = 0; i < mems.size() - 1; i += 2) {
      ans.push_back({mems[i], mems[i + 1]});
    }
  }
  cout << ans.size() << endl;
  for (auto i : ans) {
    cout << i.first << " " << i.second << "\n";
  }
}
