#include <bits/stdc++.h>
using namespace std;
const long long maxN = 1e5 + 100;
const long long maxM = 1e3 + 100;
const long long mod = 1e9 + 7;
const long long hmod = 1e16 + 7;
const long double PI = 3.141592653;
const long double eps = 1e-8;
const long long D = 1379;
const long long INF = 1e18 + 20;
const long long Inf = 1e9 + 140;
const long long SQ = 320;
const long long lg = 30;
void NO() {
  cout << "NO" << endl;
  exit(0);
}
void YES() {
  cout << "YES" << endl;
  exit(0);
}
long long n;
bool p[maxN], mark[maxN];
vector<long long> g[maxN], pr;
vector<pair<long long, long long> > ans;
void gharbal() {
  p[1] = true;
  for (long long i = 2; i <= n; i++)
    if (!p[i]) {
      pr.push_back(i);
      long long q = i + i;
      g[i].push_back(i);
      while (q <= n) {
        g[i].push_back(q);
        p[q] = true;
        q += i;
      }
    }
}
int main() {
  ios_base::sync_with_stdio(0);
  cin.tie(0);
  cout.tie(0);
  cin >> n;
  gharbal();
  for (long long i = ((int)(pr).size()) - 1; i >= 0; i--) {
    long long P = pr[i];
    vector<long long> v;
    for (long long i = 0; i <= ((int)(g[P]).size()) - 1; i++) {
      long long x = g[P][i];
      if (!mark[x]) v.push_back(x);
    }
    if (((int)(v).size()) % 2) {
      if (((int)(v).size()) < 2) continue;
      mark[v[0]] = mark[v[2]] = true;
      ans.push_back(make_pair(v[0], v[2]));
      for (long long i = 3; i <= ((int)(v).size()) - 1; i++) {
        mark[v[i + 0]] = mark[v[i + 1]] = true;
        ans.push_back(make_pair(v[i + 0], v[i + 1]));
        i++;
      }
    } else {
      for (long long i = 0; i <= ((int)(v).size()) - 1; i++) {
        mark[v[i + 0]] = mark[v[i + 1]] = true;
        ans.push_back(make_pair(v[i + 0], v[i + 1]));
        i++;
      }
    }
  }
  cout << ((int)(ans).size()) << endl;
  for (long long i = 0; i <= ((int)(ans).size()) - 1; i++)
    cout << ans[i].first << ' ' << ans[i].second << endl;
}
