function totients(limit) {
let sieve_limit = Math.floor(Math.sqrt(limit));
let spf = _.range(limit + 1).map((p) => (p % 2 == 0 ? 2 : p));
for (let p of _.range(3, sieve_limit + 1, 2)) {
for (let m of _.range(p * p, limit + 1, 2 * p)) {
if (spf[m] === m) {
spf[m] = p;
}
}
}
let phis = [0, 1];
for (let n of _.range(2, limit + 1)) {
if (spf[n] === n) {
phis.push(n - 1);
} else {
let p = spf[n];
let m = n / p;
let factor = spf[m] === p ? p : p - 1;
phis.push(phis[m] * factor);
}
}
return phis;
}