All Euler problems
Project Euler

Largest Integer Divisible by Two Primes

For two distinct primes p and q, let M(p, q, N) be the largest positive integer <= N whose only prime factors are p and q (both must appear), or 0 if no such integer exists. Find sum M(p, q, 10^7)...

Source sync Apr 19, 2026
Problem #0347
Level Level 06
Solved By 5,238
Languages C++, Python
Answer 11109800204052
Length 252 words
number_theorylinear_algebrabrute_force

Problem Statement

This archive keeps the full statement, math, and original media on the page.

The largest integer \(\le 100\) that is only divisible by both the primes \(2\) and \(3\) is \(96\), as \(96=32\times 3=2^5 \times 3\). For two distinct primes \(p\) and \(q\) let \(M(p,q,N)\) be the largest positive integer \(\le N\) only divisible by both \(p\) and \(q\) and \(M(p,q,N)=0\) if such a positive integer does not exist.

E.g. \(M(2,3,100)=96\).

\(M(3,5,100)=75\) and not \(90\) because \(90\) is divisible by \(2\), \(3\) and \(5\).

Also \(M(2,73,100)=0\) because there does not exist a positive integer \(\le 100\) that is divisible by both \(2\) and \(73\).

Let \(S(N)\) be the sum of all distinct \(M(p,q,N)\). \(S(100)=2262\).

Find \(S(10\,000\,000)\).

Problem 347: Largest Integer Divisible by Two Primes

Mathematical Foundation

Theorem 1 (Structure of pp-qq-smooth numbers). The set of positive integers whose only prime factors are pp and qq is exactly {paqb:a0,b0}{1}\{p^a q^b : a \ge 0, b \ge 0\} \setminus \{1\}. The subset with both primes present is {paqb:a1,b1}\{p^a q^b : a \ge 1, b \ge 1\}.

Proof. By the fundamental theorem of arithmetic, the prime factorization of any integer in this set involves only pp and qq. Requiring both to appear forces a1a \ge 1 and b1b \ge 1. \square

Lemma 1 (Finite Enumeration). For fixed p<qp < q with pqNpq \le N, the number of integers paqbNp^a q^b \le N with a1,b1a \ge 1, b \ge 1 is at most logp(N)logq(N/p)\log_p(N) \cdot \log_q(N/p). For N=107N = 10^7, this is O(log2N)O(\log^2 N).

Proof. The exponent aa ranges from 1 to logp(N/q)\lfloor \log_p(N/q) \rfloor and for each aa, bb ranges from 1 to logq(N/pa)\lfloor \log_q(N/p^a) \rfloor. Both bounds are at most log2(N)23\log_2(N) \approx 23. \square

Theorem 2 (Correctness of Exhaustive Search). M(p,q,N)=max{paqb:a1,b1,paqbN}M(p,q,N) = \max\{p^a q^b : a \ge 1, b \ge 1, p^a q^b \le N\}, and this maximum is attained since the set is finite and non-empty (as pqNpq \le N).

Proof. The set {paqbN:a,b1}\{p^a q^b \le N : a,b \ge 1\} is non-empty because pqNpq \le N by hypothesis. It is finite because paqb2a+bp^a q^b \ge 2^{a+b} grows exponentially. A finite non-empty subset of Z\mathbb{Z} has a maximum. \square

Lemma 2 (Prime Pair Bound). The number of prime pairs (p,q)(p,q) with p<qp < q and pqNpq \le N is O(N/log2N)O(N / \log^2 N).

Proof. For each prime pp, the number of primes q(p,N/p]q \in (p, N/p] is O(N/(plogN))O(N/(p \log N)) by the prime number theorem. Summing over primes pNp \le \sqrt{N} gives O(N/log2N)O(N/\log^2 N). \square

Editorial

We but p * next_prime > N means no valid q. Finally, find max p^a * q^b <= N with a >= 1, b >= 1.

Pseudocode

but p * next_prime > N means no valid q
Find max p^a * q^b <= N with a >= 1, b >= 1
For this power_p = p^a, find max b

Complexity Analysis

  • Time: O ⁣(Nlog2Nlog2N)=O(N)O\!\left(\frac{N}{\log^2 N} \cdot \log^2 N\right) = O(N). There are O(N/log2N)O(N/\log^2 N) prime pairs, each requiring O(log2N)O(\log^2 N) work to enumerate powers.
  • Space: O(N)O(N) for the prime sieve.

Answer

11109800204052\boxed{11109800204052}

Code

Each problem page includes the exact C++ and Python source files from the local archive.

C++ project_euler/problem_347/solution.cpp
#include <bits/stdc++.h>
using namespace std;

int main() {
    const long long N = 10000000;

    // Sieve of Eratosthenes
    vector<bool> is_prime(N + 1, true);
    is_prime[0] = is_prime[1] = false;
    for (long long i = 2; i * i <= N; i++) {
        if (is_prime[i]) {
            for (long long j = i * i; j <= N; j += i)
                is_prime[j] = false;
        }
    }

    vector<long long> primes;
    for (long long i = 2; i <= N; i++) {
        if (is_prime[i]) primes.push_back(i);
    }

    long long total = 0;

    for (int i = 0; i < (int)primes.size(); i++) {
        long long p = primes[i];
        if (p * p > N) break; // p < q, so p*q > p*p

        for (int j = i + 1; j < (int)primes.size(); j++) {
            long long q = primes[j];
            if (p * q > N) break;

            long long best = 0;
            // Enumerate p^a * q^b with a>=1, b>=1
            long long pa = p;
            while (pa * q <= N) {
                long long val = pa * q;
                // Multiply by q as much as possible
                while (val * q <= N) val *= q;
                best = max(best, val);
                pa *= p;
            }

            total += best;
        }
    }

    cout << total << endl;
    return 0;
}