function totients(limit) {
let sieveLimit = Math.sqrt(limit);
let spf = _.range(0, limit).map((p) => (p % 2 === 0 ? 2 : p));
for (let p of _.range(3, sieveLimit, 2)) {
for (let m of _.range(p**2, limit, 2 * p)) {
if (spf[m] === m) {
spf[m] = p;
}
}
}
let phis = [0, 1];
for (let n of _.range(2, limit)) {
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;
}