//  [swift]







import Foundation
let main: () = {
    var P = 2
    var S = Set<Int>(arrayLiteral: 1)
    var ans = 0
    var N = nextInt()
    while N != 1 && !N.isPrime {
        let p = P
        while true {
            var z = p
            while N.isMultiple(of: z) {
                S.insert(z)
                N = N / z
                ans += 1
                z *= p
            }
            break
        }
        P = P.nextPrime
    }
    if !S.contains(N) { ans += 1}
    print(ans)
}()




















//----------------------------------

let dx = [1, 0, -1, 0] //[1, 0, -1, 0, -1,  1, -1, 1]
let dy = [0, 1, 0, -1] //[0, 1, 0, -1, -1, -1,  1, 1]

@inlinable func gcd(_ a: Int, _ b: Int) -> Int { (b > 0) ? gcd(b, a % b) : a }
@inlinable func lcm(_ a: Int, _ b: Int) -> Int { a / gcd(a, b) * b }

//----------------------------------

infix operator  =~ : ComparisonPrecedence
infix operator !=~ : ComparisonPrecedence
func =~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: Range<T>) -> Bool { !(right ~= left) }
func =~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { right ~= left }
func !=~ <T: FixedWidthInteger>(left: T, right: ClosedRange<T>) -> Bool { !(right ~= left) }

func =~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { right.contains(left) }
func !=~ <T: Collection > (left: T.Element, right: T) -> Bool where T.Element : Equatable { !right.contains(left) }

infix operator /^ : MultiplicationPrecedence
infix operator /^= : AssignmentPrecedence
func /^ <T: FixedWidthInteger>(left: T, right: T) -> T { (left + (right - 1)) / right }
func /^= <T: FixedWidthInteger>(left: inout T, right: T) { left = (left + (right - 1)) / right }

@inlinable func chmax<T: Comparable>(_ m: inout T, _ q: T) { if (m < q) { m = q } }
@inlinable func chmin<T: Comparable>(_ m: inout T, _ q: T) { if (m > q) { m = q } }
@inlinable func chRmax<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m < q) { m = q; return true } else { return false } }
@inlinable func chRmin<T: Comparable>(_ m: inout T, _ q: T) -> Bool { if (m > q) { m = q; return true } else { return false } }

prefix operator *
prefix func * <T> (a: [T]) -> (T, T) { (a[0], a[1]) }
prefix func * <T> (a: [T]) -> (T, T, T) { (a[0], a[1], a[2]) }
prefix func * <T> (a: [T]) -> (T, T, T, T) { (a[0], a[1], a[2], a[3]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4]) }
prefix func * <T> (a: [T]) -> (T, T, T, T, T, T) { (a[0], a[1], a[2], a[3], a[4], a[5]) }

func printErr(_ str: String, terminator: String = "\n") {
    let s = str + terminator
    FileHandle.standardError.write(s.data(using: .utf8)!)
    FileHandle.standardError.synchronizeFile()
}

@inlinable func next() -> String { readLine()! }
@inlinable func nextInt() -> Int { Int(next())! }
@inlinable func nextDouble() -> Double { Double(next())! }
@inlinable func listOfString() -> [String] { next().split(separator: " ").map(String.init) }
@inlinable func listOfInt() -> [Int] { listOfString().map { Int($0)! } }
@inlinable func listOfInt(_ offset: Int = 0) -> [Int] { listOfString().map { Int($0)! + offset } }
@inlinable func listOfInt(_ offsets: Int ...) -> [Int] { listOfString().enumerated().map { Int($0.element)! + offsets[$0.offset % offsets.count] } }
@inlinable func listOfDouble(_ offset: Double = 0.0) -> [Double] { listOfString().map { Double($0)! + offset } }
@inlinable func listOfDouble(_ offsets: Double ...) -> [Double] { listOfString().enumerated().map { Double($0.element)! + offsets[$0.offset % offsets.count] } }

extension Int {
    init(s: String) { self.init(s)! }
    var isEven: Bool { self.isMultiple(of: 2) }
    var isOdd: Bool { !self.isEven }
    var isTrue: Bool { self != 0 }
    var isFalse: Bool { !self.isTrue }
    var toString: String { String(self) }
    var toChar: Character { Character(UnicodeScalar(UInt8(self))) }
}
func + (left: Int, right: Bool) -> Int { left + (right ? 1 : 0) }
extension Character {
    var asciiCode: Int { Int(self.asciiValue!) }
    var string: String { String(self) }
}
extension String {
    @inlinable subscript (position: Int) -> Character { self[self.index(self.startIndex, offsetBy: position)] }
    @inlinable func repeate(_ times: Int) -> String { String(repeating: self, count: times) }
    //  @inlinable subscript (n: Int) -> String { String(self[self.index(self.startIndex, offsetBy: n)]) }
    //  @inlinable subscript (n: Int) -> Int { Int(self[self.index(self.startIndex, offsetBy: n)].asciiValue!) }
    var toInt: Int { Int(self)! }
}
extension String { // VB like
    @inlinable func _index(_ position: Int) -> String.Index! {
        if !(0 ..< self.count ~= position) { return nil }
        return self.index(self.startIndex, offsetBy: position)
    }
    @inlinable func mid(from index: Int, length: Int) -> String! {
        if let startPosition = self._index(index) {
            if let endPosition = self._index(index + length - 1) {
                return String(self[startPosition...endPosition])
            } else {
                let endPosition = self.index(before: self.endIndex)
                return String(self[startPosition...endPosition])
            }
        }
        return ""
    }
    @inlinable func left(_ length: Int) -> String { String(self.prefix(length)) }
    @inlinable func right(_ length: Int) -> String { String(self.suffix(length)) }
}

extension Dictionary {
    @inlinable mutating func getOrSet(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored }
        else {
            let newValue = defaultValue()
            self[key] = newValue
            return newValue
        }
    }
    @inlinable mutating func getOrElse(_ key: Key, _ defaultValue: () -> Value) -> Value {
        if let stored = self[key] { return stored } else { return defaultValue() }
    }
    @inlinable func containsKey(_ key: Key) -> Bool { self.keys.contains(key) }
}

extension Set {
    static func += (left: inout Set<Element>, right: Element) { left.insert(right) }
    static func -= (left: inout Set<Element>, right: Element) { left.remove(right) }
}

extension Array {
    static func += (left: inout Array<Element>, right: Element) { left.append(right) }
    init(_ size: Int, _ initValue: ((Int) -> Element)) {
        self = [Element]()
        for index in 0 ..< size {
            let value = initValue(index)
            self.append(value)
        }
    }
    init(_ size: Int, _ initValue: (() -> Element)) {
        self = [Element]()
        for _ in 0 ..< size {
            let value = initValue()
            self.append(value)
        }
    }
}
typealias IntArray = Array<Int>
typealias DoubleArray = Array<Double>
typealias BoolArray = Array<Bool>
typealias StringArray = Array<String>

extension Array where Element == Int {
    init(_ size: Int) {
        self = [Element](repeating: 0, count: size)
    }
}
extension Array where Element == Double {
    init(_ size: Int) {
        self = [Element](repeating: 0.0, count: size)
    }
}
extension Array where Element == Bool {
    init(_ size: Int) {
        self = [Element](repeating: false, count: size)
    }
}
extension Array where Element == String {
    init(_ size: Int) {
        self = [Element](repeating: "", count: size)
    }
}

extension Array {
    @inlinable func count(_ predicate: ((Element) -> Bool)) -> Int {
        var cnt = 0; for e in self { if (predicate(e)) { cnt += 1 } }
        return cnt
    }
    @inlinable func groupBy<K>(_ keySelector: (Element) -> K) -> [K : [Element]] {
        var destination = [K : [Element]]()
        for element in self {
            let key = keySelector(element)
            var list = destination.getOrSet(key) { [Element]() }
            list.append(element)
            destination[key] = list
        }
        return destination
    }
    @inlinable func groupByIndexed<K>(_ keySelector: (Element) -> K) -> [K : [Int]] {
        var destination = [K : [Int]]()
        for element in self.enumerated() {
            let key = keySelector(element.element)
            var list = destination.getOrSet(key) { [Int]() }
            list.append(element.offset)
            destination[key] = list
        }
        return destination
    }
}

extension Array {
    func binarySearch(_ element: Element, by compare: (Element, Element) -> Int, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            let cmp = compare(midVal, element)
            if (cmp < 0) { low = mid + 1 }          //-1
            else if (0 < cmp) { high = mid - 1 }    // 1
            else { return mid } // key found        // 0
        }
        return -(low + 1)  // key not found
    }
}
extension Array where Element : Comparable {
    func binarySearch(_ element: Element, fromIndex: Int = 0, toIndex: Int = -1) -> Int {
        var low = fromIndex
        var high = (toIndex == -1) ? self.count - 1 : toIndex - 1
        while (low <= high) {
            let mid = (low + high) >> 1 // safe from overflows
            let midVal = self[mid]
            if (midVal < element) { low = mid + 1 }
            else if (midVal > element) { high = mid - 1 }
            else { return mid } // key found
        }
        return -(low + 1)  // key not found
    }
}

extension Array where Element == Int {
    @inlinable func distinct() -> [Element] {
        var set = Set<Element>(), ary = [Element]()
        for n in self.indices { if !set.contains(self[n]) { ary.append(self[n]); set.insert(self[n]) } }
        return ary
    }
    @inlinable func any(_ predicate: (Element) -> Bool) -> Bool {
        var any = false; for element in self { if predicate(element) { any = true } }
        return any
    }
    @inlinable func all(_ predicate: (Element) -> Bool) -> Bool {
        self.allSatisfy(predicate)
    }
    @inlinable func sum() -> Element { self.reduce(0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}

extension Array where Element == Double {
    @inlinable func sum() -> Element { self.reduce(0.0, +) }
    @inlinable func sum(by predicate: (Element) -> Element) -> Element {
        var sum = 0.0; for e in self { sum += predicate(e) }
        return sum
    }
    @inlinable func joinToString(_ sepatator: String = " ") -> String { self.map { String($0) }.joined(separator: sepatator) }
}
extension Array where Element == String {
    @inlinable func toIntDouble() -> (Int, Double) { (Int(self[0])!, Double(self[1])!) }
    @inlinable func toIntString() -> (Int, String) { (Int(self[0])!, self[1]) }
    @inlinable func toIntIntString() -> (Int, Int, String) { (Int(self[0])!, Int(self[1])!, self[2]) }
}

@inlinable func block( _ action: () -> Void) {
    action()
}
@inlinable func repeate(_ times1: Int, _ action: () -> Void) {
    for _ in 0 ..< times1 { action() }
}
@inlinable func repeate(_ times1: Int, _ action: (Int) -> Void) {
    for index1 in 0 ..< times1 {
        action(index1)
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ action: (Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            action(index1, index2)
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ action: (Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                action(index1, index2, index3)
            }
        }
    }
}
@inlinable func repeate(_ times1: Int, _ times2: Int, _ times3: Int, _ times4: Int, _ action: (Int, Int, Int, Int) -> Void) {
    for index1 in 0 ..< times1 {
        for index2 in 0 ..< times2 {
            for index3 in 0 ..< times3 {
                for index4 in 0 ..< times4 {
                    action(index1, index2, index3, index4)
                }
            }
        }
    }
}

func measureTimeSeconds(block: (() -> Void)) -> Double {
    let startTime = Date()
    block()
    let duration = -startTime.timeIntervalSinceNow
    return duration
}

public extension UInt64 {
    /// (x * y) mod m
    /// unlike naive x * y % m, this does not overflow.
    static func mulmod(_ x:UInt64, _ y:UInt64, _ m:UInt64)->UInt64 {
        if (m == 0) { fatalError("modulo by zero") }
        if (m == 1) { return 1 }
        if (m == 2) { return x & 1 }  // just odd or even
        var a = x % m;
        if a == 0 { return 0 }
        var b = y % m;
        if b == 0 { return 0 }
        var r:UInt64 = 0;
        while a > 0 {
            if a & 1 == 1 { r = (r &+ b) % m }
            a >>= 1
            b = (b << 1) % m
        }
        return r
        // return c_mulmod(a, b, m)
    }
}
public extension UInt {
    /// (x * y) mod m without worring about overflow.
    static func mulmod(_ x:UInt, _ y:UInt, _ m:UInt)->UInt {
        let (xy, overflow) = (x * y, false)  //.multiplyWithOverflow(x, y)
        return !overflow ?  xy % m : UInt(UInt64.mulmod(UInt64(x),UInt64(y),UInt64(m)))
    }
    /// (x ** y) mod m
    static func powmod(_ x:UInt, _ y:UInt, _ m:UInt)->UInt {
        if (m == 0) { fatalError("modulo by zero") }
        if (m == 1) { return 1 }
        if (m == 2) { return x & 1 }  // just odd or even
        var r:UInt = 1, t = x, n = y
        while n > 0 {
            if n & 1 == 1 { r = mulmod(r, t, m) }
            t = mulmod(t, t, m)
            n >>= 1
        }
        return r
    }
    /// Greatest Common Divisor
    static func gcd(_ m:UInt, _ n:UInt)->UInt {
        if n == 0 { return m }
        if m < n { return gcd(n, m) }
        let r = m % n
        return r == 0 ? n : gcd(n, r)
    }
    /// b ** x
    static func ipow(_ b:UInt, _ x:UInt)->UInt {
        var r:UInt = 1, t = b, n = x
        while n > 0 {   // &* is neccessary to avoid overflow exception
            if n & 1 == 1 {
                r = r &* t
            }
            n >>= 1; t = t &* t
        }
        return r
    }
    /// Integer Square Root of `n`
    static func isqrt(_ n:UInt)->UInt {
        var xk = UInt(sqrt(Double(n)))
        if xk <= 67108864 { return (xk)}  //sqrt(2^52)
        repeat {
            let xk1 = (xk + n / xk) / 2
            if xk1 >= xk { return xk }
            xk = xk1
        } while true
    }
    
    /// Integer Cube Root of `n`
    static func icbrt(_ n:UInt)->UInt {
        if n == 0 { return 0 }
        if n == 1 { return 1 }
        if n == 18446744073709551615 { return 2642245 }
        var xk = n
        repeat {
            let xk1 = (2*xk + n/xk/xk) / 3
            if xk1 >= xk { return xk }
            xk = xk1
        } while true
    }
}
public extension Int {
    /// (x * y) mod m without worring about overflow.
    static func mulmod(_ x:Int, _ y:Int, _ m:Int)->Int {
        let (ax, ay, am) = (abs(x),abs(y),abs(m))
        let sxy = 0 < x ? 0 < y ? 1 : -1 : 1
        return sxy * Int(UInt.mulmod(UInt(ax),UInt(ay),UInt(am)))
    }
    /// Greatest Common Divisor
    static func gcd(_ m:Int, _ n:Int)->Int {
        if m < 0 {
            return gcd(-m, n < 0 ? -n : n)
        }
        if n == 0 { return m }
        if m < n { return gcd(n, m) }
        let r = m % n
        return r == 0 ? n : gcd(n, r)
    }
    /// b ** x
    static func ipow(_ b:Int, _ n:Int)->Int {
        return Int(UInt.ipow(UInt(b), UInt(n)))
    }
    /// Integer Square Root of `n`
    static func isqrt(_ n:Int)->Int {
        return Int(UInt.isqrt(UInt(n)))
    }
}
public extension UInt {
    class Prime {
        public init(){}
        public func generate()->AnyIterator<UInt> {
            var currPrime:UInt = 0
            return AnyIterator {
                let nextPrime = currPrime.nextPrime
                if nextPrime > currPrime {
                    currPrime = nextPrime;
                    return currPrime
                }
                return nil
            }
        }
    }
}
public extension UInt.Prime {
    /// primes less than 2048
    static let tinyPrimes:[UInt] = {
        var ps:[UInt] = [2, 3]
        var n:UInt = 5
        while n < 2048 {
            for p in ps {
                if n % p == 0 { break }
                if p * p > n  { ps.append(n); break }
            }
            n += 2
        }
        return ps
    }()
    /// ### [A014233]
    ///
    /// Smallest odd number for which Miller-Rabin primality test
    /// on bases <= n-th prime does not reveal compositeness.
    ///
    /// [A014233]: https://oeis.org/A014233
    static let A014233:[UInt] = [
        2047,                   // p0   = 2
        1373653,                // p1   = 3
        25326001,               // p2   = 5
        3215031751,             // p3   = 7
        2152302898747,          // p4   = 11
        3474749660383,          // p5   = 13
        341550071728321,        // p6   = 17
        341550071728321,        // p7   = 19
        3825123056546413051,    // p8   = 23
        3825123056546413051,    // p9   = 29
        3825123056546413051,    // p10  = 31
        0                       // p11  = 37; 318665857834031151167461  > UInt.max
    ]
    /// [Miller-Rabin] test `n` for `base`
    ///
    /// [Miller-Rabin]: https://en.wikipedia.org/wiki/Miller%E2%80%93Rabin_primality_test
    class func millerRabinTest(_ n:UInt, base:UInt)->Bool {
        if n < 2      { return false }
        if n & 1 == 0 { return n == 2 }
        var d = n - 1
        while d & 1 == 0 { d >>= 1 }
        var t:UInt = d
        var y = UInt.powmod(base, t, n)
        while t != n-1 && y != 1 && y != n-1 {
            y = UInt.mulmod(y, y, n)
            t <<= 1
        }
        return y == n-1 || t & 1 == 1
    }
    class func isPrime(_ n:UInt)->Bool {
        if n < 2      { return false }
        if n & 1 == 0 { return n == 2 }
        if n % 3 == 0 { return n == 3 }
        if n % 5 == 0 { return n == 5 }
        if n % 7 == 0 { return n == 7 }
        for i in 0..<A014233.count {
            // print("millerRabinTest(\(n), base:\(smallPrimes[i]))")
            if millerRabinTest(n, base:tinyPrimes[i]) == false { return false }
            if n < A014233[i] { break }
        }
        return true
    }
    class func nextPrime(_ n:UInt)->UInt {
        if n < 2 { return 2 }
        var u = n
        u += u & 1 == 0 ? 1 : 2
        while !isPrime(u) { u += 2 }
        return u
    }
    class func prevPrime(_ n:UInt)->UInt {
        if n < 2 { return 2 }
        var u = n
        u -= u & 1 == 0 ? 1 : 2
        while !isPrime(u) { u -= 2 }
        return u
    }
    class func within(_ range:Range<UInt>)->[UInt] {
        var result = [UInt]()
        var p = range.startIndex
        if !p.isPrime { p = p.nextPrime }
        while p < range.endIndex {
            result.append(p)
            p = p.nextPrime
        }
        return result
    }
    /// Try to factor `n` by [Pollard's rho] algorithm
    ///
    /// [Pollard's rho]: https://en.wikipedia.org/wiki/Pollard%27s_rho_algorithm
    ///
    /// - parameter n: the number to factor
    /// - parameter l: the number of iterations
    /// - parameter c: seed
    class func pollardsRho(_ n:UInt, _ l:UInt, _ c:UInt)->UInt {
        //return UInt(c_pbrho(UInt64(n), UInt64(l), Int32(c)))
        var x:UInt = 2, y:UInt = 2, j:UInt = 2
        for i in 1...l {
            x = UInt.mulmod(x, x, n)
            x += c
            let d  = UInt.gcd(x < y ? y - x : x - y, n);
            if (d != 1) {
                return d == n ? 1 : d
            }
            if (i % j == 0) {
                y = x
                j += j
            }
        }
        return 1
    }
    // cf.
    //   http://en.wikipedia.org/wiki/Shanks'_square_forms_factorization
    //   https://github.com/danaj/Math-Prime-Util/blob/master/factor.c
    static let squfofMultipliers:[UInt] = [
        1,      3,      5,      7,      11,
        3*5,    3*7,    3*11,   5*7,    5*11,
        7*11,   3*5*7,  3*5*11, 3*7*11, 5*7*11, 3*5*7*11
    ]
    /// Try to factor `n` by [SQUFOF] = Shanks' Square Forms Factorization
    ///
    /// [SQUFOF]: http://en.wikipedia.org/wiki/Shanks'_square_forms_factorization
    class func squfof(_ n:UInt)->UInt {
        let ks = squfofMultipliers.filter{n < UInt(Int.max) / $0}.reversed()
        // print("ks=\(ks)")
        for k in ks {
            //            if UInt.multiplyWithOverflow(n, k).overflow { continue }
            //let g = UInt(c_squfof(UInt64(n), UInt64(k)))
            let g = squfof_one(n, k)
            // print("squof(\(n),\(k)) == \(g)")
            if g != 1 { return g }
        }
        return 1
    }
    class func squfof_one(_ n:UInt, _ k:UInt)->UInt {
        // print("n=\(n),k=\(k)")
        if n < 2      { return 1 }
        if n & 1 == 0 { return 2 }
        let rn = UInt.isqrt(n)
        if rn * rn == n { return rn }
        // if overflows just give up
        if n > UInt(Int.max) { return 1 }
        let kn = Int(k) &* Int(n)
        let rkn = Int.isqrt(kn)
        var p0 = rkn
        var q0 = 1
        var q1 = kn &- p0*p0
        var b0, b1, p1, q2 : Int
        for i in 0..<Int.isqrt(2 * rkn) {
            // print("Stage 1: p0=\(p0), q0=\(q0), q1=\(q1)")
            b1 = (rkn &+ p0) / q1
            p1 = b1 &* q1 &- p0
            q2 = q0 &+ b1 &* (p0 - p1)
            if i & 1 == 1 {
                let rq = Int.isqrt(q1)
                if rq * rq == q1 {
                    //  square root found; the algorithm cannot fail now.
                    b0 = (rkn &- p0) / rq
                    p0 = b0 &* rq &+ p0
                    q0 = rq
                    q1 = (kn &- p0*p0) / q0
                    while true {
                        // print("Stage 2: p0=\(p0), q0=\(q0), q1=\(q1)")
                        b1 = (rkn &+ p0) / q1
                        p1 = b1 &* q1 &- p0
                        q2 = q0 &+ b1 &* (p0 - p1)
                        if p0 == p1 {
                            return UInt.gcd(n, UInt(p1))
                        }
                        p0 = p1; q0 = q1; q1 = q2;
                    }
                }
            }
            p0 = p1; q0 = q1; q1 = q2
        }
        return 1
    }
    /// factor `u` and return prime facrors of it in array.
    ///
    /// axiom: `UInt.Prime.factor(u).reduce(1,*) == u` for any `u:UInt`
    ///
    /// It should succeed for all `u <= Int.max` but may fail for larger UInts.
    /// In which case `1` is prepended to the result so the axiom still holds.
    class func factor(_ u:UInt)->[UInt] {
        var n = u
        if n < 2 { return [n] }
        if isPrime(n) { return [n] }
        var result = [UInt]()
        for p in tinyPrimes[0..<83] {
            while n % p == 0 { result.append(p); n /= p }
            if n == 1 { return result }
        }
        if isPrime(n) { return result + [n] }
        if n < UInt(tinyPrimes.last! * tinyPrimes.last!) {
            for p in tinyPrimes[83..<tinyPrimes.count] {
                while n % p == 0 { result.append(p); n /= p }
                if n == 1 { return result }
            }
            if n != 1 { result.append(n) }
            return result
        }
        if isPrime(n) { return result + [n] }
        let l = Swift.min(UInt.isqrt(n), 0x1_0000)
        var d = pollardsRho(n, l, 1)
        if d == 1 {
            d = squfof(n)
        }
        result += d != 1 ? factor(d) + factor(n/d) : [1, n]
        result.sort(by: <)
        return result
    }
}
public extension UInt {
    /// true iff `self` is prime
    var isPrime:Bool { return Prime.isPrime(self) }
    /// the next prime number to `self`
    var nextPrime:UInt { return Prime.nextPrime(self) }
    /// the previous prime number from `self`
    var prevPrime:UInt { return Prime.prevPrime(self) }
    /// the prime factors of `self`
    ///
    /// axiom: `i.primeFactors.reduce(1,*) == i` for any `i:Int`
    ///
    /// for negative integers, `-1` is appended to keep axiom.
    var primeFactors:[UInt] { return Prime.factor(self) }
}
public extension Int {
    /// true iff `self` is prime
    var isPrime:Bool {
        return self < 2 ? false : UInt(self).isPrime
    }
    /// the next prime number to `self`
    var nextPrime:Int { return Int(UInt(self).nextPrime) }
    /// the previous prime number from `self`
    var prevPrime:Int { return Int(UInt(self).prevPrime) }
    /// the prime factors of `self`
    ///
    /// axiom: `u.primeFactors.reduce(1,*) == u` for any `u:UInt`
    ///
    /// It may fail for `u > UInt(Int.max)`.
    /// In which case `1` is prepended to the result.
    var primeFactors:[Int] {
        var result = UInt(abs(self)).primeFactors.map{ Int($0) }
        if self < 0 { result += [-1] }
        return result
    }
}
public extension Int {
    class Prime {
        public init(){}
        public func generate()->AnyIterator<Int> {
            var currPrime = 0
            return AnyIterator {
                if currPrime < 9223372036854775783 {
                    currPrime = currPrime.nextPrime
                    return currPrime
                }
                return nil
            }
        }
    }
}
public extension Int.Prime {
    class func within(_ range:Range<Int>)->[Int] {
        let start = UInt(Swift.max(range.startIndex, 0))
        let end   = UInt(range.endIndex)
        return UInt.Prime.within(start..<end).map{ Int($0) }
    }
}