#include <bits/stdc++.h>
using namespace std;
bool is_prime[100000];
void gen_is_primes(int n);
void gen_prime_groups(int n, vector<bool>& to_match,
                      list<int>& candidate_primes,
                      list<pair<int, int> >& groups);
void gen_prime_groups(int n, int p, vector<bool>& to_match,
                      list<pair<int, int> >& groups);
void gen_unmatched_multiples(int n, int i, vector<bool>& to_match,
                             list<int>& unmatched_multiples);
void gen_even_groups(vector<bool>& to_match, list<pair<int, int> >& groups);
void gen_is_primes(int n) {
  fill_n(is_prime, n, true);
  is_prime[0] = false;
  is_prime[1] = false;
  for (int i = 2; i <= n / 2; i++) {
    if (is_prime[i]) {
      for (int j = 2 * i; j <= n; j += i) {
        is_prime[j] = false;
      }
    }
  }
}
void gen_prime_groups(int n, vector<bool>& to_match,
                      list<int>& candidate_primes,
                      list<pair<int, int> >& groups) {
  for (list<int>::iterator i = candidate_primes.begin();
       i != candidate_primes.end(); i++) {
    gen_prime_groups(n, *i, to_match, groups);
  }
}
void gen_prime_groups(int n, int p, vector<bool>& to_match,
                      list<pair<int, int> >& groups) {
  list<int>* unmatched_multiples = new list<int>();
  gen_unmatched_multiples(n, p, to_match, *unmatched_multiples);
  for (list<int>::iterator it = unmatched_multiples->begin();
       it != unmatched_multiples->end(); it++) {
    int curr = *it;
    int curr_partner = *(++it);
    to_match[curr] = false;
    to_match[curr_partner] = false;
    groups.push_back(make_pair(curr, curr_partner));
  }
  delete unmatched_multiples;
}
void gen_unmatched_multiples(int n, int i, vector<bool>& to_match,
                             list<int>& unmatched_multiples) {
  for (int curr_multiple = i; curr_multiple <= n; curr_multiple += i) {
    if (to_match[curr_multiple]) {
      unmatched_multiples.push_back(curr_multiple);
    }
  }
  if (unmatched_multiples.size() % 2 != 0) {
    unmatched_multiples.remove(2 * i);
  }
}
void gen_even_groups(vector<bool>& to_match, list<pair<int, int> >& groups) {
  list<int> unmatched;
  for (vector<bool>::iterator i = to_match.begin(); i != to_match.end(); i++) {
    if (*i) {
      int i_index = i - to_match.begin();
      unmatched.push_back(i_index);
    }
  }
  if (unmatched.size() % 2 != 0) {
    unmatched.erase(unmatched.begin());
  }
  for (list<int>::iterator i = unmatched.begin(); i != unmatched.end(); i++) {
    int curr = *i;
    int curr_partner = *(++i);
    groups.push_back(make_pair(curr, curr_partner));
  }
}
int main() {
  int n;
  cin >> n;
  gen_is_primes(n);
  vector<bool> to_match(n, false);
  for (int i = 2; i <= n; i++) {
    to_match[i] = !is_prime[i] || (i <= n / 2);
  }
  list<int>* candidate_primes = new list<int>;
  for (int i = n / 2; i >= 3; i--) {
    if (is_prime[i]) {
      candidate_primes->push_back(i);
    }
  }
  list<pair<int, int> >* groups = new list<pair<int, int> >;
  gen_prime_groups(n, to_match, *candidate_primes, *groups);
  gen_even_groups(to_match, *groups);
  cout << groups->size() << endl;
  for (list<pair<int, int> >::iterator it = groups->begin();
       it != groups->end(); it++) {
    cout << it->first << " " << it->second << endl;
  }
  delete groups;
  return 0;
}
