• 🏆 Texturing Contest #33 is OPEN! Contestants must re-texture a SD unit model found in-game (Warcraft 3 Classic), recreating the unit into a peaceful NPC version. 🔗Click here to enter!
  • It's time for the first HD Modeling Contest of 2024. Join the theme discussion for Hive's HD Modeling Contest #6! Click here to post your idea!

Advanced Maths & Ingame Calculator

Advanced Mathematics & Ingame Calculator
vJass Version 1.2.0.0


mathheaderkopie.png

1. Introduction

This is a math library designed to provide advanced mathematic functions and functionalities that are not supported by the World Editor. Mathematics are important for various things like calculating a units armor, physic systems with kinematics or differential equations, movement, artificial intelligence, statistics for balancing and many more. Therefore it is quite annoying that the World Editor lacks of many important math functions. The aim of this system is to close this gap - The library provides extremly efficient functions to calculate logarithms, hyperbolic functions and their inverses as well as typecheck or rounding functions and many more. Not only "complicated" functions are provided but also very easy ones like the absolute value of a real number, to finally have a full and complete list of important functions which every Math library should provide.

Further the library is designed modular, so that further and more advanced extensions can be easily added or removed from the system core. As a first Extension, there is a MathParser library included to the system which provides a fully functional interpreter for mathematic expressions, making it possible to implement an ingame calculator to the game. Further Plug-Ins or Extensions will follow.


2. System Code

Enclosed is the systems code. The system uses Newton-Cotes formulars to compute logarithms, hyperbolic functions and their inverses at an extremly high precision with a minimal overhead. Only four divisions are used in the worst case to compute the natural logarithm of a number, apart from that only additions and multiplications are used, making these functions very efficient. Some functions of the library already exist in the standard editor, like the min/max functions or abs. These are included for better readability to not have to use BJs. For more details about the interpreter, see section 3.

JASS:
library Maths/* v 1.2.0.0
**********************************************************************************
*
*   Advanced Mathematics
*   ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*   By looking_for_help aka eey
*
*   This system provides a large amount of standard mathematical functions that
*   miss in standard Jass like logarithmic, hyperbolic, typecheck or rounding 
*   functions. It can be extended with various optional libraries.
*
***********************************************************************************
*
*   Requirements
*   ¯¯¯¯¯¯¯¯¯¯¯¯
*   */  uses ErrorMessage   /*  hiveworkshop.com/forums/jass-resources-412/snippet-error-message-239210/
*
***********************************************************************************
*
*   Implementation
*   ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*   To use this system, just copy this script to your trigger editor, then you 
*   can use it straight away. To see how the evaluation function works, compare
*   the example IngameCalculator trigger.
*
**********************************************************************************
*
*   Available Plug-Ins and Extensions
*   ¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*       library MathParser
*           - A library that allows you to parse string expressions. Compare the
*             IngameCalculator Trigger for an example usage.
*
*       library Matrices
*           - A library that allows you to perform Matrix and Vector operations
*             like solving a System of Linear Equations, compute the inverse of
*             a Matrix, perform Matrix multiplication and so on.
*
**********************************************************************************
*
*   System API
*   ¯¯¯¯¯¯¯¯¯¯
*       struct Math
*       ¯ ¯ ¯ ¯ ¯ ¯
*       readonly static real Pi
*           - Refer to this field for the number Pi, the ratio of a circle's 
*             circumference to its diameter
*
*       readonly static real E
*           - Refer to this field for the number E, the base of the natural
*             exponential function.
*
*       readonly static real Phi
*           - Refer to this field for the number Phi, the golden ratio.
*
*       readonly static real Inf
*           - Refer to this field for 2^128, the biggest real number Wc3 can 
*             handle. You can use -Math.Inf to get the smallest real number.
*
*       readonly static integer MinInt
*           - Refer to this field for -2147483648, the smallest integer number 
*             that Wc3 can handle.
*
*       readonly static integer MaxInt
*           - Refer to this field for 2147483647, the biggest integer number 
*             that Wc3 can handle.
*
*       static method abs takes real r returns real
*           - Computes the absolute value of a number.
*
*       static method sig takes real r returns real
*           - Extracts the sign of a real number.
*
*       static method max takes real r1, real r2 returns real
*           - Returns the bigger of two values r1 and r2.
*
*       static method min takes real r1, real r2 returns real
*           - Returns the smaller of two values r1 and r2.
*
*       static method mod takes real r1, real r2  returns real
*           - Computes the rest of the division r1/r2.
*
*       static method modInt takes integer n1, integer n2 returns integer
*           - Computes the modulo of n1/n2.
*
*       static method multiMod takes integer n1, integer n2, integer mod returns integer
*           - Computes the modulo of n1*n2/mod. Use this to compute the
*             modulo of very large numbers.
*
*       static method expMod takes integer x, integer n, integer modulo returns integer
*           - Computes the modulo of x^n/modulo. Use this to compute the
*             modulo of extremly large numbers.
*
*       static method digits takes real r returns integer
*           - Returns the number of digits before the comma of a given real number.
*
*       static method isDigit takes string s returns boolean
*           - Determines whether a string is a digit or not.
*
*       static method isInteger takes real r returns boolean
*           - Determines whether a real is integer or not.
*
*       static method isEven takes real r returns boolean
*           - Determines the parity of a real number.
*
*       static method isPrime takes real r returns boolean
*           - Determines whether a number is a prime or not by using a deterministic
*             version of the Miller-Rabin test.
*
*       static method sinh takes real r returns real
*           - Computes the hyperbolic sine of a real number.
*
*       static method cosh takes real r returns real
*           - Computes the hyperbolic cosine of a real number.
*
*       static method tanh takes real r returns real
*           - Computes the hyperbolic tangent of a real number.
*
*       static method asinh takes real r returns real
*           - Computes the inverse hyperbolic sine of a real number.
*
*       static method acosh takes real r returns real
*           - Computes the inverse hyperbolic cosine of a real number.
*
*       static method atanh takes real r returns real
*           - Computes the inverse hyperbolic tangent of a real number.
*
*       static method ln takes real r returns real
*           - Computes the natural logarithm to a number by using Newton-Cotes.
*             Reaches extremly high accuracies very efficiently. This method
*             is used to compute all other logarithms and inverse hyperbolic
*             functions.
*
*       static method log2 takes real r returns real
*           - Computes the binary logarithm to a number.
*
*       static method log10 takes real r returns real
*           - Computes the common logarithm to a number.
*
*       static method log takes real r1, real r2 returns real
*           - Computes the logarithm of a number r2 to the base r1.
*
*       static method floor takes real r returns real
*           - Rounds a number to the next smallest integer.
*
*       static method ceil takes real r returns real
*           - Rounds a number to the next largest integer.
*
*       static method round takes real r returns real
*           - Rounds a number to the nearest whole number.
*
*       static method fractional takes real r returns real
*           - Computes the fractional part of a number.
*
*       static method mergeFloat takes real r returns real
*           - Merges the fracional and the non fractional parts of a number
*             together to an integer number.
*
*       static method factorial takes real r returns real
*           - Computes the factorial of a number r. If r is not a natural
*             number, the gamma function as an extension to the factorial
*             function is used.
*
*********************************************************************************/
    
    globals
        /*************************************************************************
        *   Customizable globals
        *************************************************************************/
           
        // Do you want the system to store primes that were once detected?
        private constant boolean STORE_DETECTED_PRIMES = true
           
        /*************************************************************************
        *   End of customizable globals
        *************************************************************************/
        
        public hashtable h
        private constant real E_INV = 0.3678794
        private constant real LOG_02_FACTOR = 1.4429504
        private constant real LOG_10_FACTOR = 0.4342945
        private constant real LN_FACTOR = 1.2840254
        private constant real LN_FACTOR_INV = 0.7788008
    endglobals
    
    struct Math //extends array
        // Constants
        static constant real Pi = 3.141593
        static constant real E = 2.718282
        static constant real Phi = 1.618034
        static constant real Inf = Pow(2.0, 128.0)
        static constant integer MinInt = -2147483648
        static constant integer MaxInt = 2147483647
        
        // Absolute value
        static method abs takes real r returns real
            if r < 0 then
                return -r
            endif
            return r
        endmethod
        
        // Signum
        static method sig takes real r returns real
            if r > 0 then
                return 1.0
            elseif r < 0 then
                return -1.0
            endif
            return 0.0
        endmethod
        
        // Min-Max
        static method max takes real r1, real r2 returns real
            if r1 < r2 then
                return r2
            endif
            return r1
        endmethod
        
        static method min takes real r1, real r2 returns real
            if r1 < r2 then
                return r1
            endif
            return r2
        endmethod
        
        // Modulus
        static method mod takes real r1, real r2  returns real
            local real modulus = r1 - I2R(R2I(r1/r2))*r2

            if modulus < 0 then
                set modulus = modulus + r2
            endif
            return modulus
        endmethod
        
        static method modInt takes integer n1, integer n2 returns integer
            local integer modulus = n1 - (n1/n2)*n2

            if modulus < 0 then
                set modulus = modulus + n2
            endif
            return modulus
        endmethod

        static method multiMod takes integer n1, integer n2, integer mod returns integer
            local integer factor1 = R2I(floor(n1/mod))
            local integer factor2 = R2I(floor(n2/mod))
            local integer modulus

            if factor1 == 0 then
                set factor1 = 1
            endif
            if factor2 == 0 then
                set factor2 = 1
            endif
          
            if n1 > mod/2 and n2 > mod/2 then
                set n1 = (n1 - factor1*mod)*(n2 - factor2*mod)
            else
                set n1 = n1*n2
            endif
            set n2 = mod
                
            set modulus = n1 - (n1/n2)*n2
            if modulus < 0 then
                set modulus = modulus + n2
            endif

            return modulus
        endmethod
        
        static method expMod takes integer x, integer n, integer modulo returns integer
            local string exponent = ""
            local integer result = 1
            local integer stringLen
            local integer i = 0
            
            loop
                if modInt(n, 2) == 1 then
                    set exponent = "1"+exponent
                else
                    set exponent = "0"+exponent
                endif
                set n = n/2
                 
                exitwhen n < 1
            endloop

            set stringLen = StringLength(exponent)
            loop
                exitwhen i >= stringLen
                set result = multiMod(result, result, modulo)
                if SubString(exponent, i, i + 1) == "1" then
                    set result = multiMod(result, x, modulo)
                endif
                set i = i + 1
            endloop

            return result
        endmethod
        
        // Digits
        static method digits takes real r returns integer
            local string s = R2S(r)
            local integer i = 0
            loop
                exitwhen SubString(s, i, i + 1) == "."
                set i = i + 1
            endloop
            if r < 0 then
                return i - 1
            endif
            return i
        endmethod

        // Logarithms
        static method ln takes real r returns real
            local real sum = 0.0
            local real sign = 1.0
            debug if r < 0.0 then
                debug call ThrowError(true, "Maths", "ln", "Math", 0, "Logarithm of negative number is undefined!")
            debug endif
            if r < 1.0 then
                set r = 1.0/r
                set sign = -1.0
            endif
            loop
                exitwhen r < E
                set r = r*E_INV
                set sum = sum + 1.0
            endloop
            loop
                exitwhen r < LN_FACTOR
                set r = r*LN_FACTOR_INV
                set sum = sum + 0.25
            endloop

            return sign*(sum + 0.125*(r - 1.0)*(1 + 9.0/(2.0 + r) + 4.5/(0.5 + r) + 1.0/r))
        endmethod
        
        static method log2 takes real r returns real
            return LOG_02_FACTOR*ln(r)
        endmethod
        
        static method log10 takes real r returns real
            return LOG_10_FACTOR*ln(r)
        endmethod
        
        static method log takes real base, real arg returns real
            return ln(arg)/ln(base)
        endmethod
        
        // Hyperbolic functions
        static method sinh takes real r returns real
            return 0.5*(Pow(E, r) - Pow(E, -r))
        endmethod
        
        static method cosh takes real r returns real
            return 0.5*(Pow(E, r) + Pow(E, -r))
        endmethod
        
        static method tanh takes real r returns real
            return sinh(r)/cosh(r)
        endmethod
        
        static method asinh takes real r returns real
            return ln(r + SquareRoot(r*r + 1))
        endmethod
        
        static method acosh takes real r returns real
            return ln(r + SquareRoot(r*r - 1))
        endmethod
        
        static method atanh takes real r returns real
            return 0.5*ln((1 + r)/(1 - r))
        endmethod
        
        // Rounding
        static method floor takes real r returns real
            if r < 0 then
                return -I2R(R2I(-r))
            endif
            return I2R(R2I(r))
        endmethod
        
        static method ceil takes real r returns real
            if floor(r) == r then
                return r
            elseif r < 0 then
                return -(I2R(R2I(-r)) + 1.0)
            endif
            return I2R(R2I(r)) + 1.0
        endmethod
        
        static method round takes real r returns real
            if r > 0 then
                return I2R(R2I(r + 0.5))
            endif
            return I2R(R2I(r - 0.5))
        endmethod

        static method fractional takes real r returns real
            return r - floor(r)
        endmethod
        
        static method mergeFloat takes real r returns real
            local real afterC = fractional(r)
            local real beforeC = floor(r)
            local string beforeComma = R2S(beforeC)
            local string afterComma = R2S(afterC)
            local string subString
            local integer i = 0
            local integer stringLen = StringLength(beforeComma)
            local integer endPosition = 0
            
            if afterC == 0 then
                return beforeC
            endif
            loop
                exitwhen SubString(beforeComma, i, i + 1) == "." 
                set i = i + 1
            endloop
            set beforeComma = SubString(beforeComma, 0, i)
            set i = StringLength(afterComma)
            loop
                set subString = SubString(afterComma, i, i + 1)
                exitwhen subString == "." 
                if endPosition == 0 and subString != "0" and subString != "" then
                    set endPosition = i
                endif
                set i = i - 1
            endloop

            return S2R(beforeComma+SubString(afterComma, i + 1, endPosition + 1))
        endmethod
        
        // Type checks
        static method isDigit takes string s returns boolean
            return not (StringLength(s) != 1 or S2R(s) == 0 and s != "0")
        endmethod
        
        static method isInteger takes real r returns boolean
            return I2R(R2I(r)) == r
        endmethod
        
        static method isEven takes real r returns boolean
            return mod(r, 2.0) == 0 
        endmethod
        
        static method isPrime takes integer n returns boolean
            local integer s 
            local integer d
            local integer a = 2
            local integer temp
            local integer counter
            local integer dSave
            local integer modulus
            local boolean firstTest = false
            local boolean secondTest = false

            if n == 2 or n == 7 or n == 61 then
                return true
            elseif isEven(n) or n < 2 then
                return false
            endif
            
            static if STORE_DETECTED_PRIMES then
                if LoadBoolean(h, n, 0) then
                    return LoadBoolean(h, n, 1)
                endif
            endif

            if n < 157 then
                set a = n
                loop
                    exitwhen a == 1
                    if modInt(n, a) == 0 and a != n then
                        static if STORE_DETECTED_PRIMES then
                            call SaveBoolean(h, n, 0, true)
                            call SaveBoolean(h, n, 1, false)
                        endif
                        return false
                    endif
                    set a = a - 1
                endloop
                static if STORE_DETECTED_PRIMES then
                    call SaveBoolean(h, n, 0, true)
                    call SaveBoolean(h, n, 1, true)
                endif
                return true
            endif
            
            set s = R2I(floor(log2(n - 1)))
            loop
                set temp = R2I(Pow(2, I2R(s)))
                exitwhen modInt(n - 1, temp) == 0
                set s = s - 1
            endloop

            set d = (n - 1)/(R2I(Pow(2, I2R(s))))
            set dSave = d
            set a = 2
            set counter = 0
            loop
                exitwhen counter > s
                set modulus = expMod(a, d, n)
                if (counter == 0 and modulus == 1) or (counter > 0 and modulus - n == -1) then
                    set firstTest = true
                    exitwhen true
                endif
                set d = 2*d

                set counter = counter + 1
                if counter == 1 then
                    set d = dSave
                endif
            endloop

            if not firstTest then
                static if STORE_DETECTED_PRIMES then
                    call SaveBoolean(h, n, 0, true)
                    call SaveBoolean(h, n, 1, false)
                endif
                return false
            endif
            
            set a = 7
            set d = dSave
            set counter = 0
            loop
                exitwhen counter > s
                set modulus = expMod(a, d, n)
                if (counter == 0 and modulus == 1) or (counter > 0 and modulus - n == -1) then
                    if firstTest then
                        set secondTest = true
                        exitwhen true
                    endif
                endif
                set d = 2*d

                set counter = counter + 1
                if counter == 1 then
                    set d = dSave
                endif
            endloop

            if not secondTest then
                static if STORE_DETECTED_PRIMES then
                    call SaveBoolean(h, n, 0, true)
                    call SaveBoolean(h, n, 1, false)
                endif
                return false
            endif
            
            set a = 61
            set d = dSave
            set counter = 0
            loop
                exitwhen counter > s
                set modulus = expMod(a, d, n)
                if (counter == 0 and modulus == 1) or (counter > 0 and modulus - n == -1) then
                    if secondTest then
                        static if STORE_DETECTED_PRIMES then
                            call SaveBoolean(h, n, 0, true)
                            call SaveBoolean(h, n, 1, true)
                        endif
                        return true
                    endif
                endif
                set d = 2*d
                
                set counter = counter + 1
                if counter == 1 then
                    set d = dSave
                endif
            endloop
                
            static if STORE_DETECTED_PRIMES then
                call SaveBoolean(h, n, 0, true)
                call SaveBoolean(h, n, 1, false)
            endif
            return false
        endmethod
        
        // Factorial
        static method factorial takes real r returns real
            local real z = 1.0
            if floor(r) == r then
                debug if r < 0 then
                    debug call ThrowError(true, "Maths", "factorial", "Math", 0, "Factorial of negative number is not defined!")
                debug endif
                if r == 0 then
                    return 1.0
                endif
                loop
                    exitwhen r == 0.0
                    set z = z*r
                    set r = r - 1.0
                endloop
                return z
            endif
            set r = r + 1.0
            return SquareRoot((2.0*Pi)/(r))*Pow(((1.0/E)*(r + 1.0/(12.0*r - 1.0/(10.0*r)))), r)
        endmethod
    endstruct
    
    private module Init
        private static method onInit takes nothing returns nothing
            set h = InitHashtable()
        endmethod
    endmodule
    
    private struct Inits extends array
        implement Init
    endstruct
endlibrary




Math struct (function list)


readonly static real Pi
Refer to this field for the number pi, the ratio of a circle's circumference to its diameter

readonly static real E
Refer to this field for the number E, the base of the natural exponential function.

readonly static real Phi
Refer to this field for the number Phi, the golden ratio.

readonly static real Inf
Refer to this field for 2^128, the biggest real number Wc3 can handle. You can use -Math.Inf to get the smallest real number.

readonly static integer MinInt
Refer to this field for -2147483648, the smallest integer number that Wc3 can handle.

readonly static integer MaxInt
Refer to this field for 2147483647, the biggest integer number that Wc3 can handle.

static method abs takes real r returns real
Computes the absolute value of a number.

static method sig takes real r returns real
Extracts the sign of a real number.

static method max takes real r1, real r2 returns real
Returns the bigger of two values r1 and r2.

static method min takes real r1, real r2 returns real
Returns the smaller of two values r1 and r2.

static method mod takes real r1, real r2 returns real
Computes the rest of the division r1/r2.

static method modInt takes integer n1, integer n2 returns integer
Computes the modulo of n1/n2.

static method multiMod takes integer n1, integer n2, integer mod returns integer
Computes the modulo of n1*n2/mod. Use this to compute themodulo of very large numbers.

static method expMod takes integer x, integer n, integer modulo returns integer
Computes the modulo of x^n/modulo. Use this to compute the modulo of extremly large numbers.

static method digits takes real r returns integer
Returns the number of digits before the comma of a given real number.

static method isDigit takes string s returns boolean
Determines whether a string is a digit or not.

static method isInteger takes real r returns boolean
Determines whether a real is integer or not.

static method isEven takes real r returns boolean
Determines the parity of a real number.

static method isPrime takes real r returns boolean
Determines whether a number is a prime or not by using a deterministic version of the Miller-Rabin test. Works for values about ~100000.

static method sinh takes real r returns real
Computes the hyperbolic sine of a real number.

static method cosh takes real r returns real
Computes the hyperbolic cosine of a real number.

static method tanh takes real r returns real
Computes the hyperbolic tangent of a real number.

static method asinh takes real r returns real
Computes the inverse hyperbolic sine of a real number.

static method acosh takes real r returns real
Computes the inverse hyperbolic cosine of a real number.

static method atanh takes real r returns real
Computes the inverse hyperbolic tangent of a real number.

static method ln takes real r returns real
Computes the natural logarithm to a number by using Newton-Cotes. Reaches extremly high accuracies very efficiently. This method is used to compute all other logarithms and inverse hyperbolic functions.

static method log2 takes real r returns real
Computes the binary logarithm to a number.

static method log10 takes real r returns real
Computes the common logarithm to a number.

static method log takes real r1, real r2 returns real
Computes the logarithm of a number r2 to the base r1. If you want to compute the logarithm to the bases 2, 10 or E, you should use the specific functions as they are faster.

static method floor takes real r returns real
Rounds a number to the next smallest integer.

static method ceil takes real r returns real
Rounds a number to the next largest integer.

static method round takes real r returns real
Rounds a number to the nearest whole number.

static method fractional takes real r returns real
Computes the fractional part of a number.

static method mergeFloat takes real r returns real
Merges the fracional and the non fractional parts of a number together to an integer number.

static method factorial takes real r returns real
Computes the factorial of a number r. If r is not a natural number, the gamma function as an extension to the factorial function is used.




3. Implementation and Available Extensions

To implement this system, just copy and paste the Math and the IngameCalculator triggers to your map. The only requirement is vJass, then you can use it right away, same applies for the available Extensions.

3.1. MathParser

This is one Extension to the Math library, a Math Parser library making it possible to dynamically evaluate mathematic expressions. This can be used to implement an ingame calculator to the game which makes ingame calculations very comfortable. This can be also useful for several things like: mathematic minigames or riddles, calculations during debugging or as a comfort function for maps that have a complex stat/skill system. Also maps with economy simulation parts could benefit from this. The math interpreter is based on standard Matlab conventions and supports the following symbols:

  • Numbers with or without decimal point, e.g.: 3, 4.3, 55.2
  • Arithmetic operators: +, -, *, /
  • Power: ^
  • Parenthesis: ( )
  • Result memory (stores the last computed result): ans
  • Clear screen: clc

The interpreter is designed to be very robust towards the different typing styles of mathematical expressions. So you can write for example 5*(1+2) or 5(1+2), the interpreter will automatically bring it into an understandable form. With the formatExpression method it is garantueed that the expression will also follow the standard conventions in terms of spacing and operator placement. Finally the interpreter is provided with various syntax and math error messages which will throw exceptions if the entered expression is invalid. These error messages can be optionally turned of in the system configuration. Enclosed is the Plug-In code:


JASS:
library MathParser /* v 1.1.0.0
**********************************************************************************
*
*   MathParser
*   ¯¯¯¯¯¯¯¯¯¯
*   By looking_for_help aka eey
*
*   This system provides methods for parsing mathematically string expressions,
*   represented as strings. Also methods for formating string expressions are
*   provided, making it possible to implement an ingame calculator to the game.
*
***********************************************************************************
*
*   Requirements
*   ¯¯¯¯¯¯¯¯¯¯¯¯
*   */  uses Maths   /*  hiveworkshop.com/forums/spells-569/advanced-maths-ingame-calculator-234024/?prev=r%3D20%26page%3D5
*
***********************************************************************************
*
*   Implementation
*   ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*   To use this system, you need the library Math. Once you implemented it, just 
*   copy this script to your trigger editor, then you can use it straight away. To 
*   see how the evaluation function works, compare the example IngameCalculator 
*   trigger for an example usage.
*
***********************************************************************************
*
*   System API
*   ¯¯¯¯¯¯¯¯¯¯
*   readonly static real ans
*       - Stores the last result of the evaluation method. Initialized as 0.
*
*   static method calculate takes string expression returns real
*       - Use this method to calculate a mathematic expression presented as
*         a string. Allowed values are numbers, the decimal seperator, basic
*         arithmetic operators like +, -, *, / and ^ as well as parenthesis.
*         You can also put "ans" into the expression to refer to the last
*         calculation result. Error messages on math and syntax errors will
*         be displayed if specified so in the configurable globals. The
*         syntax parsing strictly follows Matlab conventions.
*
*   static method formatExpression takes string expression returns string
*       - Use this method to format an user defined expression so that it
*         looks nice. Compare the IngameCalculator trigger for an example
*         usage.
*
*********************************************************************************/

    globals
        /*************************************************************************
        *   Customizable globals
        *************************************************************************/
        
        // Do you want the system to display error messages on math errors?
        private constant boolean DISPLAY_MATH_ERRORS = true
        
        // Do you want the system to display error messages on syntax errors?
        private constant boolean DISPLAY_SYNTAX_ERRORS = true
           
        /*************************************************************************
        *   End of customizable globals
        *************************************************************************/
    endglobals

    private module Init
        private static method onInit takes nothing returns nothing
            call init()
        endmethod
    endmodule
    
    struct MathParser extends array
        readonly static real ans = 0.0
        private static constant integer ADDITION = 1
        private static constant integer SUBSTRACTION = 2
        private static constant integer MULTIPLICATION = 3
        private static constant integer DIVISION = 4
        private static constant integer EXPONENTIATION = 5
        
        private static method getPriority takes string op returns integer
            return LoadInteger(Maths_h, StringHash(op), 0)
        endmethod
    
        private static method error takes string s, integer flag returns nothing
            local real crashThread
            if flag == 0 then
                static if DISPLAY_MATH_ERRORS then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 60.0, "|cffff0000Math Error!|r "+s)
                endif
            else
                static if DISPLAY_SYNTAX_ERRORS then
                    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 60.0, "|cffff0000Syntax Error!|r "+s)
                endif
            endif
            set crashThread = 0/0
        endmethod
    
        private static method convertExpression takes string expression returns string
            local integer stringLen = StringLength(expression)
            local integer i = 0
            local integer stackCounter = -1
            local string postfix = ""
            local string array stack
            local string actualChar
            local string prevChar
            local boolean decimalDetected = false
            local boolean numberDetected = false
            local boolean numberOnceDetected = false
            local boolean unaryOperator = false
            local integer openBraces = 0

            loop
                exitwhen i > stringLen
                set prevChar = SubString(expression, i - 1, i)
                set actualChar = SubString(expression, i, i + 1)
                set unaryOperator = not (prevChar == ")" or Math.isDigit(prevChar))

                if actualChar == ")" and openBraces < 1 then
                    call thistype.error("Unbalanced parenthesis!", 1)
                endif
                
                if actualChar == "m" or actualChar == "p" or actualChar == "M" or actualChar == "P" then
                    call thistype.error("Undefined symbols used!", 1)
                endif
                if actualChar == "+" and unaryOperator and prevChar != "^"  then
                    set actualChar = "p"
                elseif actualChar == "-" and unaryOperator and prevChar != "^" then
                    set actualChar = "m"
                elseif actualChar == "-" and unaryOperator and prevChar == "^" then
                    set actualChar = "M"
                elseif actualChar == "+" and unaryOperator and prevChar == "^" then
                    set actualChar = "P"
                endif
                if Math.isDigit(actualChar) then
                    set postfix = postfix+actualChar
                    set numberDetected = true
                    set numberOnceDetected = true
                elseif actualChar == "." then
                    if decimalDetected == false and Math.isDigit(SubString(expression, i - 1, i)) and Math.isDigit(SubString(expression, i + 1, i + 2)) then
                       set postfix = postfix+actualChar
                       set decimalDetected = true
                    else
                        call thistype.error("Incorrect use of decimal point!", 1)
                    endif
                elseif thistype.isOperator(actualChar) or actualChar == "(" or actualChar == ")" then
                    set decimalDetected = false
                    if numberDetected then
                        set numberDetected = false
                        set postfix = postfix+" "
                    endif

                    if thistype.getPriority(actualChar) > thistype.getPriority(stack[stackCounter]) or actualChar == "("  then
                        set stackCounter = stackCounter + 1
                        set stack[stackCounter] = actualChar
                        if actualChar == "(" then
                            set openBraces = openBraces + 1
                        endif
                    elseif openBraces > 0 and actualChar != ")" and actualChar != "("  and thistype.getPriority(actualChar) <= thistype.getPriority(stack[stackCounter]) then
                        loop
                            exitwhen stack[stackCounter] == "("
                            set postfix = postfix+stack[stackCounter]+" "
                            set stackCounter = stackCounter - 1
                        endloop
                        set stackCounter = stackCounter + 1
                        set stack[stackCounter] = actualChar
                    else
                        if actualChar == ")" then
                            set openBraces = openBraces - 1
                            loop
                                exitwhen stack[stackCounter] == "("
                                set postfix = postfix+stack[stackCounter]+" "
                                set stackCounter = stackCounter - 1
                            endloop

                            set stack[stackCounter] = ""
                            set stackCounter = stackCounter - 1
                        else
                            loop
                                exitwhen stackCounter < 0
                                set postfix = postfix+stack[stackCounter]+" "
                                set stackCounter = stackCounter - 1
                            endloop
                            set stackCounter = stackCounter + 1
                            set stack[stackCounter] = actualChar
                        endif
                    endif
                else
                    if i != stringLen then
                        call thistype.error("Undefined symbols used!", 1)
                    endif
                endif
                set i = i + 1
            endloop

            if not numberOnceDetected then
                call thistype.error("Invalid expression!", 1)
            endif
            if stackCounter >= 0 then
                if openBraces > 0 then
                    call thistype.error("Unbalanced parenthesis!", 1)
                endif
                loop
                    exitwhen stackCounter < 0
                    if stack[stackCounter] != "(" then
                        if numberDetected then
                            set postfix = postfix+" "+stack[stackCounter]+" "
                            set numberDetected = false
                        else
                            set postfix = postfix+stack[stackCounter]+" "
                        endif
                    endif
                    set  stackCounter = stackCounter - 1
                endloop
            endif
            set stringLen = StringLength(postfix)
            if Math.isDigit(SubString(postfix, stringLen - 1, stringLen)) then
                set postfix = postfix+" "
            endif

            return postfix
        endmethod
        
        private static method subCalc takes string op1, string op2, string op returns real
            local real r1 = S2R(op1)
            local real r2 = S2R(op2)
            local integer localOp
            
            if op1 == null or op2 == null then
                call thistype.error("Unbalanced operators!", 1)
            endif
            set localOp = LoadInteger(Maths_h, StringHash(op), 1)
            if localOp < MULTIPLICATION then
                if localOp == ADDITION then
                    return r1 + r2
                else
                    return r1 - r2
                endif
            else
                if localOp == MULTIPLICATION then
                    return r1*r2
                elseif localOp == DIVISION then
                    if r2 == 0 then
                        call thistype.error("Division by zero!", 0)
                    endif
                    return r1/r2
                else
                    if r1 < 0.0 and not Math.isInteger(r2) then
                        call thistype.error("(N-th) square root from negativ value not defined!", 0)
                    endif
                    return Pow(r1, r2)
                endif
            endif
            call thistype.error("Undefined operators!", 1)
            return 0.0
        endmethod
        
        private static method isOperator takes string s returns boolean
            return s == "+" or s == "-" or s == "*" or s == "/" or s == "^" or s == "(" or s == "p" or s == "m" or s == "P" or s == "M"
        endmethod
        
        private static method prepareExpression takes string expression returns string
            local integer stringLen = StringLength(expression)
            local integer i = 0
            local string actualChar
            local string prevChar
            local string nextChar
            
            loop
                exitwhen i > stringLen
                set actualChar = SubString(expression, i, i + 1)
                if actualChar == " " then
                    set expression = SubString(expression, 0, i)+SubString(expression, i + 1, stringLen)
                    set i = i - 1
                endif
                set i = i + 1
            endloop
            
            set i = 0
            set stringLen = StringLength(expression)
            loop
                exitwhen i > stringLen
                if SubString(expression, i, i + 3) == "ans" then
                    set expression = SubString(expression, 0, i)+"("+R2S(ans)+")"+SubString(expression, i + 3, stringLen)
                    set stringLen = StringLength(expression)
                endif
                
                set prevChar = SubString(expression, i - 1, i)
                set actualChar = SubString(expression, i, i + 1)
                set nextChar = SubString(expression, i + 1, i + 2)
                
                if actualChar == "+" then
                    if SubString(expression, i + 1, i + 2) == "+" then
                        if Math.isDigit(SubString(expression, i - 1, i)) then
                            set expression = SubString(expression, 0, i)+"+"+SubString(expression, i + 2, stringLen)
                        else
                            set expression = SubString(expression, 0, i)+SubString(expression, i + 2, stringLen)
                        endif
                        set i = i - 1
                    elseif SubString(expression, i + 1, i + 2) == "-" then
                        set expression = SubString(expression, 0, i)+"-"+SubString(expression, i + 2, stringLen)
                        set i = i - 1
                    endif
                elseif actualChar == "-" then
                    if SubString(expression, i + 1, i + 2) == "+" then
                        set expression = SubString(expression, 0, i)+"-"+SubString(expression, i + 2, stringLen)
                        set i = i - 1
                    elseif SubString(expression, i + 1, i + 2) == "-" then
                        if Math.isDigit(SubString(expression, i - 1, i)) then
                            set expression = SubString(expression, 0, i)+"+"+SubString(expression, i + 2, stringLen)
                        else
                            set expression = SubString(expression, 0, i)+SubString(expression, i + 2, stringLen)
                        endif
                        set i = i - 1
                    endif
                elseif actualChar == "(" and (Math.isDigit(prevChar) or prevChar == ")") then
                    set expression = SubString(expression, 0, i)+"*"+SubString(expression, i, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                elseif actualChar == ")" and Math.isDigit(nextChar) then
                    set expression = SubString(expression, 0, i + 1)+"*"+SubString(expression, i + 1, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                endif
                set i = i + 1
            endloop
            
            return expression
        endmethod
        
        private static method evaluateExpression takes string postfix returns real
            local integer stringLen = StringLength(postfix)
            local integer i = 0
            local integer position = 0
            local integer counter = 0
            local integer stackCounter = -1
            local string actualToken
            local string array stack
            local real result = 0.0

            loop
                exitwhen i == stringLen
                if SubString(postfix, i, i + 1) == " " then
                    set actualToken = SubString(postfix, position, position + counter)
                    if Math.isDigit(SubString(actualToken, 0, 1)) then
                        set stackCounter = stackCounter + 1
                        set stack[stackCounter] = actualToken
                    else
                        if not (actualToken == "m " or actualToken == "p " or actualToken == "M " or actualToken == "P ") then
                            set result = thistype.subCalc(stack[stackCounter - 1], stack[stackCounter], actualToken)
                            set stack[stackCounter] = ""
                            set stack[stackCounter - 1] = R2S(result)
                            set stackCounter = stackCounter - 1
                        else
                            if actualToken == "m " or actualToken == "M " then
                                if S2R(stack[stackCounter]) > 0 then
                                    set stack[stackCounter] = "-"+stack[stackCounter]
                                else
                                    set stack[stackCounter] = SubString(stack[stackCounter], 1, StringLength(stack[stackCounter]))
                                endif
                            endif
                        endif
                    endif
                    set position = i + 1
                    set counter = 0
                endif
                set i = i + 1
                set counter = counter + 1
            endloop

            return S2R(stack[0])
        endmethod
    
        static method calculate takes string expression returns real
            set ans = thistype.evaluateExpression(thistype.convertExpression(thistype.prepareExpression(expression)))
            return ans
        endmethod
        
        static method formatExpression takes string expression returns string
            local integer i = 0
            local integer stringLen = StringLength(expression)
            local string prevChar
            local string nextChar
            local string actualChar
            local string prevAnsToken
            local string nextAnsToken
            local boolean unaryOperator = false
            
            loop
                exitwhen i > stringLen
                if SubString(expression, i, i + 1) == " " then
                    set expression = SubString(expression, 0, i)+SubString(expression, i + 1, stringLen)
                    set i = i - 1
                endif
                set i = i + 1
            endloop
            
            set i = 0
            set stringLen = StringLength(expression)
            loop
                exitwhen i > stringLen
                set actualChar = SubString(expression, i, i + 1)
                if actualChar == "+" then
                    if SubString(expression, i + 1, i + 2) == "+" then
                        if Math.isDigit(SubString(expression, i - 1, i)) then
                            set expression = SubString(expression, 0, i)+"+"+SubString(expression, i + 2, stringLen)
                        else
                            set expression = SubString(expression, 0, i)+SubString(expression, i + 2, stringLen)
                        endif
                        set i = i - 1
                    elseif SubString(expression, i + 1, i + 2) == "-" then
                        set expression = SubString(expression, 0, i)+"-"+SubString(expression, i + 2, stringLen)
                        set i = i - 1
                    endif
                elseif actualChar == "-" then
                    if SubString(expression, i + 1, i + 2) == "+" then
                        set expression = SubString(expression, 0, i)+"-"+SubString(expression, i + 2, stringLen)
                        set i = i - 1
                    elseif SubString(expression, i + 1, i + 2) == "-" then
                        if Math.isDigit(SubString(expression, i - 1, i)) then
                            set expression = SubString(expression, 0, i)+"+"+SubString(expression, i + 2, stringLen)
                        else
                            set expression = SubString(expression, 0, i)+SubString(expression, i + 2, stringLen)
                        endif
                        set i = i - 1
                    endif
                endif
                set i = i + 1
            endloop
            
            set i = 0
            set stringLen = StringLength(expression)
            loop
                exitwhen i > stringLen
                set actualChar = SubString(expression, i, i + 1)
                set prevChar = SubString(expression, i - 1, i)
                set nextChar = SubString(expression, i + 1, i + 2)
                set prevAnsToken = SubString(expression, i - 3, i)
                set nextAnsToken = SubString(expression, i + 1, i + 4)
                
                set unaryOperator = not (prevChar == ")" or Math.isDigit(prevChar) or prevAnsToken == "ans")
                if actualChar == "+" and not unaryOperator then
                    set expression = SubString(expression, 0, i)+" + "+SubString(expression, i + 1, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i + 1
                elseif actualChar == "+" and unaryOperator then
                    set expression = SubString(expression, 0, i)+SubString(expression, i + 1, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                elseif actualChar == "-" and not unaryOperator then
                    set expression = SubString(expression, 0, i)+" - "+SubString(expression, i + 1, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i + 1
                elseif actualChar == "(" and (Math.isDigit(prevChar) or prevChar == ")") then
                    set expression = SubString(expression, 0, i)+"*"+SubString(expression, i, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                elseif actualChar == ")" and Math.isDigit(nextChar) then
                    set expression = SubString(expression, 0, i + 1)+"*"+SubString(expression, i + 1, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                endif
                if prevAnsToken == "ans" and (Math.isDigit(actualChar) or actualChar == "(" or SubString(expression, i, i + 3) == "ans") then
                    set expression = SubString(expression, 0, i)+"*"+SubString(expression, i, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                elseif nextAnsToken == "ans" and (Math.isDigit(actualChar) or actualChar == ")") then
                    set expression = SubString(expression, 0, i + 1)+"*"+SubString(expression, i + 1, stringLen)
                    set stringLen = StringLength(expression)
                    set i = i - 1
                endif
                
                set i = i + 1
            endloop
            
            return expression
        endmethod
        
        private static method init takes nothing returns nothing
            call SaveInteger(Maths_h, StringHash("+"), 0, 1)
            call SaveInteger(Maths_h, StringHash("-"), 0, 1)
            call SaveInteger(Maths_h, StringHash("*"), 0, 2)
            call SaveInteger(Maths_h, StringHash("/"), 0, 2)
            call SaveInteger(Maths_h, StringHash("m"), 0, 3)
            call SaveInteger(Maths_h, StringHash("p"), 0, 3)
            call SaveInteger(Maths_h, StringHash("^"), 0, 4)
            call SaveInteger(Maths_h, StringHash("M"), 0, 5)
            call SaveInteger(Maths_h, StringHash("P"), 0, 5)
            call SaveInteger(Maths_h, StringHash("("), 0, 6)
            call SaveInteger(Maths_h, StringHash("+ "), 1, ADDITION)
            call SaveInteger(Maths_h, StringHash("- "), 1, SUBSTRACTION)
            call SaveInteger(Maths_h, StringHash("* "), 1, MULTIPLICATION)
            call SaveInteger(Maths_h, StringHash("/ "), 1, DIVISION)
            call SaveInteger(Maths_h, StringHash("^ "), 1, EXPONENTIATION)
        endmethod
        
        implement Init
    endstruct
endlibrary



JASS:
library IngameCalculator uses MathParser
    globals
        /*************************************************************************
        *   Customizable globals
        *************************************************************************/
        
        // Define a command before performing a calculation, e.g. "-calc ". 
        // Use an empty string for no command.
        private constant string commandString = ""
        
        // Type in this string to clear the screen.
        private constant string clearScreen = "clc"
        
        /*************************************************************************
        *   End of customizable globals
        *************************************************************************/
    endglobals

    private struct Calculator extends array
        readonly static string expression
    
        private static method onEnter takes nothing returns nothing
            set expression = GetEventPlayerChatString()
            if SubString(expression, 0, StringLength(commandString)) == commandString then
                set expression = SubString(expression, StringLength(commandString), StringLength(expression))
                if expression == clearScreen then
                    call ClearTextMessages()
                else
                    call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 60.0, MathParser.formatExpression(expression)+" = "+R2S(MathParser.calculate(expression)))
                endif
            endif
        endmethod
        
        implement CalcInit
    endstruct
   
    module CalcInit
        private static method onInit takes nothing returns nothing
            local trigger t = CreateTrigger()
            local code c = function thistype.onEnter
            local integer i = 0

            loop
                exitwhen i > 11
                call TriggerRegisterPlayerChatEvent(t, Player(i), "", false)
                set i = i + 1
            endloop
            call TriggerAddCondition(t, Filter(c))
            set t = null
            set c = null
        endmethod
    endmodule
endlibrary




MathParser struct


readonly static real ans
Stores the last result of the evaluation method. Initialized as 0.

static method calculate takes string expression returns real
Use this method to calculate a mathematic expression presented as a string. Allowed values are numbers, the decimal seperator, basic arithmetic operators like +, -, *, / and ^ as well as parenthesis. You can also put "ans" into the expression to refer to the last calculation result. Error messages on math and syntax errors will be displayed if specified so in the configurable globals. The syntax parsing strictly follows Matlab conventions.

static method formatExpression takes string expression returns string
Use this method to format an user defined expression so that it looks nice. Compare the IngameCalculator trigger for an example usage.




3.2. Matrices

This is another Extension to the basic Maths library which gives you the possiblity to perform Matrix operations in Warcraft 3. Matrices can basically be used like 2D-Arrays with this library. The library also provides advanced methods to initialize, reshape or to perform calculations with Matrices. Gaußian Eliminiation with pivotising is implemented as well as solving a System of Linear Equations (SLE), inverting or transposing a Matrix as well as calculating the norm, condition or trace.

This library will serve as a base for more advanced libraries in the future which allow curve fitting, trajectory interpolation and many more.


JASS:
library Matrices /* v 1.1.0.1
**********************************************************************************
*
*   Matrices
*   ¯¯¯¯¯¯¯¯ 
*   By looking_for_help aka eey
*
*   This system provides advanced methods for handling Matrices in Warcraft 3.
*   Features like Matrix multiplication, calculation of norms or trace as well as
*   solving a system of linear equations with Gauss-Elimination are implemented.
*   The system also provides a big variety of functions to initialize, copy or
*   reshape Matrices.
*
*   Credits go to Magtheridon for helping with the Systems API.
*  
**********************************************************************************
*
*   Requirements
*   ¯¯¯¯¯¯¯¯¯¯¯¯
*   */  uses Maths   /*  hiveworkshop.com/forums/spells-569/advanced-maths-ingame-calculator-234024/?prev=r%3D20%26page%3D5
*
**********************************************************************************
*
*   Implementation
*   ¯¯¯¯¯¯¯¯¯¯¯¯¯¯
*   To use this system just copy it into an empty trigger in your map. As this
*   system uses the Math library you should install it first to get the system
*   to work. The Math library can be found under the link above.
*
**********************************************************************************
*
*   System API
*   ¯¯¯¯¯¯¯¯¯¯ 
*
*   Struct usage
*   -----------------------------
*
*       struct Matrix
*           - This struct provides the methods and logic to use Matrices in 
*             Warcraft 3 with this system. Use the create method to allocate a 
*             new instance of a Matrix of your desired size. The Matrix can then 
*             be used like a 2D-Array (example displayed above) and provides  
*             various methods to perform advanced Matrix operations.
*                             
*                                                          0  1  2    
*                                                       0 [0][0][0]
*             local Matrix mat = Matrix.create(3, 3) =  1 [0][0][0]
*                                                       2 [0][0][0]
*
*
*   Operators
*   -----------------------------
*
*       [] operators
*           - Use the [] operators to access directly to the values of a given 
*             Matrix. For example mat[2][1] will return the element in the third 
*             row, second column. Note that the indices are, like Wc3 arrays, 
*             zero-based.
*
*
*   Fields
*   -----------------------------
*
*       readonly integer n
*           - Specifies the number of rows of a given Matrix.
*
*       readonly integer m
*           - Specifies the number of columns of a given Matrix.
*
*       readonly static Matrix Invalid_Matrix
*           - An invalid Matrix of the size 0 x 0. You can't create such a Matrix, 
*             so if you need one, use this field. Some algorithms, such as solveSLE 
*             return such a Matrix if no solution for a given System of Linear 
*             Equations could be found. You can use the method isValid() to 
*             determine wether a Matrix is valid or not.       
*
*       static constant integer ONE_NORM
*           - Use this as a parameter for the norm method to specify that the method
*             should calculate the one norm (maximum of column sum absolute values).
*
*       static constant integer EUCLIDEAN_NORM
*           - Use this as a parameter for the norm method to specify that the method
*             should calculate the euclidean norm (square root of sum of squares).
*
*       static constant integer INFINITY_NORM
*           - Use this as a parameter for the norm method to specify that the method
*             should calculate the infinity norm (maximum of row sum absolute values).
*
*       static constant integer METHOD_ROW_WISE
*           - Use this as a parameter for methods like initStepWise or reShape to
*             specify whether the method should be applied row-wise.
*
*       static constant integer METHOD_COL_WISE
*           - Use this as a parameter for methods like initStepWise or reShape to
*             specify whether the method should be applied col-wise.
*
*
*   Methods
*   -----------------------------
*
*       static method create takes integer nDim, integer mDim returns Matrix
*           - Creates a new n x m Matrix with the maximum size of MAX_MATRIX_SIZE
*             (specified in the globals block). The Matrix is initialized with 
*             zeros.
*
*       method destroy takes nothing returns nothing
*           - Destroys a given Matrix to free its memory usage.
*  
*       method display takes nothing returns nothing
*           - Use this method to display a Matrix ingame. This is especially 
*             meant for debugging issues.
*
*       method isValid takes nothing returns boolean
*           - Checks whether a given Matrix is valid (means: not empty) or not.
*
*       method isEqual takes Matrix mat returns boolean
*           - Checks whether two Matrices are equal or not. If A == B then
*             A.isEqual(B) returns true.
*
*       method init takes real value returns nothing
*           - Use this method to initialize a Matrix with a desired real value. 
*             Note that this method does not create a new instance of the Matrix 
*             object, as well as all methods that only initialize the values of a 
*             Matrix.
*
*       method eye takes nothing returns nothing
*           - Use this method to initialize an Identity Matrix.
*
*       method diag takes real value, integer whichDiagonal returns nothing
*           - Use this method to initialize a Diagonal Matrix with a desired real
*             value. Use the second argument to specify which diagonal you want
*             to set (zero is the main diagonal, negative values address the 
*             upper, positive values the lower diagonals).
*
*       method rand takes real lowerBound, real upperBound returns nothing
*           - Use this method to initialize a Matrix with random real values.
*
*       method initStepWise takes real startValue, real steps returns nothing
*           - Use this method to initialize a matrix from a given start value in
*             ascending or descending order specified by the steps parameter.
*
*       method assign takes nothing returns Matrix
*           - Use this method to assign a Matrix to another Matrix. For example
*             set B = A.assign() will copy A to B. Note that A and B must be of
*             equal size for this operation to work.
*
*       method addScalar takes real value returns Matrix
*           - This method performs a element-wise addition of a given real value
*             and returns the new Matrix. Example: A.addScalar(2.0) will add the
*             value 2.0 to all elements of the Matrix A.
*
*       method subScalar takes real value returns Matrix
*           - This method performs a element-wise subtraction of a given real 
*             value.
*
*       method mulScalar takes real value returns Matrix
*           - This method performs a element-wise multiplication by a given real
*             value.
*
*       method divScalar takes real value returns Matrix
*           - This method performs a element-wise division by a given real value.
*
*       method abs takes nothing returns Matrix
*           - This method performs the abs function on all Matrix elements.
*
*       method add takes Matrix whichMatrix returns Matrix
*           - Matrix addition. The expression A.add(B) where both A and B are
*             Matrices returns the resulting Matrix A + B. Note that the Matrices
*             must follow common Matrix calculation rules, like here that A and B
*             have the same size.
*
*       method sub takes Matrix whichMatrix returns MAtrix
*           - Matrix substraction. Same as the add method, A.sub(B) performs 
*             A - B.
*
*       method multiply takes Matrix whichMatrix returns Matrix
*           - Matrix multiplication. The expression A.multiply(B) performs the
*             operation A*B. Note that A's number of columns must equal B's 
*             number of rows for this operation to be well-defined.
*
*       method transpose takes nothing returns Matrix
*           - Matrix transposition. The expression A.transpose() computes A^T.
*
*       method invert takes nothing returns Matrix
*           - Matrix inversion. Use A.invert() to calculate A^-1, the inverse 
*             of the Matrix A. Be aware of the fact that not every Matrix is
*             invertable.
*
*       method gauss takes nothing returns Matrix
*           - Use this method to perform a Gauss-Elimination with pivotising.
*             The result is a upper triangular Matrix.
*
*       method solveSLE takes Matrix b returns Matrix
*           - Use this method to solve a System of Linear Equations following
*             the common notation A*x = b. To calculate x use A.solveSLE(b) 
*             where A is the system Matrix and b is the solution vector. If the 
*             SLE has no unique solution, an invalid vector of size 0 x 0 is 
*             returned.
*
*       method dotProduct takes Matrix b returns real
*           - Use this method to calculate the dot product of two Vectors. Use
*             it like a.dotProduct(b), which results in a^T*b. Calling this
*             method is faster than performing the transposition manualy and
*             should therefore be used if possible. To check whether two Vectors
*             are orthogonal, the dot product must be zero.
*
*       method crossProduct takes Matrix b returns Matrix
*           - Use this method to calculate the cross product of two Vectors.
*             This implementation only supports calculation of cross products
*             for Vectors in R^3.
*
*       method trace takes nothing returns real
*           - Returns the trace of a given Matrix. Which is defined as the sum 
*             over its diagonal elements.
*
*       method det takes nothing returns real
*           - Returns the determinant of a given Matrix. From A.det() == 0 
*             follows for example that A is not invertable.
*
*       method rank takes nothing returns integer
*           - Returns the rank of a given Matrix. A square Matrix must have full 
*             rank to be invertable, which means that A.rank() == A.n must return
*             true.
*
*       method norm takes integer whichNorm returns real
*           - Computes the norm of a given Matrix. You can choose between different
*             norms by using the constants defined in the Matrix struct. Valid 
*             values for the whichNorm parameter are ONE_NORM, EUCLIDEAN_NORM 
*             and the INFINITY_NORM.
*
*       method cond takes integer whichNorm returns real
*           - Computes the condition of a Matrix. You can specify which Norm you 
*             want to use for that purpose by the parameter whichNorm (see method 
*             norm). Note that the Matrix must be invertable otherwise the 
*             condition will be infinity.
*
*       method subMatrix takes integer startRow, integer startCol, integer endRow, 
*                        integer endCol returns Matrix
*           - This method can be used to get a sub Matrix out of another Matrix.
*             With the parameters startRow and startCol you can specify where
*             the submatrix should begin and the parameters endRow as well as
*             endCol define where to end the sub Matrix. If A is for example
*             a 3 x 3 Matrix, A.subMatrix(0, 0, 2, 0) will return the first
*             column Vector of A, while A.subMatrix(0, 0, 1, 1) will return
*             the first 2 x 2 sub Matrix of A and so on.
*
*       method embed takes Matrix subMat, integer startRow, integer startCol 
*                    returns Matrix
*           - This method embeds one Matrix into another. If you have for example
*             the 3 x 3 Matrix A and the 2 x 2 Matrix B then A.embed(B, 0, 0)
*             will assign the upper left sub matrix of A to the values of B. The 
*             parameters startRow and startCol specify where the embeding should 
*             start. Of course the sub matrix must fit into the Matrix you want to 
*             embed it into, otherwise an error will be thrown.
*
*       method concatH takes Matrix mat returns Matrix
*           - Use this method to concatenate two Matrices. The Matrices must
*             have the same amount of rows for this operation to work. The Matrices
*             will get concatenated horizontal, resulting for  two n x m
*             Matrices in a n x 2*m Matrix. Example: A.concatH(B) will concate-
*             nate A to B (from the left side).
*
*       method concatV takes Matrix mat returns Matrix
*           - Use this method to concatenate two Matrices. The Matrices must
*             have the same amount of columns for this operation to work. The 
*             Matrices will get concatenated vertically, resulting for two n x m
*             Matrices in a 2*n x m Matrix. Example: A.concatV(B) will stack
*             the Matrix B on A.
*
*       method reShape takes integer newN, integer newM, integer whichMethod 
*                      returns Matrix
*           - Use this method to reshape a Matrix. If you have for example a
*             3 x 2 Matrix A, by performing A.reShape(2, 3, METHOD_ROW_WISE)
*             the Matrix will get a 2 x 3 Matrix. The third parameter whichMethod
*             determines whether the operation should be done row-wise or
*             column-wise. METHOD_ROW_WISE and METHOD_COL_WISE are valid
*             parameters. This can also be used to make a Vektor of a Matrix
*             (or vice versa): A.reShape(6, 1, METHOD_COL_WISE) will stack
*             all column Vektors of A to one 6 x 1 Vektor.
*
*       method switchRow takes integer whichRow, integer newRow returns Matrix
*           - Use this method to switch two different rows of a Matrix. The  
*             expression A.switchRow(0, 2) will switch the first with the third 
*             row. Note that both parameters whichRow and newRow must not exceed 
*             Matrix dimensions.
*
*       method switchCol takes integer whichCol, integer newCol returns Matrix
*           - Use this method to switch two different columns of a Matrix. Same
*             rules as for switchRow apply here.
*  
*********************************************************************************/

    globals
        /*************************************************************************
        *   Configurable globals
        *************************************************************************/
    
        // Accuracy for considering a Matrix too close to singularity
        private constant real EPSILON = 0.01 
    
        // Do you want the system to display debug error messages?
        private constant boolean DISPLAY_MATRIX_ERRORS = true
    
        // Biggest possible n x n-Matrix
        private constant integer MAX_MATRIX_SIZE = 50
        
        /*************************************************************************
        *   End of configurable globals
        *************************************************************************/
    endglobals

    private struct MatrixRow
        real array values[MAX_MATRIX_SIZE]
        integer maxCols
    
        method operator [] takes integer column returns real
            return this.values[column]
        endmethod

        method operator []= takes integer column, real value returns nothing
            debug if column < 0 or column >= maxCols then
                debug call ThrowError(true, "Matrices", "[]=", "MatrixRow", this, "Can't access Matrix! Index exceeds Matrix dimensions!")
            debug endif
            set this.values[column] = value
        endmethod
        
        static method create takes integer cols returns thistype
            local thistype this = MatrixRow.allocate()
            set this.maxCols = cols
            return this
        endmethod
    endstruct

    private module Inits
        private static method onInit takes nothing returns nothing
            set Matrix.Invalid_Matrix = Matrix.createInvalid()
        endmethod
    endmodule
    
    struct Matrix
        private MatrixRow array matRow[MAX_MATRIX_SIZE]
        
        static constant integer ONE_NORM = 1
        static constant integer EUCLIDEAN_NORM = 2
        static constant integer INFINITY_NORM = 3
        
        static constant integer METHOD_ROW_WISE = 0
        static constant integer METHOD_COL_WISE = 1
        
        readonly static Matrix Invalid_Matrix
        
        readonly integer n
        readonly integer m
        
        method operator [] takes integer row returns MatrixRow
            debug if row < 0 or row >= n then
                debug call ThrowError(true, "Matrices", "[]", "Matrix", this, "Can't access Matrix! Index exceeds Matrix dimensions!")
            debug endif
            return this.matRow[row]
        endmethod
        
        static method create takes integer nDim, integer mDim returns thistype
            local integer i = 0
            local thistype this 
            
            if nDim < 1 or mDim < 1 then
                debug call ThrowError(true, "Matrices", "create", "Matrix", 0, "Invalid Matrix!")
            endif
            
            set this = Matrix.allocate()
            loop
                exitwhen i > nDim - 1
                set this.matRow[i] = MatrixRow.create(mDim)
                set i = i + 1
            endloop
            set this.n = nDim
            set this.m = mDim
            
            return this
        endmethod
        
        private static method createInvalid takes nothing returns thistype
            local thistype this = Matrix.allocate()

            set this.n = 0
            set this.m = 0
            
            return this
        endmethod
        
        method isValid takes nothing returns boolean
            return this.n == 0
        endmethod
        
        method isEqual takes Matrix mat returns boolean
            local integer i = 0
            local integer j = 0
        
            if this.n != mat.n or this.m != mat.m then
                return false
            endif
            
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    if this.matRow[i][j] != mat[i][j] then
                        return false
                    endif
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return true
        endmethod
        
        method addScalar takes real value returns Matrix
            local integer i = 0
            local integer j = 0
            local Matrix mat
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "addScalar", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = Matrix.create(n, m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set mat[i][j] = this.matRow[i][j] + value
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
        
        method subScalar takes real value returns Matrix
            local integer i = 0
            local integer j = 0
            local Matrix mat
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "subScalar", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = Matrix.create(n, m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set mat[i][j] = this.matRow[i][j] - value
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
        
        method multScalar takes real value returns Matrix
            local integer i = 0
            local integer j = 0
            local Matrix mat
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "multScalar", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = Matrix.create(n, m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set mat[i][j] = this.matRow[i][j]*value
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
        
        method divScalar takes real value returns Matrix
            local integer i = 0
            local integer j = 0
            local Matrix mat
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "divScalar", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = Matrix.create(n, m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set mat[i][j] = this.matRow[i][j]/value
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
        
        method abs takes nothing returns Matrix
            local integer i = 0
            local integer j = 0
            local Matrix mat
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "abs", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = Matrix.create(n, m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    if this.matRow[i][j] >= 0 then
                        set mat[i][j] = this.matRow[i][j]
                    else
                        set mat[i][j] = -this.matRow[i][j]
                    endif
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
        
        method eye takes real value returns nothing
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "eye", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            loop
                exitwhen j >= n
                loop
                    exitwhen i >= m
                    if i != j then
                        set this.matRow[j][i] = 0.0
                    else
                        set this.matRow[j][i] = 1.0
                    endif
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
        endmethod
        
        method diag takes real value, integer whichDiagonal returns nothing
            local integer i = 0
            local integer j = 0
            local integer minDim
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "diag", "Matrix", this, "Invalid Matrix!")
            debug endif
            if n <= m then
                set minDim = n - 1
            else
                set minDim = m - 1
            endif
            
            debug if whichDiagonal > minDim then
                debug call ThrowError(true, "Matrices", "diag", "Matrix", this, "Diagonal Index exceeds Matrix dimensions!")
            debug endif
            
            loop
                exitwhen j >= n
                loop
                    exitwhen i >= m
                    if i != j - whichDiagonal then
                        set this.matRow[j][i] = 0.0
                    else
                        set this.matRow[j][i] = value
                    endif
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
        endmethod
        
        method init takes real value returns nothing
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "init", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            loop
                exitwhen j >= n
                loop
                    exitwhen i >= m
                    set this.matRow[j][i] = value
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
        endmethod
        
        method rand takes real lowerBound, real upperBound returns nothing
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "rand", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            loop
                exitwhen j >= n
                loop
                    exitwhen i >= m
                    set this.matRow[j][i] = GetRandomReal(lowerBound, upperBound)
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
        endmethod
        
        method initStepWise takes real startValue, real step, integer whichMethod returns nothing
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "initStepWise", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if (whichMethod != METHOD_ROW_WISE and whichMethod != METHOD_COL_WISE) then
                debug call ThrowError(true, "Matrices", "initStepWise", "Matrix", this, "Invalid method for initializing!")
            debug endif
            
            if whichMethod == METHOD_ROW_WISE then
                loop
                    exitwhen j >= n
                    loop
                        exitwhen i >= m
                        set this.matRow[j][i] = startValue
                        set startValue = startValue + step
                        set i = i + 1
                    endloop
                    set i = 0
                    set j = j + 1
                endloop
            elseif whichMethod == METHOD_COL_WISE then
                loop
                    exitwhen j >= m
                    loop
                        exitwhen i >= n
                        set this.matRow[i][j] = startValue
                        set startValue = startValue + step
                        set i = i + 1
                    endloop
                    set i = 0
                    set j = j + 1
                endloop
            endif
        endmethod
  
        method add takes Matrix mat returns Matrix
            local Matrix result
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "add", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if mat.n != this.n or mat.m != this.m then
                debug call ThrowError(true, "Matrices", "add", "Matrix", this, "Matrices must be of same dimension!")
            debug endif
            
            set result = Matrix.create(n, m)
            loop
                exitwhen j >= n
                loop
                    exitwhen i >= m
                    set result[j][i] = this.matRow[j][i] + mat[j][i]
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
            
            return result
        endmethod
        
        method sub takes Matrix mat returns Matrix
            local Matrix result
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "sub", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if mat.n != this.n or mat.m != this.m then
                debug call ThrowError(true, "Matrices", "sub", "Matrix", this, "Matrices must be of same dimension!")
            debug endif
            
            set result = Matrix.create(n, m)
            loop
                exitwhen j >= n
                loop
                    exitwhen i >= m
                    set result[j][i] = this.matRow[j][i] - mat[j][i]
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
            
            return result
        endmethod
  
        method multiply takes Matrix mat returns Matrix
            local Matrix result
            local integer i = 0
            local integer j = 0
            local integer k = 0
            local real temp = 0.0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "multiply", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if this.m != mat.n then
                debug call ThrowError(true, "Matrices", "multiply", "Matrix", this, "Matrix dimensions must agree!")
            debug endif
            
            set result = Matrix.create(n, mat.m)
            loop
                exitwhen j >= result.n
                loop
                    exitwhen k >= result.m
                    loop
                        exitwhen i >= this.m
                        set temp = temp + this.matRow[j][i]*mat[i][k]
                        set i = i + 1
                    endloop
                    set result[j][k] = temp
                    set i = 0
                    set temp = 0.0
                    set k = k + 1
                endloop
                set k = 0
                set j = j + 1
            endloop
            
            return result
        endmethod
  
        method transpose takes nothing returns Matrix
            local Matrix mat = Matrix.create(m, n)
            local integer i = 0
            local integer j = 0

            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "transpose", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            loop
                exitwhen j >= m
                loop
                    exitwhen i >= n
                    set mat[j][i] = this.matRow[i][j]
                    set i = i + 1
                endloop
                set i = 0
                set j = j + 1
            endloop
            
            return mat
        endmethod

        method gauss takes nothing returns Matrix
            local Matrix mat
            local integer i = 0
            local integer j = 0
            local integer k = 0
            local integer row
            local real maxVal = -Math.Inf
            local real pivot
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "gauss", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = this.assign() 
            loop
                exitwhen i >= n - 1
                set j = i + 1
                set row = i
                loop
                    exitwhen j >= n
                    set pivot = Math.abs(mat[j][i])
                    if pivot > maxVal then
                        set maxVal = pivot
                        set row = j
                    endif
                    set j = j + 1
                endloop
                
                if row != i then
                    set j = 0
                    loop
                        exitwhen j >= m
                        set pivot = mat[i][j]
                        set mat[i][j] = mat[row][j]
                        set mat[row][j] = pivot
                        set j = j + 1
                    endloop
                endif
                
                set j = i + 1
                loop
                    exitwhen j >= n
                    set pivot = mat[j][i]/mat[i][i]
                    set k = i
                    loop
                        exitwhen k >= n
                        set mat[j][k] = mat[j][k] - pivot*mat[i][k]
                        set k = k + 1
                    endloop
                    set j = j + 1
                endloop
                set i = i + 1
            endloop
        
            return mat
        endmethod
  
        method invert takes nothing returns Matrix
            local Matrix mat
            local Matrix inv
            local integer i = 0
            local integer j = 0
            local integer k = 0
            local integer row
            local real maxVal = -Math.Inf
            local real pivot
            local real temp_inv
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "invert", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = this.assign()
            set inv = Matrix.create(n, n)
            call inv.eye(n)
            loop
                exitwhen i >= n - 1
                set j = i + 1
                set row = i
                loop
                    exitwhen j >= n
                    set pivot = Math.abs(mat[j][i])
                    if pivot > maxVal then
                        set maxVal = pivot
                        set row = j
                    endif
                    set j = j + 1
                endloop
                
                if row != i then
                    set j = 0
                    loop
                        exitwhen j >= m
                        set pivot = mat[i][j]
                        set mat[i][j] = mat[row][j]
                        set mat[row][j] = pivot
                        set temp_inv = inv[i][j]
                        set inv[i][j] = inv[row][j]
                        set inv[row][j] = temp_inv
                        set j = j + 1
                    endloop
                endif
                
                set j = i + 1
                loop
                    exitwhen j >= n
                    set pivot = mat[j][i]/mat[i][i]
                    set k = 0
                    loop
                        exitwhen k >= n
                        set mat[j][k] = mat[j][k] - pivot*mat[i][k]
                        set inv[j][k] = inv[j][k] - pivot*inv[i][k]
                        set k = k + 1
                    endloop
                    set j = j + 1
                endloop
                set i = i + 1
            endloop
            
            set i = n - 1
            loop
                exitwhen i < 0
                set j = i - 1
                loop
                    exitwhen j < 0
                    set pivot = mat[j][i]/mat[i][i]
                    set mat[j][i] = mat[j][i] - pivot*mat[i][i]
                    set k = 0
                    loop
                        exitwhen k >= m
                        set inv[j][k] = inv[j][k] - pivot*inv[i][k]
                        set k = k + 1
                    endloop
                    set j = j - 1
                endloop
                set i = i - 1
            endloop
            
            set i = 0
            loop
                exitwhen i >= n
                set j = 0
                loop
                    exitwhen j >= m
                    set inv[i][j] = inv[i][j]/mat[i][i]
                    set j = j + 1
                endloop
                set i = i + 1
            endloop
            call mat.destroy()
            
            return inv
        endmethod
  
        method trace takes nothing returns real
            local integer i = 0
            local integer minDim
            local real result = 0.0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "trace", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            if n <= m then
                set minDim = n - 1
            else
                set minDim = m - 1
            endif
            
            loop
                exitwhen i > minDim
                set result = result + this.matRow[i][i]
                set i = i + 1
            endloop
        
            return result
        endmethod
        
        method assign takes nothing returns Matrix
            local integer i = 0
            local integer j = 0
            local Matrix mat = Matrix.create(n, m)
            
            if n < 1 then
                set mat = Invalid_Matrix
                return mat
            endif
            
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set mat[i][j] = this.matRow[i][j]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
        
        method rank takes nothing returns integer
            local Matrix mat = this.assign()
            local integer minDim
            local integer i
            local integer rank
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "rank", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            if n <= m then
                set minDim = n - 1
            else
                set minDim = m - 1
            endif
            
            set i = minDim
            set rank = minDim + 1
            set mat = this.gauss()
            
            loop
                exitwhen i < 1
                if Math.abs(mat[i][i]) < EPSILON then
                    set rank = rank - 1
                endif
                set i = i - 1
            endloop
            
            return rank
        endmethod
        
        method cond takes integer whichNorm returns real
            local Matrix mat
            local real result

            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "cond", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            set mat = this.assign()
            set mat = this.multiply(mat.invert())
            set result = mat.norm(whichNorm)
            call mat.destroy()
            return result
        endmethod
        
        method det takes nothing returns real
            local Matrix mat
            local integer i = 0
            local real result = 1.0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "det", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if n != m then
                debug call ThrowError(true, "Matrices", "det", "Matrix", this, "Matrix must be square!")
            debug endif
            
            set mat = this.assign()
            set mat = mat.gauss()
            
            loop
                exitwhen i >= n
                set result = result*mat[i][i]
                set i = i + 1
            endloop
            if Math.abs(result) < EPSILON then
                set result = 0.0
            endif
            
            call mat.destroy()
            return result
        endmethod
    
        method solveSLE takes Matrix b returns Matrix
            local Matrix mat
            local Matrix sol
            local Matrix x
            local integer i = 0
            local integer j = 0
            local integer k = 0
            local integer row
            local real maxVal = -Math.Inf
            local real pivot
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "solveSLE", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if this.n != this.m or b.n != this.n or b.m > 1 then
                debug call ThrowError(true, "Matrices", "solveSLE", "Matrix", this, "Invalid Matrices used! Can't solve SLE!")
            debug endif
            
            set mat = this.assign()
            set sol = b.assign()
            set x = Matrix.create(b.n, 1)
            loop
                exitwhen i >= n - 1
                set j = i + 1
                set row = i
                loop
                    exitwhen j >= n
                    set pivot = Math.abs(mat[j][i])
                    if pivot > maxVal then
                        set maxVal = pivot
                        set row = j
                    endif
                    set j = j + 1
                endloop
                
                if Math.abs(pivot) < EPSILON then
                    return Matrix.Invalid_Matrix
                endif
                
                if row != i then
                    set j = 0
                    loop
                        exitwhen j >= m
                        set pivot = mat[i][j]
                        set mat[i][j] = mat[row][j]
                        set mat[row][j] = pivot
                        set j = j + 1
                    endloop
                    set pivot = sol[i][0]
                    set sol[i][0] = sol[row][0]
                    set sol[row][0] = pivot
                endif
                
                set j = i + 1
                loop
                    exitwhen j >= n
                    set pivot = mat[j][i]/mat[i][i]
                    set k = i
                    loop
                        exitwhen k >= n
                        set mat[j][k] = mat[j][k] - pivot*mat[i][k]
                        set k = k + 1
                    endloop
                    set sol[j][0] = sol[j][0] - pivot*sol[i][0]
                    set j = j + 1
                endloop
                set i = i + 1
            endloop
            
            set x[x.n - 1][0] = sol[x.n - 1][0]/mat[n - 1][n - 1]
            set i = x.n - 2
            loop
                exitwhen i < 0
                set pivot = sol[i][0]
                set j = i + 1
                loop
                    exitwhen j >= n
                    set pivot = pivot - mat[i][j]*x[j][0]
                    set j = j + 1
                endloop
                set x[i][0] = pivot/mat[i][i]
                set i = i - 1
            endloop
            call sol.destroy()
            call mat.destroy()
            
            return x
        endmethod
  
        method norm takes integer whichNorm returns real
            local integer i = 0
            local integer j = 0
            local real result
            local real maxVal = -Math.Inf
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "norm", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if whichNorm != ONE_NORM and whichNorm != EUCLIDEAN_NORM and whichNorm != INFINITY_NORM then
                debug call ThrowError(true, "Matrices", "[]", "Matrix", this, "Invalid Norm used!")
            debug endif
            
            if whichNorm == ONE_NORM then
                set result = 0.0
                loop
                    exitwhen i >= m
                    loop
                        exitwhen j >= n
                        set result = result + Math.abs(this.matRow[j][i])
                        set j = j + 1
                    endloop
                    if result > maxVal then
                        set maxVal = result
                    endif
                    set result = 0.0
                    set j = 0
                    set i = i + 1
                endloop
                return maxVal
            elseif whichNorm == EUCLIDEAN_NORM then
                set result = 0.0
                loop
                    exitwhen i >= n
                    loop
                        exitwhen j >= m
                        set result = result + this.matRow[i][j]*this.matRow[i][j]
                        set j = j + 1
                    endloop
                    set j = 0
                    set i = i + 1
                endloop
                return SquareRoot(result)
            else
                set result = 0.0
                loop
                    exitwhen i >= n
                    loop
                        exitwhen j >= m
                        set result = result + Math.abs(this.matRow[i][j])
                        set j = j + 1
                    endloop
                    if result > maxVal then
                        set maxVal = result
                    endif
                    set result = 0.0
                    set j = 0
                    set i = i + 1
                endloop
                return maxVal
            endif
        endmethod
  
        method dotProduct takes Matrix mat returns real
            local real temp = 0.0
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 or mat.n < 1 then
                debug call ThrowError(true, "Matrices", "dotProduct", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if mat.m != 1 or this.m != 1 then
                debug call ThrowError(true, "Matrices", "dotProduct", "Matrix", this, "Dot-Product is only defined for Vectors!")
            debug endif
            debug if mat.n != this.n then
                debug call ThrowError(true, "Matrices", "dotProduct", "Matrix", this, "Dot-Product is only defined for Vectors of same length!")
            debug endif
            
            loop
                exitwhen i > n
                set temp = temp + this.matRow[i][1]*mat[i][1]
                set i = i + 1
            endloop
            
            return temp
        endmethod
  
        method crossProduct takes Matrix mat returns Matrix
            local Matrix result
        
            debug if n < 1 or mat.n < 1 then
                debug call ThrowError(true, "Matrices", "crossProduct", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if mat.m != 1 or this.m != 1 then
                debug call ThrowError(true, "Matrices", "crossProduct", "Matrix", this, "Cross-Product is only defined for Vectors!")
            debug endif
            debug if mat.n != this.n then
                debug call ThrowError(true, "Matrices", "crossProduct", "Matrix", this, "Cross-Product is only defined for Vectors of same length!")
            debug endif
            debug if mat.n != 3 or this.n != 3 then
                debug call ThrowError(true, "Matrices", "crossProduct", "Matrix", this, "This implementation only supports Cross-Products for Vectors in R^3")
            debug endif
            
            set result = Matrix.create(3, 1)
            set result[0][0] = this.matRow[1][0]*mat[2][0] - this.matRow[2][0]*mat[1][0]
            set result[1][0] = this.matRow[2][0]*mat[0][0] - this.matRow[0][0]*mat[2][0]
            set result[2][0] = this.matRow[0][0]*mat[1][0] - this.matRow[1][0]*mat[0][0]
            
            return result
        endmethod
  
        method reShape takes integer newN, integer newM, integer whichMethod returns Matrix
            local Matrix mat
            local integer i = 0
            local integer j = 0
            local integer row = 0
            local integer col = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "reShape", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if newN*newM != n*m then
                debug call ThrowError(true, "Matrices", "reShape", "Matrix", this, "Reshape not possible! Dimension missmatch!")
            debug endif
            debug if newN < 1 or newM < 1 then
                debug call ThrowError(true, "Matrices", "reShape", "Matrix", this, "Reshape not possible! Index must be greater than zero!")
            debug endif
            debug if n == 0 then
                debug call ThrowError(true, "Matrices", "reShape", "Matrix", this, "Reshape not possible! Matrix is invalid!")
            debug endif
            debug if whichMethod != METHOD_ROW_WISE and whichMethod != METHOD_COL_WISE then
                debug call ThrowError(true, "Matrices", "reShape", "Matrix", this, "Invalid method for reshaping!")
            debug endif
            
            set mat = Matrix.create(newN, newM)
            
            if whichMethod == METHOD_ROW_WISE then
                loop
                    exitwhen i >= n
                    loop
                        exitwhen j >= m
                        set mat[row][col] = this.matRow[i][j]
                        set col = col + 1
                        if col >= mat.m then
                            set row = row + 1
                            set col = 0
                        endif
                        set j = j + 1
                    endloop
                    set j = 0
                    set i = i + 1
                endloop
            elseif whichMethod == METHOD_COL_WISE then
                loop
                    exitwhen i >= m
                    loop
                        exitwhen j >= n
                        set mat[row][col] = this.matRow[j][i]
                        set col = col + 1
                        if col >= mat.m then
                            set row = row + 1
                            set col = 0
                        endif
                        set j = j + 1
                    endloop
                    set j = 0
                    set i = i + 1
                endloop
            endif
            
            return mat
        endmethod
  
        method embed takes Matrix subMat, integer startRow, integer startCol returns Matrix
            local Matrix mat
            local integer i = 0
            local integer j = 0
            
            debug if n == 0 or subMat.n == 0 then
                debug call ThrowError(true, "Matrices", "embed", "Matrix", this, "Can't embed sub Matrix! This is an invalid Matrix!")
            debug endif
            debug if startRow < 0 or startCol < 0 then
                debug call ThrowError(true, "Matrices", "embed", "Matrix", this, "Can't merge Matrices! Index must be greater than 0!")
            debug endif
            debug if startRow + subMat.n - 1 > n or startCol + subMat.m - 1 > m then
                debug call ThrowError(true, "Matrices", "embed", "Matrix", this, "Can't merge Matrices! Matrices don't fit!")
            debug endif
            
            set mat = this.assign()
            loop
                exitwhen i >= subMat.n
                loop
                    exitwhen j >= subMat.m
                    set mat[i + startRow][j + startCol] = subMat[i][j]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
  
        method subMatrix takes integer startRow, integer startCol, integer endRow, integer endCol returns Matrix
            local Matrix mat
            local integer i = 0
            local integer j = 0
            
            debug if n == 0 then
                debug call ThrowError(true, "Matrices", "subMatrix", "Matrix", this, "Can't determine sub Matrix! This is an invalid Matrix!")
            debug endif
            debug if endRow < startRow or endCol < startCol then
                debug call ThrowError(true, "Matrices", "subMatrix", "Matrix", this, "Can't determine sub Matrix! Size of sub Matrix smaller 1 x 1!")
            debug endif
            debug if endRow > n - 1 or endCol > m - 1 then
                debug call ThrowError(true, "Matrices", "subMatrix", "Matrix", this, "Sub Matrix exceeds Matrix dimensions!")
            debug endif
            
            set mat = Matrix.create(endRow - startRow + 1, endCol - startCol + 1)
            loop
                exitwhen i >= mat.n
                loop
                    exitwhen j >= mat.m
                    set mat[i][j] = this.matRow[i + startRow][j + startCol]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return mat
        endmethod
    
        method concatV takes Matrix mat returns Matrix
            local Matrix result
            local integer i = 0
            local integer j = 0
            
            debug if n == 0 or m == 0 then
                debug call ThrowError(true, "Matrices", "concatV", "Matrix", this, "Can't concat Invalid Matrices!")
            debug endif
            debug if m != mat.m then
                debug call ThrowError(true, "Matrices", "concatV", "Matrix", this, "Can't concat Matrices! Matrix column dimensions must be equal!")
            debug endif
    
            set result = Matrix.create(n + mat.n, m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set result[i][j] = mat[i][j]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            set i = 0
            set j = 0
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set result[i + n][j] = this.matRow[i][j]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            
            return result
        endmethod
    
        method concatH takes Matrix mat returns Matrix
            local Matrix result
            local integer i = 0
            local integer j = 0
            
            debug if n == 0 or m == 0 then
                debug call ThrowError(true, "Matrices", "concatH", "Matrix", this, "Can't concat Invalid Matrices!")
            debug endif
            debug if n != mat.n then
                debug call ThrowError(true, "Matrices", "concatH", "Matrix", this, "Can't concat Matrices! Matrix row dimensions must be equal!")
            debug endif
            
            set result = Matrix.create(n, m + mat.m)
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set result[i][j] = this.matRow[i][j]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop
            set i = 0
            set j = 0
            loop
                exitwhen i >= n
                loop
                    exitwhen j >= m
                    set result[i][j + m] = mat[i][j]
                    set j = j + 1
                endloop
                set j = 0
                set i = i + 1
            endloop

            return result
        endmethod
  
        method switchRow takes integer whichRow, integer newRow returns nothing
            local real temp
            local integer i = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "switchRow", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if whichRow < 0 or whichRow >= n or newRow < 0 or newRow >= n then
                debug call ThrowError(true, "Matrices", "switchRow", "Matrix", this, "Can't switch row. Index exceeds Matrix dimensions!")
            debug endif
            
            loop
                exitwhen i >= this.m
                set temp = this.matRow[newRow][i]
                set this.matRow[newRow][i] = this.matRow[whichRow][i]
                set this.matRow[whichRow][i] = temp
                set i = i + 1
            endloop
        endmethod
  
        method switchCol takes integer whichCol, integer newCol returns nothing
            local real temp
            local integer i = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "switchCol", "Matrix", this, "Invalid Matrix!")
            debug endif
            debug if whichCol < 0 or whichCol >= n or newCol < 0 or newCol >= n then
                debug call ThrowError(true, "Matrices", "switchCol", "Matrix", this, "Can't switch column. Index exceeds Matrix dimensions!")
            debug endif
            
            loop
                exitwhen i >= this.n
                set temp = this.matRow[i][newCol]
                set this.matRow[i][newCol] = this.matRow[i][whichCol]
                set this.matRow[i][whichCol] = temp
                set i = i + 1
            endloop
        endmethod
  
        method display takes nothing returns nothing
            local string s = ""
            local integer i = 0
            local integer j = 0
            
            debug if n < 1 then
                debug call ThrowError(true, "Matrices", "display", "Matrix", this, "Invalid Matrix!")
            debug endif
            
            loop
                exitwhen j >= this.n
                loop
                    exitwhen i >= this.m
                    set s = s + " " + R2S(this.matRow[j][i])
                    set i = i + 1
                endloop
                call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 60.0, s)
                set s = ""
                set i = 0
                set j = j + 1
            endloop
        endmethod
        
        implement Inits
    endstruct
endlibrary



JASS:
scope Example initializer Init
    private function Init takes nothing returns nothing
        /**********************************************************************************
        *
        *   Example Code
        *   ¯¯¯¯¯¯¯¯¯¯¯¯
        *
        *   Solves the Linear System of Equations A*x = b for 
        *
        *    [1][4][7]   [x1]   [1]                          [ 0]
        *   [17][5][8] * [x2] = [2]    with the solution x = [ 2] approximately.
        *    [3][6][9]   [x3]   [3]                          [-1]
        *
        *   Feel free to try out more.
        *
        **********************************************************************************/
    
        // Create a 3 x 3 system Matrix A
        local Matrix A = Matrix.create(3, 3)
        
        // Create a 3 x 1 solution Vector b
        local Matrix b = Matrix.create(3, 1)
        
        // Instanciate the unknown Vector x
        local Matrix x

        // Initialize Matrix A in ascending order (col-wise)
        call A.initStepWise(1.0, 1.0, Matrix.METHOD_COL_WISE)
        
        // Set the element in the second row, first column of A to 17.0
        set A[1][0] = 17.0
        
        // Initialize Vector b (row-wise)
        call b.initStepWise(1.0, 1.0, Matrix.METHOD_ROW_WISE)
        
        // Solve SLE
        set x = A.solveSLE(b)

        // Display A, b and x
        call A.display()
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 60.0, " ")
        call b.display()
        call DisplayTimedTextToPlayer(GetLocalPlayer(), 0.0, 0.0, 60.0, " ")
        call x.display()
    endfunction
endscope




Matrix struct


[] operators
Use the [] operators to access directly to the values of a given Matrix. For example mat[2][1] will return the element in the third row, second column. Note that the indices are, like Wc3 arrays, zero-based.

readonly integer n
Specifies the number of rows of a given Matrix.

readonly integer m
Specifies the number of columns of a given Matrix.

readonly static Matrix Invalid_Matrix
An invalid Matrix of the size 0 x 0. You can't create such a Matrix, so if you need one, use this field. Some algorithms, such as solveSLE return such a Matrix if no solution for a given System of Linear Equations could be found. You can use the method isValid() to determine wether a Matrix is valid or not.

static constant integer ONE_NORM
Use this as a parameter for the norm method to specify that the method should calculate the one norm (maximum of column sum absolute values).

static constant integer EUCLIDEAN_NORM
Use this as a parameter for the norm method to specify that the method should calculate the euclidean norm (square root of sum of squares).

static constant integer INFINITY_NORM
Use this as a parameter for the norm method to specify that the method should calculate the infinity norm (maximum of row sum absolute values).

static constant integer METHOD_ROW_WISE
Use this as a parameter for methods like initStepWise or reShape to specify whether the method should be applied row-wise.

static constant integer METHOD_COL_WISE
Use this as a parameter for methods like initStepWise or reShape to specify whether the method should be applied col-wise.

static method create takes integer nDim, integer mDim returns Matrix
Creates a new n x m Matrix with the maximum size of MAX_MATRIX_SIZE (specified in the globals block). The Matrix is initialized with zeros.

method destroy takes nothing returns nothing
Destroys a given Matrix to free its memory usage.

method display takes nothing returns nothing
Use this method to display a Matrix ingame. This is especially meant for debugging issues.

method isValid takes nothing returns boolean
Checks whether a given Matrix is valid (means: not empty) or not.

method isEqual takes Matrix mat returns boolean
Checks whether two Matrices are equal or not. If A == B then A.isEqual(B) returns true.

method init takes real value returns nothing
Use this method to initialize a Matrix with a desired real value. Note that this method does not create a new instance of the Matrix object, as well as all methods that only initialize the values of a Matrix.

method eye takes nothing returns nothing
Use this method to initialize an Identity Matrix.

method diag takes real value, integer whichDiagonal returns nothing
Use this method to initialize a Diagonal Matrix with a desired real value. Use the second argument to specify which diagonal you want to set (zero is the main diagonal, negative values address the upper, positive values the lower diagonals).

method rand takes real lowerBound, real upperBound returns nothing
Use this method to initialize a Matrix with random real values.

method initStepWise takes real startValue, real steps returns nothing
Use this method to initialize a matrix from a given start value in ascending or descending order specified by the steps parameter.

method assign takes nothing returns Matrix
Use this method to assign a Matrix to another Matrix. For example set B = A.assign() will copy A to B. Note that A and B must be of equal size for this operation to work.

method addScalar takes real value returns Matrix
This method performs a element-wise addition of a given real value and returns the new Matrix. Example: A.addScalar(2.0) will add the value 2.0 to all elements of the Matrix A.

method subScalar takes real value returns Matrix
This method performs a element-wise subtraction of a given real value.

method mulScalar takes real value returns Matrix
This method performs a element-wise multiplication by a given real value.

method divScalar takes real value returns Matrix
This method performs a element-wise division by a given real value.

method abs takes nothing returns Matrix
This method performs the abs function on all Matrix elements.

method add takes Matrix whichMatrix returns Matrix
Matrix addition. The expression A.add(B) where both A and B are Matrices returns the resulting Matrix A + B. Note that the Matrices must follow common Matrix calculation rules, like here that A and B have the same size.

method sub takes Matrix whichMatrix returns Matrix
Matrix substraction. Same as the add method, A.sub(B) performs A - B.

method multiply takes Matrix whichMatrix returns Matrix
Matrix multiplication. The expression A.multiply(B) performs the operation A*B. Note that A's number of columns must equal B's number of rows for this operation to be well-defined.

method transpose takes nothing returns Matrix
Matrix transposition. The expression A.transpose() computes A^T.

method invert takes nothing returns Matrix
Matrix inversion. Use A.invert() to calculate A^-1, the inverse of the Matrix A. Be aware of the fact that not every Matrix is invertable.

method gauss takes nothing returns Matrix
Use this method to perform a Gauss-Elimination with pivotising. The result is a upper triangular Matrix.

method solveSLE takes Matrix b returns Matrix
Use this method to solve a System of Linear Equations following the common notation A*x = b. To calculate x use A.solveSLE(b) where A is the system Matrix and b is the solution vector. If the SLE has no unique solution, an invalid vector of size 0 x 0 is returned.

method dotProduct takes Matrix b returns real
Use this method to calculate the dot product of two Vectors. Use it like a.dotProduct(b), which results in a^T*b. Calling this method is faster than performing the transposition manualy and should therefore be used if possible. To check whether two Vectors are orthogonal, the dot product must be zero.

method crossProduct takes Matrix b returns Matrix
Use this method to calculate the cross product of two Vectors. This implementation only supports calculation of cross products for Vectors in R^3.

method trace takes nothing returns real
Returns the trace of a given Matrix. Which is defined as the sum over its diagonal elements.

method det takes nothing returns real
Returns the determinant of a given Matrix. From A.det() == 0 follows for example that A is not invertable.

method rank takes nothing returns integer
Returns the rank of a given Matrix. A square Matrix must have full rank to be invertable, which means that A.rank() == A.n must return true.

method norm takes integer whichNorm returns real
Computes the norm of a given Matrix. You can choose between different norms by using the constants defined in the Matrix struct. Valid values for the whichNorm parameter are ONE_NORM, EUCLIDEAN_NORM and the INFINITY_NORM.

method cond takes integer whichNorm returns real
Computes the condition of a Matrix. You can specify which Norm you want to use for that purpose by the parameter whichNorm (see method norm). Note that the Matrix must be invertable otherwise the condition will be infinity.

method subMatrix takes integer startRow, integer startCol, integer endRow, integer endCol returns Matrix
This method can be used to get a sub Matrix out of another Matrix. With the parameters startRow and startCol you can specify where the submatrix should begin and the parameters endRow as well as endCol define where to end the sub Matrix. If A is for example a 3 x 3 Matrix, A.subMatrix(0, 0, 2, 0) will return the first column Vector of A, while A.subMatrix(0, 0, 1, 1) will return the first 2 x 2 sub Matrix of A and so on.

method embed takes Matrix subMat, integer startRow, integer startCol returns Matrix
This method embeds one Matrix into another. If you have for example the 3 x 3 Matrix A and the 2 x 2 Matrix B then A.embed(B, 0, 0) will assign the upper left sub matrix of A to the values of B. The parameters startRow and startCol specify where the embeding should start. Of course the sub matrix must fit into the Matrix you want to embed it into, otherwise an error will be thrown.

method concatH takes Matrix mat returns Matrix
Use this method to concatenate two Matrices. The Matrices must have the same amount of rows for this operation to work. The Matrices will get concatenated horizontal, resulting for two n x m Matrices in a n x 2*m Matrix. Example: A.concatH(B) will concatenate A to B (from the left side).

method concatV takes Matrix mat returns Matrix
Use this method to concatenate two Matrices. The Matrices must have the same amount of columns for this operation to work. The Matrices will get concatenated vertically, resulting for two n x m Matrices in a 2*n x m Matrix. Example: A.concatV(B) will stack the Matrix B on A.

method reShape takes integer newN, integer newM, integer whichMethod returns Matrix
Use this method to reshape a Matrix. If you have for example a 3 x 2 Matrix A, by performing A.reShape(2, 3, METHOD_ROW_WISE) the Matrix will get a 2 x 3 Matrix. The third parameter whichMethod determines whether the operation should be done row-wise or column-wise. METHOD_ROW_WISE and METHOD_COL_WISE are valid parameters. This can also be used to make a Vektor of a Matrix (or vice versa): A.reShape(6, 1, METHOD_COL_WISE) will stack all column Vektors of A to one 6 x 1 Vektor.

method switchRow takes integer whichRow, integer newRow returns Matrix
Use this method to switch two different rows of a Matrix. The expression A.switchRow(0, 2) will switch the first with the third row. Note that both parameters whichRow and newRow must not exceed Matrix dimensions.

method switchCol takes integer whichCol, integer newCol returns Matrix
Use this method to switch two different columns of a Matrix. Same rules as for switchRow apply here.




4. Screenshots

Enclosed are some screenshots of the testmap, showing some of the ingame calculations from the MathParser Extension.


calc1m.png


calc2w.png


calc3.png




5. Accuracy and Performance

The following tables show the accuracy of the natural logarithm function which is used to calculate al other logarithms as well as the hyperbolic functions and their inverses. Also performance for all math functions is displayed in an extra table. Finally the efficiency of the isPrime method is analysed and compared towards the standard brute force attempt.



As it is shown in the following table, the logarithm reaches extremly high accuracies. This is important because
many other functions can be computed by using logarithms, therefore high acuracy is required. The logarithm
functions Ln1 to Ln5 from the table were taken from this Snippet by BlinkBoy.

table1u.png


The following table shows the OP-Limit values for new math functions. As the table shows, nearly all functions
are very efficient and can be used without any problems. Critical methods in terms of performance are isPrime,
mergeFloat and the factorial of an integer number.

table2new.png


The diagram shows the efficiency of the isPrime method. The system uses a deterministic version of the Miller-
Rabin test. While the standard brute-force attempt can only detect primes up to ~5003 before it hits the OP-Limit,
this method can detect much higher primes. As the diagram shows, the OP-Limit is quite alternating but stays
basically at the same mean. This method allows to detect primes efficiently up to ~100000.

millerrabin.jpg



Hope you enjoy it!

Greetings,
lfh

Keywords:
Advanced Mathematics, Math, Calculator, Ingame calculator, interpreter, logarithm, hyperbolic
Contents

Advanced Mathematics (Map)

Reviews
Advanced Maths & Ingame Calculator | Reviewed by Maker | 18th Jun 2013 APPROVED [tr] This can be useful, but I'd rather use a calculator. Good job none the less.
Level 14
Joined
Dec 12, 2012
Messages
1,007
Why are you using custom Pi and e as there are native constants for those?

Because the custom ones are more accurate than the native ones. Try this:

JASS:
function AccuracyTest takes nothing returns nothing
    call BJDebugMsg(R2S(bj_PI*bj_PI*bj_PI*bj_PI*bj_PI*bj_PI*bj_PI*bj_PI))
    call BJDebugMsg(R2S(Math.Pi*Math.Pi*Math.Pi*Math.Pi*Math.Pi*Math.Pi*Math.Pi*Math.Pi))
endfunction

It will display

9488.462 for bj_PI and
9488.537 for Math.Pi while
9488.531... is the correct value.

The value 3.141593 is the best in terms of accuracy which doesn't bug (higher accuracies can cause bugs under some circumstances). Therefore it makes sense to use custom values for both Pi and E.

And how can I input those?

What do you mean? Input them into the system?
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
Update to Version 1.1.0.0
- Reworked the basic Maths library
- Removed redundant functions like rand, sin, cos etc
- Now using ErrorMessage for having normal behaviour and standard output
- Renamed the StringParser library to MathParser
- MathParser library is now no longer an optional module but a seperated struct which requires Maths
- Added the new library Matrices to the documentation as well as to the testmap
 
1+1 ? Very good tool for noobs tho! 5/5 works perfectly

I don't think you understand what this is actually capable of. This isn't a "1+1" sort of calculator. It's not something you take out to do your homework with. It's for all sorts of high level calculations that you might need to be automatically done in-game. Yeah, even if you know calculus, you're not going to be there in-game to pause and run the calculation on paper every time the trigger needing it goes through. You need a system that can automatically run these calculations for your script throughout the game, and that's what this does.

It's not just "noobs" who would find use in this. In fact, it's noobs (likely you, even) who won't find use in this because they've never tried to use that sort of math while scripting and don't see this system's potential for use. It really annoys me when some newbie goes to a very advanced and adequate system and tries to pretend he's above its level.
 
Level 15
Joined
Oct 29, 2012
Messages
1,474
I don't think you understand what this is actually capable of. This isn't a "1+1" sort of calculator. It's not something you take out to do your homework with. It's for all sorts of high level calculations that you might need to be automatically done in-game. Yeah, even if you know calculus, you're not going to be there in-game to pause and run the calculation on paper every time the trigger needing it goes through. You need a system that can automatically run these calculations for your script throughout the game, and that's what this does.

It's not just "noobs" who would find use in this. In fact, it's noobs (likely you, even) who won't find use in this because they've never tried to use that sort of math while scripting and don't see this system's potential for use. It really annoys me when some newbie goes to a very advanced and adequate system and tries to pretend he's above its level.

Mr. Dude , I know that this tool is useful while scripting , But scripting in game? XD
I am noob I accept? -_____________-
 
I know that this tool is useful while scripting , But scripting in game?

You don't script in-game, no one even said that... I think you're misunderstanding his explanation...

Sometimes you want to make systems that require such complex calculations, that is where this system comes in...

or maybe you simply thought that the included calculator is the core of this system, which is not as that is just a simple example of how to use this system...

and unless you actually know those calculations in real life, I doubt that you'll likely to use this system (or at least use it effectively)...
 
Level 14
Joined
Dec 12, 2012
Messages
1,007
The last thing it needs is binary to decimal converter (and vice-versa). I made one if you want.

Hi, yes why not. You can post it in the Jass section, once it got approved I can add it to this collection.

so many fucking noob comments.. anyway you have an error in the matrix lib line 1168 should be debug endif instead of just endif

Nice find, thanks! Updated Matrix library to version 1.1.0.1.
 
Level 4
Joined
Jul 13, 2012
Messages
86
I would make the same question.
A cientific calculator would be much better than implementing the system and increasing the map size with add-ins.
Or... this is useful when the user doesn't have a calculator at home. I still like the idea.

Geez, at least you don't have to get a calculator, or alt-tab for a calculator. THIS IS GREAT

Many haters, keep hating...
 
I would make the same question.
A cientific calculator would be much better than implementing the system and increasing the map size with add-ins.
Or... this is useful when the user doesn't have a calculator at home. I still like the idea.

Here we go, another one...

This isn't just for spitting out answers to do your math homework. This is for allowing your triggers to automatically do calculations in-game that they couldn't normally, when needing to calculate certain integer or real values to use for something.

If you don't know what this could be used for, you probably don't know anywhere near enough about writing code to have a use for this in the first place.

I'm not saying I'm pro; I don't write JASS and won't have much use for this system myself, however I at least have a good enough understanding of it to know what it can be used for.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
Here we go, another one...

This isn't just for spitting out answers to do your math homework. This is for allowing your triggers to automatically do calculations in-game that they couldn't normally, when needing to calculate certain integer or real values to use for something.

If you don't know what this could be used for, you probably don't know anywhere near enough about writing code to have a use for this in the first place.

I'm not saying I'm pro; I don't write JASS and won't have much use for this system myself, however I at least have a good enough understanding of it to know what it can be used for.

Hahaha, another one bites the dust.
 

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
This is for allowing your triggers to automatically do calculations in-game that they couldn't normally, when needing to calculate certain integer or real values to use for something.

bullshit detected. If you can create a system that calculate something you can obviously calculate whatever it is, in game by yourself since both of you are using the same language (in the end it all ends up as jass).
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
bullshit detected. If you can create a system that calculate something you can obviously calculate whatever it is, in game by yourself since both of you are using the same language (in the end it all ends up as jass).

But it is easier, example instead of creating all the codes for calculating logarithms, factorials, natural logarithms, isPrime, etc., with this system, it is already at your disposal with just using a function and some copy pasting.
Just like the reason why people use systems, for easy use.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
I never said that it couldn't be useful. However I fail to see why you would used so advanced calculations in wc3 modding so the usage seems limited. Anyway, did not come here to say that.


This is what I replied to.

A lot of natural phenomenon has a logarithmic rate. Maybe you want to imitate/simulate that or something. It's depends on someone's creativity if he will find this useful or not. Maybe this is useful in Missile system that wants a very accurate representation of i.e. projectile motions. Another example is if you want to create a spell called Capacitor Charging that increases damage based on the exponential rate of a capacitor's increase in voltage. It would be impossible to do this if you don't know how to create a custom log function. This system allows us to use a lot of mathematical functions out there.

>This is what I replied to
For example you want to know if a certain variable is prime for whatever reason, there is no way to do this using a native Jass function. Then this will come in handy.
 
Last edited:

Chaosy

Tutorial Reviewer
Level 40
Joined
Jun 9, 2011
Messages
13,183
For example you want to know if a certain variable is prime for whatever reason, there is no way to do this using a native Jass function. Then this will come in handy.

If there's a system for it, you can do it yourself. Since this calculator can check if it's a prime number, then your code can as well. Worth it? depends.
Once again, I never said that it isn't handy. The quote stated that it simply was impossible to do the math without the system, which is wrong.
 
Level 22
Joined
Feb 6, 2014
Messages
2,466
If there's a system for it, you can do it yourself. Since this calculator can check if it's a prime number, then your code can as well. Worth it? depends.
Once again, I never said that it isn't handy. The quote stated that it simply was impossible to do the math without the system, which is wrong.

Tell me, how can a someone simply make a code that check if a number is prime number? It's not something you can easily do without having to research a lot. From my perspective, that is what Infernal Tater mean. There is no native function that checks if a number is prime. One does not simply able to know if a number is prime in-game. People couldn't normally do that and people couldn't normally make a function that checks if a number is prime.
 
I never said that it couldn't be useful. However I fail to see why you would used so advanced calculations in wc3 modding so the usage seems limited. Anyway, did not come here to say that.


This is what I replied to.

You can't normally; not without writing complex code to do so.

Sure, if a number is seven, you know yourself that it is prime, but the game will have no clue unless you write code to determine it; there is no in-game function for it.

Just like you can't normally save data as an elaborate encoded line of text that players can type to load in future games, without using a system either written by yourself or someone else.

It's a system. It doesn't mean you can't do it yourself, but you can't do it without writing a lot of code yourself; the point of this system is to save you the time. Every system can technically be done yourself; it was made by another human being, and you're a human being. You could spend years learning to JASS. You could then spend weeks writing your own systems. You can do it all yourself if you want to, and there's nothing wrong with that. But that doesn't mean that everything is "useless", it saves other people time.

When you buy food, by your definition, it would be "useless" because you can obtain and cook food yourself; all your purchase did was save you time. When you bought your computer/bought parts to build your computer, you could have spend your life learning how to build computer parts, and built it yourself. So your motherboard was useless. Your house is "useless" because you could build one yourself over time.

Do you see the point I'm trying to make? Just because you can do something yourself doesn't make it useless. Everything you get is prepared by other people to save you time and effort. That doesn't make it useless.
 
Last edited:
Level 14
Joined
Dec 12, 2012
Messages
1,007
If there's a system for it, you can do it yourself.

Of course. But thats nothing new, right?

The whole point of systems is that not everyone has do do everything himself ;)

Since this calculator can check if it's a prime number, then your code can as well. Worth it? depends.

Maybe you misunderstood something here. This is not really a single system but more a math framework. So the calculator and the math core (where the isPrime function is located) are not the same thing.
Of course you can write your own prime checking method, but doing this efficient is not as easy as it seems at first. Thats why this library uses the Miller-Rabin test which is very efficient.

But Shadow Flux and InfernalTater explained that quite nicely already ;)

Magtheridon96 said:
Pollard-Rho for Integer Factorization!
Just for the heck of it!

Hm, maybe, I will take a look at it ;)
 
Level 24
Joined
Aug 1, 2013
Messages
4,657
I was wondering...
JASS:
        static method isPrime takes integer n returns boolean
            local integer s 
            local integer d
            local integer a = 2
            local integer temp
            local integer counter
            local integer dSave
            local integer modulus
            local boolean firstTest = false
            local boolean secondTest = false

            if n == 2 or n == 7 or n == 61 then
                return true
            elseif isEven(n) or n < 2 then
                return false
            endif
            
            static if STORE_DETECTED_PRIMES then
                if LoadBoolean(h, n, 0) then
                    return LoadBoolean(h, n, 1)
                endif
            endif

            if n < 157 then
                set a = n
                loop
                    exitwhen a == 1
                    if modInt(n, a) == 0 and a != n then
                        static if STORE_DETECTED_PRIMES then
                            call SaveBoolean(h, n, 0, true)
                            call SaveBoolean(h, n, 1, false)
                        endif
                        return false
                    endif
                    set a = a - 1
                endloop
                static if STORE_DETECTED_PRIMES then
                    call SaveBoolean(h, n, 0, true)
                    call SaveBoolean(h, n, 1, true)
                endif
                return true
            endif
            
            set s = R2I(floor(log2(n - 1)))
            loop
                set temp = R2I(Pow(2, I2R(s)))
                exitwhen modInt(n - 1, temp) == 0
                set s = s - 1
            endloop

            set d = (n - 1)/(R2I(Pow(2, I2R(s))))
            set dSave = d
            set a = 2
            set counter = 0
            loop
                exitwhen counter > s
                set modulus = expMod(a, d, n)
                if (counter == 0 and modulus == 1) or (counter > 0 and modulus - n == -1) then
                    set firstTest = true
                    exitwhen true
                endif
                set d = 2*d

                set counter = counter + 1
                if counter == 1 then
                    set d = dSave
                endif
            endloop

            if not firstTest then
                static if STORE_DETECTED_PRIMES then
                    call SaveBoolean(h, n, 0, true)
                    call SaveBoolean(h, n, 1, false)
                endif
                return false
            endif
            
            set a = 7
            set d = dSave
            set counter = 0
            loop
                exitwhen counter > s
                set modulus = expMod(a, d, n)
                if (counter == 0 and modulus == 1) or (counter > 0 and modulus - n == -1) then
                    if firstTest then
                        set secondTest = true
                        exitwhen true
                    endif
                endif
                set d = 2*d

                set counter = counter + 1
                if counter == 1 then
                    set d = dSave
                endif
            endloop

            if not secondTest then
                static if STORE_DETECTED_PRIMES then
                    call SaveBoolean(h, n, 0, true)
                    call SaveBoolean(h, n, 1, false)
                endif
                return false
            endif
            
            set a = 61
            set d = dSave
            set counter = 0
            loop
                exitwhen counter > s
                set modulus = expMod(a, d, n)
                if (counter == 0 and modulus == 1) or (counter > 0 and modulus - n == -1) then
                    if secondTest then
                        static if STORE_DETECTED_PRIMES then
                            call SaveBoolean(h, n, 0, true)
                            call SaveBoolean(h, n, 1, true)
                        endif
                        return true
                    endif
                endif
                set d = 2*d
                
                set counter = counter + 1
                if counter == 1 then
                    set d = dSave
                endif
            endloop
                
            static if STORE_DETECTED_PRIMES then
                call SaveBoolean(h, n, 0, true)
                call SaveBoolean(h, n, 1, false)
            endif
            return false
        endmethod
vs
JASS:
        //Returns wether num is a prime or not.
        static method isPrime takes integer num returns boolean
            local integer i
            local real x
            local integer max
            
            if num == 2 then
                //num is 2. (Only even prime.)
                return true
            endif
            if num == 1 or num <= 0 or modInt(num, 2) == 0 then
                //num is 1, not positive or num is dividable by 2. (2 itself is already filtered out.)
                return false
            endif
            
            set i = 3
            set max = R2I(SquareRoot(num))//No need to check if 99*x = 101. At max 10*10 would be "usefull" to check.
            loop
                exitwhen i > max
                
                //If num is dividable by i, then it is not a prime.
                //if modInt(num, i) == 0. then
                //    return false
                //endif
                //Now that we are talking about uninteresting stuff. Lets remove half of the mod:
                set x = I2R(num)/i
                if x == R2I(x) then
                    // num/i is an integer.
                    return false
                endif
                
                set i = i +2
            endloop
            
            return true
        endmethod
I am sorry for not trying to understand your "isPrime", but as far as I can see, mine is much easier to understand and may be quite a bit faster.
Another approach would be slightly the same but instead of "i+=2", you do "nextPrime()", knowing integers are 2^31-1 at max and the squareroot of that is <46341, you only need all primes listed until 46337 (the last prime before 46341)... which actually fits inside a normal array.... so:
JASS:
    function isPrime takes integer num returns boolean
        local integer i
        local real x
        local integer max
        
        if num == 1 or num <= 0 then
            return false
        endif
        
        set i = 0
        set max = R2I(SquareRoot(num))
        loop
            exitwhen PRIMES[i] > max
            
            set x = I2R(num)/PRIMES[i]
            if x == R2I(x) then
                return false
            endif
            
            set i = i +1
        endloop
        return true
    endfunction
    
    
    function Init takes nothing returns nothing
        set PRIMES[0] = 2
        set PRIMES[1] = 3
        set PRIMES[2] = 5
        set PRIMES[3] = 7
        set PRIMES[4] = 11
        set PRIMES[5] = 13
        set PRIMES[6] = 17
        set PRIMES[7] = 19
        set PRIMES[8] = 23
        set PRIMES[9] = 29
        set PRIMES[10] = 31
        set PRIMES[11] = 37
        set PRIMES[12] = 41
        set PRIMES[13] = 43
        set PRIMES[14] = 47
        set PRIMES[15] = 53
        set PRIMES[16] = 59
        set PRIMES[17] = 61
        set PRIMES[18] = 67
        set PRIMES[19] = 71
        set PRIMES[20] = 73
        set PRIMES[21] = 79
        set PRIMES[22] = 83
        set PRIMES[23] = 89
        set PRIMES[24] = 97
        set PRIMES[25] = 101
        set PRIMES[26] = 103
        set PRIMES[27] = 107
        set PRIMES[28] = 109
        set PRIMES[29] = 113
        set PRIMES[30] = 127
        set PRIMES[31] = 131
        set PRIMES[32] = 137
        set PRIMES[33] = 139
        set PRIMES[34] = 149
        set PRIMES[35] = 151
        set PRIMES[36] = 157
        set PRIMES[37] = 163
        set PRIMES[38] = 167
        set PRIMES[39] = 173
        set PRIMES[40] = 179
        set PRIMES[41] = 181
        set PRIMES[42] = 191
        set PRIMES[43] = 193
        set PRIMES[44] = 197
        set PRIMES[45] = 199
        set PRIMES[46] = 211
        set PRIMES[47] = 223
        set PRIMES[48] = 227
        set PRIMES[49] = 229
        set PRIMES[50] = 233
        set PRIMES[51] = 239
        set PRIMES[52] = 241
        set PRIMES[53] = 251
        set PRIMES[54] = 257
        set PRIMES[55] = 263
        set PRIMES[56] = 269
        set PRIMES[57] = 271
        set PRIMES[58] = 277
        set PRIMES[59] = 281
        set PRIMES[60] = 283
        set PRIMES[61] = 293
        set PRIMES[62] = 307
        set PRIMES[63] = 311
        set PRIMES[64] = 313
        set PRIMES[65] = 317
        set PRIMES[66] = 331
        set PRIMES[67] = 337
        set PRIMES[68] = 347
        set PRIMES[69] = 349
        set PRIMES[70] = 353
        set PRIMES[71] = 359
        set PRIMES[72] = 367
        set PRIMES[73] = 373
        set PRIMES[74] = 379
        set PRIMES[75] = 383
        set PRIMES[76] = 389
        set PRIMES[77] = 397
        set PRIMES[78] = 401
        set PRIMES[79] = 409
        set PRIMES[80] = 419
        set PRIMES[81] = 421
        set PRIMES[82] = 431
        set PRIMES[83] = 433
        set PRIMES[84] = 439
        set PRIMES[85] = 443
        set PRIMES[86] = 449
        set PRIMES[87] = 457
        set PRIMES[88] = 461
        set PRIMES[89] = 463
        set PRIMES[90] = 467
        set PRIMES[91] = 479
        set PRIMES[92] = 487
        set PRIMES[93] = 491
        set PRIMES[94] = 499
        set PRIMES[95] = 503
        set PRIMES[96] = 509
        set PRIMES[97] = 521
        set PRIMES[98] = 523
        set PRIMES[99] = 541
        set PRIMES[100] = 547
        set PRIMES[101] = 557
        set PRIMES[102] = 563
        set PRIMES[103] = 569
        set PRIMES[104] = 571
        set PRIMES[105] = 577
        set PRIMES[106] = 587
        set PRIMES[107] = 593
        set PRIMES[108] = 599
        set PRIMES[109] = 601
        set PRIMES[110] = 607
        set PRIMES[111] = 613
        set PRIMES[112] = 617
        set PRIMES[113] = 619
        set PRIMES[114] = 631
        set PRIMES[115] = 641
        set PRIMES[116] = 643
        set PRIMES[117] = 647
        set PRIMES[118] = 653
        set PRIMES[119] = 659
        set PRIMES[120] = 661
        set PRIMES[121] = 673
        set PRIMES[122] = 677
        set PRIMES[123] = 683
        set PRIMES[124] = 691
        set PRIMES[125] = 701
        set PRIMES[126] = 709
        set PRIMES[127] = 719
        set PRIMES[128] = 727
        set PRIMES[129] = 733
        set PRIMES[130] = 739
        set PRIMES[131] = 743
        set PRIMES[132] = 751
        set PRIMES[133] = 757
        set PRIMES[134] = 761
        set PRIMES[135] = 769
        set PRIMES[136] = 773
        set PRIMES[137] = 787
        set PRIMES[138] = 797
        set PRIMES[139] = 809
        set PRIMES[140] = 811
        set PRIMES[141] = 821
        set PRIMES[142] = 823
        set PRIMES[143] = 827
        set PRIMES[144] = 829
        set PRIMES[145] = 839
        set PRIMES[146] = 853
        set PRIMES[147] = 857
        set PRIMES[148] = 859
        set PRIMES[149] = 863
        set PRIMES[150] = 877
        set PRIMES[151] = 881
        set PRIMES[152] = 883
        set PRIMES[153] = 887
        set PRIMES[154] = 907
        set PRIMES[155] = 911
        set PRIMES[156] = 919
        set PRIMES[157] = 929
        set PRIMES[158] = 937
        set PRIMES[159] = 941
        set PRIMES[160] = 947
        set PRIMES[161] = 953
        set PRIMES[162] = 967
        set PRIMES[163] = 971
        set PRIMES[164] = 977
        set PRIMES[165] = 983
        set PRIMES[166] = 991
        set PRIMES[167] = 997
        set PRIMES[168] = 1009
        set PRIMES[169] = 1013
        set PRIMES[170] = 1019
        set PRIMES[171] = 1021
        set PRIMES[172] = 1031
        set PRIMES[173] = 1033
        set PRIMES[174] = 1039
        set PRIMES[175] = 1049
        set PRIMES[176] = 1051
        set PRIMES[177] = 1061
        set PRIMES[178] = 1063
        set PRIMES[179] = 1069
        set PRIMES[180] = 1087
        set PRIMES[181] = 1091
        set PRIMES[182] = 1093
        set PRIMES[183] = 1097
        set PRIMES[184] = 1103
        set PRIMES[185] = 1109
        set PRIMES[186] = 1117
        set PRIMES[187] = 1123
        set PRIMES[188] = 1129
        set PRIMES[189] = 1151
        set PRIMES[190] = 1153
        set PRIMES[191] = 1163
        set PRIMES[192] = 1171
        set PRIMES[193] = 1181
        set PRIMES[194] = 1187
        set PRIMES[195] = 1193
        set PRIMES[196] = 1201
        set PRIMES[197] = 1213
        set PRIMES[198] = 1217
        set PRIMES[199] = 1223
        set PRIMES[200] = 1229
        set PRIMES[201] = 1231
        set PRIMES[202] = 1237
        set PRIMES[203] = 1249
        set PRIMES[204] = 1259
        set PRIMES[205] = 1277
        set PRIMES[206] = 1279
        set PRIMES[207] = 1283
        set PRIMES[208] = 1289
        set PRIMES[209] = 1291
        set PRIMES[210] = 1297
        set PRIMES[211] = 1301
        set PRIMES[212] = 1303
        set PRIMES[213] = 1307
        set PRIMES[214] = 1319
        set PRIMES[215] = 1321
        set PRIMES[216] = 1327
        set PRIMES[217] = 1361
        set PRIMES[218] = 1367
        set PRIMES[219] = 1373
        set PRIMES[220] = 1381
        set PRIMES[221] = 1399
        set PRIMES[222] = 1409
        set PRIMES[223] = 1423
        set PRIMES[224] = 1427
        set PRIMES[225] = 1429
        set PRIMES[226] = 1433
        set PRIMES[227] = 1439
        set PRIMES[228] = 1447
        set PRIMES[229] = 1451
        set PRIMES[230] = 1453
        set PRIMES[231] = 1459
        set PRIMES[232] = 1471
        set PRIMES[233] = 1481
        set PRIMES[234] = 1483
        set PRIMES[235] = 1487
        set PRIMES[236] = 1489
        set PRIMES[237] = 1493
        set PRIMES[238] = 1499
        set PRIMES[239] = 1511
        set PRIMES[240] = 1523
        set PRIMES[241] = 1531
        set PRIMES[242] = 1543
        set PRIMES[243] = 1549
        set PRIMES[244] = 1553
        set PRIMES[245] = 1559
        set PRIMES[246] = 1567
        set PRIMES[247] = 1571
        set PRIMES[248] = 1579
        set PRIMES[249] = 1583
        set PRIMES[250] = 1597
        set PRIMES[251] = 1601
        set PRIMES[252] = 1607
        set PRIMES[253] = 1609
        set PRIMES[254] = 1613
        set PRIMES[255] = 1619
        set PRIMES[256] = 1621
        set PRIMES[257] = 1627
        set PRIMES[258] = 1637
        set PRIMES[259] = 1657
        set PRIMES[260] = 1663
        set PRIMES[261] = 1667
        set PRIMES[262] = 1669
        set PRIMES[263] = 1693
        set PRIMES[264] = 1697
        set PRIMES[265] = 1699
        set PRIMES[266] = 1709
        set PRIMES[267] = 1721
        set PRIMES[268] = 1723
        set PRIMES[269] = 1733
        set PRIMES[270] = 1741
        set PRIMES[271] = 1747
        set PRIMES[272] = 1753
        set PRIMES[273] = 1759
        set PRIMES[274] = 1777
        set PRIMES[275] = 1783
        set PRIMES[276] = 1787
        set PRIMES[277] = 1789
        set PRIMES[278] = 1801
        set PRIMES[279] = 1811
        set PRIMES[280] = 1823
        set PRIMES[281] = 1831
        set PRIMES[282] = 1847
        set PRIMES[283] = 1861
        set PRIMES[284] = 1867
        set PRIMES[285] = 1871
        set PRIMES[286] = 1873
        set PRIMES[287] = 1877
        set PRIMES[288] = 1879
        set PRIMES[289] = 1889
        set PRIMES[290] = 1901
        set PRIMES[291] = 1907
        set PRIMES[292] = 1913
        set PRIMES[293] = 1931
        set PRIMES[294] = 1933
        set PRIMES[295] = 1949
        set PRIMES[296] = 1951
        set PRIMES[297] = 1973
        set PRIMES[298] = 1979
        set PRIMES[299] = 1987
        set PRIMES[300] = 1993
        set PRIMES[301] = 1997
        set PRIMES[302] = 1999
        set PRIMES[303] = 2003
        set PRIMES[304] = 2011
        set PRIMES[305] = 2017
        set PRIMES[306] = 2027
        set PRIMES[307] = 2029
        set PRIMES[308] = 2039
        set PRIMES[309] = 2053
        set PRIMES[310] = 2063
        set PRIMES[311] = 2069
        set PRIMES[312] = 2081
        set PRIMES[313] = 2083
        set PRIMES[314] = 2087
        set PRIMES[315] = 2089
        set PRIMES[316] = 2099
        set PRIMES[317] = 2111
        set PRIMES[318] = 2113
        set PRIMES[319] = 2129
        set PRIMES[320] = 2131
        set PRIMES[321] = 2137
        set PRIMES[322] = 2141
        set PRIMES[323] = 2143
        set PRIMES[324] = 2153
        set PRIMES[325] = 2161
        set PRIMES[326] = 2179
        set PRIMES[327] = 2203
        set PRIMES[328] = 2207
        set PRIMES[329] = 2213
        set PRIMES[330] = 2221
        set PRIMES[331] = 2237
        set PRIMES[332] = 2239
        set PRIMES[333] = 2243
        set PRIMES[334] = 2251
        set PRIMES[335] = 2267
        set PRIMES[336] = 2269
        set PRIMES[337] = 2273
        set PRIMES[338] = 2281
        set PRIMES[339] = 2287
        set PRIMES[340] = 2293
        set PRIMES[341] = 2297
        set PRIMES[342] = 2309
        set PRIMES[343] = 2311
        set PRIMES[344] = 2333
        set PRIMES[345] = 2339
        set PRIMES[346] = 2341
        set PRIMES[347] = 2347
        set PRIMES[348] = 2351
        set PRIMES[349] = 2357
        set PRIMES[350] = 2371
        set PRIMES[351] = 2377
        set PRIMES[352] = 2381
        set PRIMES[353] = 2383
        set PRIMES[354] = 2389
        set PRIMES[355] = 2393
        set PRIMES[356] = 2399
        set PRIMES[357] = 2411
        set PRIMES[358] = 2417
        set PRIMES[359] = 2423
        set PRIMES[360] = 2437
        set PRIMES[361] = 2441
        set PRIMES[362] = 2447
        set PRIMES[363] = 2459
        set PRIMES[364] = 2467
        set PRIMES[365] = 2473
        set PRIMES[366] = 2477
        set PRIMES[367] = 2503
        set PRIMES[368] = 2521
        set PRIMES[369] = 2531
        set PRIMES[370] = 2539
        set PRIMES[371] = 2543
        set PRIMES[372] = 2549
        set PRIMES[373] = 2551
        set PRIMES[374] = 2557
        set PRIMES[375] = 2579
        set PRIMES[376] = 2591
        set PRIMES[377] = 2593
        set PRIMES[378] = 2609
        set PRIMES[379] = 2617
        set PRIMES[380] = 2621
        set PRIMES[381] = 2633
        set PRIMES[382] = 2647
        set PRIMES[383] = 2657
        set PRIMES[384] = 2659
        set PRIMES[385] = 2663
        set PRIMES[386] = 2671
        set PRIMES[387] = 2677
        set PRIMES[388] = 2683
        set PRIMES[389] = 2687
        set PRIMES[390] = 2689
        set PRIMES[391] = 2693
        set PRIMES[392] = 2699
        set PRIMES[393] = 2707
        set PRIMES[394] = 2711
        set PRIMES[395] = 2713
        set PRIMES[396] = 2719
        set PRIMES[397] = 2729
        set PRIMES[398] = 2731
        set PRIMES[399] = 2741
        set PRIMES[400] = 2749
        set PRIMES[401] = 2753
        set PRIMES[402] = 2767
        set PRIMES[403] = 2777
        set PRIMES[404] = 2789
        set PRIMES[405] = 2791
        set PRIMES[406] = 2797
        set PRIMES[407] = 2801
        set PRIMES[408] = 2803
        set PRIMES[409] = 2819
        set PRIMES[410] = 2833
        set PRIMES[411] = 2837
        set PRIMES[412] = 2843
        set PRIMES[413] = 2851
        set PRIMES[414] = 2857
        set PRIMES[415] = 2861
        set PRIMES[416] = 2879
        set PRIMES[417] = 2887
        set PRIMES[418] = 2897
        set PRIMES[419] = 2903
        set PRIMES[420] = 2909
        set PRIMES[421] = 2917
        set PRIMES[422] = 2927
        set PRIMES[423] = 2939
        set PRIMES[424] = 2953
        set PRIMES[425] = 2957
        set PRIMES[426] = 2963
        set PRIMES[427] = 2969
        set PRIMES[428] = 2971
        set PRIMES[429] = 2999
        set PRIMES[430] = 3001
        set PRIMES[431] = 3011
        set PRIMES[432] = 3019
        set PRIMES[433] = 3023
        set PRIMES[434] = 3037
        set PRIMES[435] = 3041
        set PRIMES[436] = 3049
        set PRIMES[437] = 3061
        set PRIMES[438] = 3067
        set PRIMES[439] = 3079
        set PRIMES[440] = 3083
        set PRIMES[441] = 3089
        set PRIMES[442] = 3109
        set PRIMES[443] = 3119
        set PRIMES[444] = 3121
        set PRIMES[445] = 3137
        set PRIMES[446] = 3163
        set PRIMES[447] = 3167
        set PRIMES[448] = 3169
        set PRIMES[449] = 3181
        set PRIMES[450] = 3187
        set PRIMES[451] = 3191
        set PRIMES[452] = 3203
        set PRIMES[453] = 3209
        set PRIMES[454] = 3217
        set PRIMES[455] = 3221
        set PRIMES[456] = 3229
        set PRIMES[457] = 3251
        set PRIMES[458] = 3253
        set PRIMES[459] = 3257
        set PRIMES[460] = 3259
        set PRIMES[461] = 3271
        set PRIMES[462] = 3299
        set PRIMES[463] = 3301
        set PRIMES[464] = 3307
        set PRIMES[465] = 3313
        set PRIMES[466] = 3319
        set PRIMES[467] = 3323
        set PRIMES[468] = 3329
        set PRIMES[469] = 3331
        set PRIMES[470] = 3343
        set PRIMES[471] = 3347
        set PRIMES[472] = 3359
        set PRIMES[473] = 3361
        set PRIMES[474] = 3371
        set PRIMES[475] = 3373
        set PRIMES[476] = 3389
        set PRIMES[477] = 3391
        set PRIMES[478] = 3407
        set PRIMES[479] = 3413
        set PRIMES[480] = 3433
        set PRIMES[481] = 3449
        set PRIMES[482] = 3457
        set PRIMES[483] = 3461
        set PRIMES[484] = 3463
        set PRIMES[485] = 3467
        set PRIMES[486] = 3469
        set PRIMES[487] = 3491
        set PRIMES[488] = 3499
        set PRIMES[489] = 3511
        set PRIMES[490] = 3517
        set PRIMES[491] = 3527
        set PRIMES[492] = 3529
        set PRIMES[493] = 3533
        set PRIMES[494] = 3539
        set PRIMES[495] = 3541
        set PRIMES[496] = 3547
        set PRIMES[497] = 3557
        set PRIMES[498] = 3559
        set PRIMES[499] = 3571
        set PRIMES[500] = 3581
        set PRIMES[501] = 3583
        set PRIMES[502] = 3593
        set PRIMES[503] = 3607
        set PRIMES[504] = 3613
        set PRIMES[505] = 3617
        set PRIMES[506] = 3623
        set PRIMES[507] = 3631
        set PRIMES[508] = 3637
        set PRIMES[509] = 3643
        set PRIMES[510] = 3659
        set PRIMES[511] = 3671
        set PRIMES[512] = 3673
        set PRIMES[513] = 3677
        set PRIMES[514] = 3691
        set PRIMES[515] = 3697
        set PRIMES[516] = 3701
        set PRIMES[517] = 3709
        set PRIMES[518] = 3719
        set PRIMES[519] = 3727
        set PRIMES[520] = 3733
        set PRIMES[521] = 3739
        set PRIMES[522] = 3761
        set PRIMES[523] = 3767
        set PRIMES[524] = 3769
        set PRIMES[525] = 3779
        set PRIMES[526] = 3793
        set PRIMES[527] = 3797
        set PRIMES[528] = 3803
        set PRIMES[529] = 3821
        set PRIMES[530] = 3823
        set PRIMES[531] = 3833
        set PRIMES[532] = 3847
        set PRIMES[533] = 3851
        set PRIMES[534] = 3853
        set PRIMES[535] = 3863
        set PRIMES[536] = 3877
        set PRIMES[537] = 3881
        set PRIMES[538] = 3889
        set PRIMES[539] = 3907
        set PRIMES[540] = 3911
        set PRIMES[541] = 3917
        set PRIMES[542] = 3919
        set PRIMES[543] = 3923
        set PRIMES[544] = 3929
        set PRIMES[545] = 3931
        set PRIMES[546] = 3943
        set PRIMES[547] = 3947
        set PRIMES[548] = 3967
        set PRIMES[549] = 3989
        set PRIMES[550] = 4001
        set PRIMES[551] = 4003
        set PRIMES[552] = 4007
        set PRIMES[553] = 4013
        set PRIMES[554] = 4019
        set PRIMES[555] = 4021
        set PRIMES[556] = 4027
        set PRIMES[557] = 4049
        set PRIMES[558] = 4051
        set PRIMES[559] = 4057
        set PRIMES[560] = 4073
        set PRIMES[561] = 4079
        set PRIMES[562] = 4091
        set PRIMES[563] = 4093
        set PRIMES[564] = 4099
        set PRIMES[565] = 4111
        set PRIMES[566] = 4127
        set PRIMES[567] = 4129
        set PRIMES[568] = 4133
        set PRIMES[569] = 4139
        set PRIMES[570] = 4153
        set PRIMES[571] = 4157
        set PRIMES[572] = 4159
        set PRIMES[573] = 4177
        set PRIMES[574] = 4201
        set PRIMES[575] = 4211
        set PRIMES[576] = 4217
        set PRIMES[577] = 4219
        set PRIMES[578] = 4229
        set PRIMES[579] = 4231
        set PRIMES[580] = 4241
        set PRIMES[581] = 4243
        set PRIMES[582] = 4253
        set PRIMES[583] = 4259
        set PRIMES[584] = 4261
        set PRIMES[585] = 4271
        set PRIMES[586] = 4273
        set PRIMES[587] = 4283
        set PRIMES[588] = 4289
        set PRIMES[589] = 4297
        set PRIMES[590] = 4327
        set PRIMES[591] = 4337
        set PRIMES[592] = 4339
        set PRIMES[593] = 4349
        set PRIMES[594] = 4357
        set PRIMES[595] = 4363
        set PRIMES[596] = 4373
        set PRIMES[597] = 4391
        set PRIMES[598] = 4397
        set PRIMES[599] = 4409
        set PRIMES[600] = 4421
        set PRIMES[601] = 4423
        set PRIMES[602] = 4441
        set PRIMES[603] = 4447
        set PRIMES[604] = 4451
        set PRIMES[605] = 4457
        set PRIMES[606] = 4463
        set PRIMES[607] = 4481
        set PRIMES[608] = 4483
        set PRIMES[609] = 4493
        set PRIMES[610] = 4507
        set PRIMES[611] = 4513
        set PRIMES[612] = 4517
        set PRIMES[613] = 4519
        set PRIMES[614] = 4523
        set PRIMES[615] = 4547
        set PRIMES[616] = 4549
        set PRIMES[617] = 4561
        set PRIMES[618] = 4567
        set PRIMES[619] = 4583
        set PRIMES[620] = 4591
        set PRIMES[621] = 4597
        set PRIMES[622] = 4603
        set PRIMES[623] = 4621
        set PRIMES[624] = 4637
        set PRIMES[625] = 4639
        set PRIMES[626] = 4643
        set PRIMES[627] = 4649
        set PRIMES[628] = 4651
        set PRIMES[629] = 4657
        set PRIMES[630] = 4663
        set PRIMES[631] = 4673
        set PRIMES[632] = 4679
        set PRIMES[633] = 4691
        set PRIMES[634] = 4703
        set PRIMES[635] = 4721
        set PRIMES[636] = 4723
        set PRIMES[637] = 4729
        set PRIMES[638] = 4733
        set PRIMES[639] = 4751
        set PRIMES[640] = 4759
        set PRIMES[641] = 4783
        set PRIMES[642] = 4787
        set PRIMES[643] = 4789
        set PRIMES[644] = 4793
        set PRIMES[645] = 4799
        set PRIMES[646] = 4801
        set PRIMES[647] = 4813
        set PRIMES[648] = 4817
        set PRIMES[649] = 4831
        set PRIMES[650] = 4861
        set PRIMES[651] = 4871
        set PRIMES[652] = 4877
        set PRIMES[653] = 4889
        set PRIMES[654] = 4903
        set PRIMES[655] = 4909
        set PRIMES[656] = 4919
        set PRIMES[657] = 4931
        set PRIMES[658] = 4933
        set PRIMES[659] = 4937
        set PRIMES[660] = 4943
        set PRIMES[661] = 4951
        set PRIMES[662] = 4957
        set PRIMES[663] = 4967
        set PRIMES[664] = 4969
        set PRIMES[665] = 4973
        set PRIMES[666] = 4987
        set PRIMES[667] = 4993
        set PRIMES[668] = 4999
        set PRIMES[669] = 5003
        set PRIMES[670] = 5009
        set PRIMES[671] = 5011
        set PRIMES[672] = 5021
        set PRIMES[673] = 5023
        set PRIMES[674] = 5039
        set PRIMES[675] = 5051
        set PRIMES[676] = 5059
        set PRIMES[677] = 5077
        set PRIMES[678] = 5081
        set PRIMES[679] = 5087
        set PRIMES[680] = 5099
        set PRIMES[681] = 5101
        set PRIMES[682] = 5107
        set PRIMES[683] = 5113
        set PRIMES[684] = 5119
        set PRIMES[685] = 5147
        set PRIMES[686] = 5153
        set PRIMES[687] = 5167
        set PRIMES[688] = 5171
        set PRIMES[689] = 5179
        set PRIMES[690] = 5189
        set PRIMES[691] = 5197
        set PRIMES[692] = 5209
        set PRIMES[693] = 5227
        set PRIMES[694] = 5231
        set PRIMES[695] = 5233
        set PRIMES[696] = 5237
        set PRIMES[697] = 5261
        set PRIMES[698] = 5273
        set PRIMES[699] = 5279
        set PRIMES[700] = 5281
        set PRIMES[701] = 5297
        set PRIMES[702] = 5303
        set PRIMES[703] = 5309
        set PRIMES[704] = 5323
        set PRIMES[705] = 5333
        set PRIMES[706] = 5347
        set PRIMES[707] = 5351
        set PRIMES[708] = 5381
        set PRIMES[709] = 5387
        set PRIMES[710] = 5393
        set PRIMES[711] = 5399
        set PRIMES[712] = 5407
        set PRIMES[713] = 5413
        set PRIMES[714] = 5417
        set PRIMES[715] = 5419
        set PRIMES[716] = 5431
        set PRIMES[717] = 5437
        set PRIMES[718] = 5441
        set PRIMES[719] = 5443
        set PRIMES[720] = 5449
        set PRIMES[721] = 5471
        set PRIMES[722] = 5477
        set PRIMES[723] = 5479
        set PRIMES[724] = 5483
        set PRIMES[725] = 5501
        set PRIMES[726] = 5503
        set PRIMES[727] = 5507
        set PRIMES[728] = 5519
        set PRIMES[729] = 5521
        set PRIMES[730] = 5527
        set PRIMES[731] = 5531
        set PRIMES[732] = 5557
        set PRIMES[733] = 5563
        set PRIMES[734] = 5569
        set PRIMES[735] = 5573
        set PRIMES[736] = 5581
        set PRIMES[737] = 5591
        set PRIMES[738] = 5623
        set PRIMES[739] = 5639
        set PRIMES[740] = 5641
        set PRIMES[741] = 5647
        set PRIMES[742] = 5651
        set PRIMES[743] = 5653
        set PRIMES[744] = 5657
        set PRIMES[745] = 5659
        set PRIMES[746] = 5669
        set PRIMES[747] = 5683
        set PRIMES[748] = 5689
        set PRIMES[749] = 5693
        set PRIMES[750] = 5701
        set PRIMES[751] = 5711
        set PRIMES[752] = 5717
        set PRIMES[753] = 5737
        set PRIMES[754] = 5741
        set PRIMES[755] = 5743
        set PRIMES[756] = 5749
        set PRIMES[757] = 5779
        set PRIMES[758] = 5783
        set PRIMES[759] = 5791
        set PRIMES[760] = 5801
        set PRIMES[761] = 5807
        set PRIMES[762] = 5813
        set PRIMES[763] = 5821
        set PRIMES[764] = 5827
        set PRIMES[765] = 5839
        set PRIMES[766] = 5843
        set PRIMES[767] = 5849
        set PRIMES[768] = 5851
        set PRIMES[769] = 5857
        set PRIMES[770] = 5861
        set PRIMES[771] = 5867
        set PRIMES[772] = 5869
        set PRIMES[773] = 5879
        set PRIMES[774] = 5881
        set PRIMES[775] = 5897
        set PRIMES[776] = 5903
        set PRIMES[777] = 5923
        set PRIMES[778] = 5927
        set PRIMES[779] = 5939
        set PRIMES[780] = 5953
        set PRIMES[781] = 5981
        set PRIMES[782] = 5987
        set PRIMES[783] = 6007
        set PRIMES[784] = 6011
        set PRIMES[785] = 6029
        set PRIMES[786] = 6037
        set PRIMES[787] = 6043
        set PRIMES[788] = 6047
        set PRIMES[789] = 6053
        set PRIMES[790] = 6067
        set PRIMES[791] = 6073
        set PRIMES[792] = 6079
        set PRIMES[793] = 6089
        set PRIMES[794] = 6091
        set PRIMES[795] = 6101
        set PRIMES[796] = 6113
        set PRIMES[797] = 6121
        set PRIMES[798] = 6131
        set PRIMES[799] = 6133
        set PRIMES[800] = 6143
        set PRIMES[801] = 6151
        set PRIMES[802] = 6163
        set PRIMES[803] = 6173
        set PRIMES[804] = 6197
        set PRIMES[805] = 6199
        set PRIMES[806] = 6203
        set PRIMES[807] = 6211
        set PRIMES[808] = 6217
        set PRIMES[809] = 6221
        set PRIMES[810] = 6229
        set PRIMES[811] = 6247
        set PRIMES[812] = 6257
        set PRIMES[813] = 6263
        set PRIMES[814] = 6269
        set PRIMES[815] = 6271
        set PRIMES[816] = 6277
        set PRIMES[817] = 6287
        set PRIMES[818] = 6299
        set PRIMES[819] = 6301
        set PRIMES[820] = 6311
        set PRIMES[821] = 6317
        set PRIMES[822] = 6323
        set PRIMES[823] = 6329
        set PRIMES[824] = 6337
        set PRIMES[825] = 6343
        set PRIMES[826] = 6353
        set PRIMES[827] = 6359
        set PRIMES[828] = 6361
        set PRIMES[829] = 6367
        set PRIMES[830] = 6373
        set PRIMES[831] = 6379
        set PRIMES[832] = 6389
        set PRIMES[833] = 6397
        set PRIMES[834] = 6421
        set PRIMES[835] = 6427
        set PRIMES[836] = 6449
        set PRIMES[837] = 6451
        set PRIMES[838] = 6469
        set PRIMES[839] = 6473
        set PRIMES[840] = 6481
        set PRIMES[841] = 6491
        set PRIMES[842] = 6521
        set PRIMES[843] = 6529
        set PRIMES[844] = 6547
        set PRIMES[845] = 6551
        set PRIMES[846] = 6553
        set PRIMES[847] = 6563
        set PRIMES[848] = 6569
        set PRIMES[849] = 6571
        set PRIMES[850] = 6577
        set PRIMES[851] = 6581
        set PRIMES[852] = 6599
        set PRIMES[853] = 6607
        set PRIMES[854] = 6619
        set PRIMES[855] = 6637
        set PRIMES[856] = 6653
        set PRIMES[857] = 6659
        set PRIMES[858] = 6661
        set PRIMES[859] = 6673
        set PRIMES[860] = 6679
        set PRIMES[861] = 6689
        set PRIMES[862] = 6691
        set PRIMES[863] = 6701
        set PRIMES[864] = 6703
        set PRIMES[865] = 6709
        set PRIMES[866] = 6719
        set PRIMES[867] = 6733
        set PRIMES[868] = 6737
        set PRIMES[869] = 6761
        set PRIMES[870] = 6763
        set PRIMES[871] = 6779
        set PRIMES[872] = 6781
        set PRIMES[873] = 6791
        set PRIMES[874] = 6793
        set PRIMES[875] = 6803
        set PRIMES[876] = 6823
        set PRIMES[877] = 6827
        set PRIMES[878] = 6829
        set PRIMES[879] = 6833
        set PRIMES[880] = 6841
        set PRIMES[881] = 6857
        set PRIMES[882] = 6863
        set PRIMES[883] = 6869
        set PRIMES[884] = 6871
        set PRIMES[885] = 6883
        set PRIMES[886] = 6899
        set PRIMES[887] = 6907
        set PRIMES[888] = 6911
        set PRIMES[889] = 6917
        set PRIMES[890] = 6947
        set PRIMES[891] = 6949
        set PRIMES[892] = 6959
        set PRIMES[893] = 6961
        set PRIMES[894] = 6967
        set PRIMES[895] = 6971
        set PRIMES[896] = 6977
        set PRIMES[897] = 6983
        set PRIMES[898] = 6991
        set PRIMES[899] = 6997
        set PRIMES[900] = 7001
        set PRIMES[901] = 7013
        set PRIMES[902] = 7019
        set PRIMES[903] = 7027
        set PRIMES[904] = 7039
        set PRIMES[905] = 7043
        set PRIMES[906] = 7057
        set PRIMES[907] = 7069
        set PRIMES[908] = 7079
        set PRIMES[909] = 7103
        set PRIMES[910] = 7109
        set PRIMES[911] = 7121
        set PRIMES[912] = 7127
        set PRIMES[913] = 7129
        set PRIMES[914] = 7151
        set PRIMES[915] = 7159
        set PRIMES[916] = 7177
        set PRIMES[917] = 7187
        set PRIMES[918] = 7193
        set PRIMES[919] = 7207
        set PRIMES[920] = 7211
        set PRIMES[921] = 7213
        set PRIMES[922] = 7219
        set PRIMES[923] = 7229
        set PRIMES[924] = 7237
        set PRIMES[925] = 7243
        set PRIMES[926] = 7247
        set PRIMES[927] = 7253
        set PRIMES[928] = 7283
        set PRIMES[929] = 7297
        set PRIMES[930] = 7307
        set PRIMES[931] = 7309
        set PRIMES[932] = 7321
        set PRIMES[933] = 7331
        set PRIMES[934] = 7333
        set PRIMES[935] = 7349
        set PRIMES[936] = 7351
        set PRIMES[937] = 7369
        set PRIMES[938] = 7393
        set PRIMES[939] = 7411
        set PRIMES[940] = 7417
        set PRIMES[941] = 7433
        set PRIMES[942] = 7451
        set PRIMES[943] = 7457
        set PRIMES[944] = 7459
        set PRIMES[945] = 7477
        set PRIMES[946] = 7481
        set PRIMES[947] = 7487
        set PRIMES[948] = 7489
        set PRIMES[949] = 7499
        set PRIMES[950] = 7507
        set PRIMES[951] = 7517
        set PRIMES[952] = 7523
        set PRIMES[953] = 7529
        set PRIMES[954] = 7537
        set PRIMES[955] = 7541
        set PRIMES[956] = 7547
        set PRIMES[957] = 7549
        set PRIMES[958] = 7559
        set PRIMES[959] = 7561
        set PRIMES[960] = 7573
        set PRIMES[961] = 7577
        set PRIMES[962] = 7583
        set PRIMES[963] = 7589
        set PRIMES[964] = 7591
        set PRIMES[965] = 7603
        set PRIMES[966] = 7607
        set PRIMES[967] = 7621
        set PRIMES[968] = 7639
        set PRIMES[969] = 7643
        set PRIMES[970] = 7649
        set PRIMES[971] = 7669
        set PRIMES[972] = 7673
        set PRIMES[973] = 7681
        set PRIMES[974] = 7687
        set PRIMES[975] = 7691
        set PRIMES[976] = 7699
        set PRIMES[977] = 7703
        set PRIMES[978] = 7717
        set PRIMES[979] = 7723
        set PRIMES[980] = 7727
        set PRIMES[981] = 7741
        set PRIMES[982] = 7753
        set PRIMES[983] = 7757
        set PRIMES[984] = 7759
        set PRIMES[985] = 7789
        set PRIMES[986] = 7793
        set PRIMES[987] = 7817
        set PRIMES[988] = 7823
        set PRIMES[989] = 7829
        set PRIMES[990] = 7841
        set PRIMES[991] = 7853
        set PRIMES[992] = 7867
        set PRIMES[993] = 7873
        set PRIMES[994] = 7877
        set PRIMES[995] = 7879
        set PRIMES[996] = 7883
        set PRIMES[997] = 7901
        set PRIMES[998] = 7907
        set PRIMES[999] = 7919
        set PRIMES[1000] = 7927
        set PRIMES[1001] = 7933
        set PRIMES[1002] = 7937
        set PRIMES[1003] = 7949
        set PRIMES[1004] = 7951
        set PRIMES[1005] = 7963
        set PRIMES[1006] = 7993
        set PRIMES[1007] = 8009
        set PRIMES[1008] = 8011
        set PRIMES[1009] = 8017
        set PRIMES[1010] = 8039
        set PRIMES[1011] = 8053
        set PRIMES[1012] = 8059
        set PRIMES[1013] = 8069
        set PRIMES[1014] = 8081
        set PRIMES[1015] = 8087
        set PRIMES[1016] = 8089
        set PRIMES[1017] = 8093
        set PRIMES[1018] = 8101
        set PRIMES[1019] = 8111
        set PRIMES[1020] = 8117
        set PRIMES[1021] = 8123
        set PRIMES[1022] = 8147
        set PRIMES[1023] = 8161
        set PRIMES[1024] = 8167
        set PRIMES[1025] = 8171
        set PRIMES[1026] = 8179
        set PRIMES[1027] = 8191
        set PRIMES[1028] = 8209
        set PRIMES[1029] = 8219
        set PRIMES[1030] = 8221
        set PRIMES[1031] = 8231
        set PRIMES[1032] = 8233
        set PRIMES[1033] = 8237
        set PRIMES[1034] = 8243
        set PRIMES[1035] = 8263
        set PRIMES[1036] = 8269
        set PRIMES[1037] = 8273
        set PRIMES[1038] = 8287
        set PRIMES[1039] = 8291
        set PRIMES[1040] = 8293
        set PRIMES[1041] = 8297
        set PRIMES[1042] = 8311
        set PRIMES[1043] = 8317
        set PRIMES[1044] = 8329
        set PRIMES[1045] = 8353
        set PRIMES[1046] = 8363
        set PRIMES[1047] = 8369
        set PRIMES[1048] = 8377
        set PRIMES[1049] = 8387
        set PRIMES[1050] = 8389
        set PRIMES[1051] = 8419
        set PRIMES[1052] = 8423
        set PRIMES[1053] = 8429
        set PRIMES[1054] = 8431
        set PRIMES[1055] = 8443
        set PRIMES[1056] = 8447
        set PRIMES[1057] = 8461
        set PRIMES[1058] = 8467
        set PRIMES[1059] = 8501
        set PRIMES[1060] = 8513
        set PRIMES[1061] = 8521
        set PRIMES[1062] = 8527
        set PRIMES[1063] = 8537
        set PRIMES[1064] = 8539
        set PRIMES[1065] = 8543
        set PRIMES[1066] = 8563
        set PRIMES[1067] = 8573
        set PRIMES[1068] = 8581
        set PRIMES[1069] = 8597
        set PRIMES[1070] = 8599
        set PRIMES[1071] = 8609
        set PRIMES[1072] = 8623
        set PRIMES[1073] = 8627
        set PRIMES[1074] = 8629
        set PRIMES[1075] = 8641
        set PRIMES[1076] = 8647
        set PRIMES[1077] = 8663
        set PRIMES[1078] = 8669
        set PRIMES[1079] = 8677
        set PRIMES[1080] = 8681
        set PRIMES[1081] = 8689
        set PRIMES[1082] = 8693
        set PRIMES[1083] = 8699
        set PRIMES[1084] = 8707
        set PRIMES[1085] = 8713
        set PRIMES[1086] = 8719
        set PRIMES[1087] = 8731
        set PRIMES[1088] = 8737
        set PRIMES[1089] = 8741
        set PRIMES[1090] = 8747
        set PRIMES[1091] = 8753
        set PRIMES[1092] = 8761
        set PRIMES[1093] = 8779
        set PRIMES[1094] = 8783
        set PRIMES[1095] = 8803
        set PRIMES[1096] = 8807
        set PRIMES[1097] = 8819
        set PRIMES[1098] = 8821
        set PRIMES[1099] = 8831
        set PRIMES[1100] = 8837
        set PRIMES[1101] = 8839
        set PRIMES[1102] = 8849
        set PRIMES[1103] = 8861
        set PRIMES[1104] = 8863
        set PRIMES[1105] = 8867
        set PRIMES[1106] = 8887
        set PRIMES[1107] = 8893
        set PRIMES[1108] = 8923
        set PRIMES[1109] = 8929
        set PRIMES[1110] = 8933
        set PRIMES[1111] = 8941
        set PRIMES[1112] = 8951
        set PRIMES[1113] = 8963
        set PRIMES[1114] = 8969
        set PRIMES[1115] = 8971
        set PRIMES[1116] = 8999
        set PRIMES[1117] = 9001
        set PRIMES[1118] = 9007
        set PRIMES[1119] = 9011
        set PRIMES[1120] = 9013
        set PRIMES[1121] = 9029
        set PRIMES[1122] = 9041
        set PRIMES[1123] = 9043
        set PRIMES[1124] = 9049
        set PRIMES[1125] = 9059
        set PRIMES[1126] = 9067
        set PRIMES[1127] = 9091
        set PRIMES[1128] = 9103
        set PRIMES[1129] = 9109
        set PRIMES[1130] = 9127
        set PRIMES[1131] = 9133
        set PRIMES[1132] = 9137
        set PRIMES[1133] = 9151
        set PRIMES[1134] = 9157
        set PRIMES[1135] = 9161
        set PRIMES[1136] = 9173
        set PRIMES[1137] = 9181
        set PRIMES[1138] = 9187
        set PRIMES[1139] = 9199
        set PRIMES[1140] = 9203
        set PRIMES[1141] = 9209
        set PRIMES[1142] = 9221
        set PRIMES[1143] = 9227
        set PRIMES[1144] = 9239
        set PRIMES[1145] = 9241
        set PRIMES[1146] = 9257
        set PRIMES[1147] = 9277
        set PRIMES[1148] = 9281
        set PRIMES[1149] = 9283
        set PRIMES[1150] = 9293
        set PRIMES[1151] = 9311
        set PRIMES[1152] = 9319
        set PRIMES[1153] = 9323
        set PRIMES[1154] = 9337
        set PRIMES[1155] = 9341
        set PRIMES[1156] = 9343
        set PRIMES[1157] = 9349
        set PRIMES[1158] = 9371
        set PRIMES[1159] = 9377
        set PRIMES[1160] = 9391
        set PRIMES[1161] = 9397
        set PRIMES[1162] = 9403
        set PRIMES[1163] = 9413
        set PRIMES[1164] = 9419
        set PRIMES[1165] = 9421
        set PRIMES[1166] = 9431
        set PRIMES[1167] = 9433
        set PRIMES[1168] = 9437
        set PRIMES[1169] = 9439
        set PRIMES[1170] = 9461
        set PRIMES[1171] = 9463
        set PRIMES[1172] = 9467
        set PRIMES[1173] = 9473
        set PRIMES[1174] = 9479
        set PRIMES[1175] = 9491
        set PRIMES[1176] = 9497
        set PRIMES[1177] = 9511
        set PRIMES[1178] = 9521
        set PRIMES[1179] = 9533
        set PRIMES[1180] = 9539
        set PRIMES[1181] = 9547
        set PRIMES[1182] = 9551
        set PRIMES[1183] = 9587
        set PRIMES[1184] = 9601
        set PRIMES[1185] = 9613
        set PRIMES[1186] = 9619
        set PRIMES[1187] = 9623
        set PRIMES[1188] = 9629
        set PRIMES[1189] = 9631
        set PRIMES[1190] = 9643
        set PRIMES[1191] = 9649
        set PRIMES[1192] = 9661
        set PRIMES[1193] = 9677
        set PRIMES[1194] = 9679
        set PRIMES[1195] = 9689
        set PRIMES[1196] = 9697
        set PRIMES[1197] = 9719
        set PRIMES[1198] = 9721
        set PRIMES[1199] = 9733
        set PRIMES[1200] = 9739
        set PRIMES[1201] = 9743
        set PRIMES[1202] = 9749
        set PRIMES[1203] = 9767
        set PRIMES[1204] = 9769
        set PRIMES[1205] = 9781
        set PRIMES[1206] = 9787
        set PRIMES[1207] = 9791
        set PRIMES[1208] = 9803
        set PRIMES[1209] = 9811
        set PRIMES[1210] = 9817
        set PRIMES[1211] = 9829
        set PRIMES[1212] = 9833
        set PRIMES[1213] = 9839
        set PRIMES[1214] = 9851
        set PRIMES[1215] = 9857
        set PRIMES[1216] = 9859
        set PRIMES[1217] = 9871
        set PRIMES[1218] = 9883
        set PRIMES[1219] = 9887
        set PRIMES[1220] = 9901
        set PRIMES[1221] = 9907
        set PRIMES[1222] = 9923
        set PRIMES[1223] = 9929
        set PRIMES[1224] = 9931
        set PRIMES[1225] = 9941
        set PRIMES[1226] = 9949
        set PRIMES[1227] = 9967
        set PRIMES[1228] = 9973
        set PRIMES[1229] = 10007
        set PRIMES[1230] = 10009
        set PRIMES[1231] = 10037
        set PRIMES[1232] = 10039
        set PRIMES[1233] = 10061
        set PRIMES[1234] = 10067
        set PRIMES[1235] = 10069
        set PRIMES[1236] = 10079
        set PRIMES[1237] = 10091
        set PRIMES[1238] = 10093
        set PRIMES[1239] = 10099
        set PRIMES[1240] = 10103
        set PRIMES[1241] = 10111
        set PRIMES[1242] = 10133
        set PRIMES[1243] = 10139
        set PRIMES[1244] = 10141
        set PRIMES[1245] = 10151
        set PRIMES[1246] = 10159
        set PRIMES[1247] = 10163
        set PRIMES[1248] = 10169
        set PRIMES[1249] = 10177
        set PRIMES[1250] = 10181
        set PRIMES[1251] = 10193
        set PRIMES[1252] = 10211
        set PRIMES[1253] = 10223
        set PRIMES[1254] = 10243
        set PRIMES[1255] = 10247
        set PRIMES[1256] = 10253
        set PRIMES[1257] = 10259
        set PRIMES[1258] = 10267
        set PRIMES[1259] = 10271
        set PRIMES[1260] = 10273
        set PRIMES[1261] = 10289
        set PRIMES[1262] = 10301
        set PRIMES[1263] = 10303
        set PRIMES[1264] = 10313
        set PRIMES[1265] = 10321
        set PRIMES[1266] = 10331
        set PRIMES[1267] = 10333
        set PRIMES[1268] = 10337
        set PRIMES[1269] = 10343
        set PRIMES[1270] = 10357
        set PRIMES[1271] = 10369
        set PRIMES[1272] = 10391
        set PRIMES[1273] = 10399
        set PRIMES[1274] = 10427
        set PRIMES[1275] = 10429
        set PRIMES[1276] = 10433
        set PRIMES[1277] = 10453
        set PRIMES[1278] = 10457
        set PRIMES[1279] = 10459
        set PRIMES[1280] = 10463
        set PRIMES[1281] = 10477
        set PRIMES[1282] = 10487
        set PRIMES[1283] = 10499
        set PRIMES[1284] = 10501
        set PRIMES[1285] = 10513
        set PRIMES[1286] = 10529
        set PRIMES[1287] = 10531
        set PRIMES[1288] = 10559
        set PRIMES[1289] = 10567
        set PRIMES[1290] = 10589
        set PRIMES[1291] = 10597
        set PRIMES[1292] = 10601
        set PRIMES[1293] = 10607
        set PRIMES[1294] = 10613
        set PRIMES[1295] = 10627
        set PRIMES[1296] = 10631
        set PRIMES[1297] = 10639
        set PRIMES[1298] = 10651
        set PRIMES[1299] = 10657
        set PRIMES[1300] = 10663
        set PRIMES[1301] = 10667
        set PRIMES[1302] = 10687
        set PRIMES[1303] = 10691
        set PRIMES[1304] = 10709
        set PRIMES[1305] = 10711
        set PRIMES[1306] = 10723
        set PRIMES[1307] = 10729
        set PRIMES[1308] = 10733
        set PRIMES[1309] = 10739
        set PRIMES[1310] = 10753
        set PRIMES[1311] = 10771
        set PRIMES[1312] = 10781
        set PRIMES[1313] = 10789
        set PRIMES[1314] = 10799
        set PRIMES[1315] = 10831
        set PRIMES[1316] = 10837
        set PRIMES[1317] = 10847
        set PRIMES[1318] = 10853
        set PRIMES[1319] = 10859
        set PRIMES[1320] = 10861
        set PRIMES[1321] = 10867
        set PRIMES[1322] = 10883
        set PRIMES[1323] = 10889
        set PRIMES[1324] = 10891
        set PRIMES[1325] = 10903
        set PRIMES[1326] = 10909
        set PRIMES[1327] = 10937
        set PRIMES[1328] = 10939
        set PRIMES[1329] = 10949
        set PRIMES[1330] = 10957
        set PRIMES[1331] = 10973
        set PRIMES[1332] = 10979
        set PRIMES[1333] = 10987
        set PRIMES[1334] = 10993
        set PRIMES[1335] = 11003
        set PRIMES[1336] = 11027
        set PRIMES[1337] = 11047
        set PRIMES[1338] = 11057
        set PRIMES[1339] = 11059
        set PRIMES[1340] = 11069
        set PRIMES[1341] = 11071
        set PRIMES[1342] = 11083
        set PRIMES[1343] = 11087
        set PRIMES[1344] = 11093
        set PRIMES[1345] = 11113
        set PRIMES[1346] = 11117
        set PRIMES[1347] = 11119
        set PRIMES[1348] = 11131
        set PRIMES[1349] = 11149
        set PRIMES[1350] = 11159
        set PRIMES[1351] = 11161
        set PRIMES[1352] = 11171
        set PRIMES[1353] = 11173
        set PRIMES[1354] = 11177
        set PRIMES[1355] = 11197
        set PRIMES[1356] = 11213
        set PRIMES[1357] = 11239
        set PRIMES[1358] = 11243
        set PRIMES[1359] = 11251
        set PRIMES[1360] = 11257
        set PRIMES[1361] = 11261
        set PRIMES[1362] = 11273
        set PRIMES[1363] = 11279
        set PRIMES[1364] = 11287
        set PRIMES[1365] = 11299
        set PRIMES[1366] = 11311
        set PRIMES[1367] = 11317
        set PRIMES[1368] = 11321
        set PRIMES[1369] = 11329
        set PRIMES[1370] = 11351
        set PRIMES[1371] = 11353
        set PRIMES[1372] = 11369
        set PRIMES[1373] = 11383
        set PRIMES[1374] = 11393
        set PRIMES[1375] = 11399
        set PRIMES[1376] = 11411
        set PRIMES[1377] = 11423
        set PRIMES[1378] = 11437
        set PRIMES[1379] = 11443
        set PRIMES[1380] = 11447
        set PRIMES[1381] = 11467
        set PRIMES[1382] = 11471
        set PRIMES[1383] = 11483
        set PRIMES[1384] = 11489
        set PRIMES[1385] = 11491
        set PRIMES[1386] = 11497
        set PRIMES[1387] = 11503
        set PRIMES[1388] = 11519
        set PRIMES[1389] = 11527
        set PRIMES[1390] = 11549
        set PRIMES[1391] = 11551
        set PRIMES[1392] = 11579
        set PRIMES[1393] = 11587
        set PRIMES[1394] = 11593
        set PRIMES[1395] = 11597
        set PRIMES[1396] = 11617
        set PRIMES[1397] = 11621
        set PRIMES[1398] = 11633
        set PRIMES[1399] = 11657
        set PRIMES[1400] = 11677
        set PRIMES[1401] = 11681
        set PRIMES[1402] = 11689
        set PRIMES[1403] = 11699
        set PRIMES[1404] = 11701
        set PRIMES[1405] = 11717
        set PRIMES[1406] = 11719
        set PRIMES[1407] = 11731
        set PRIMES[1408] = 11743
        set PRIMES[1409] = 11777
        set PRIMES[1410] = 11779
        set PRIMES[1411] = 11783
        set PRIMES[1412] = 11789
        set PRIMES[1413] = 11801
        set PRIMES[1414] = 11807
        set PRIMES[1415] = 11813
        set PRIMES[1416] = 11821
        set PRIMES[1417] = 11827
        set PRIMES[1418] = 11831
        set PRIMES[1419] = 11833
        set PRIMES[1420] = 11839
        set PRIMES[1421] = 11863
        set PRIMES[1422] = 11867
        set PRIMES[1423] = 11887
        set PRIMES[1424] = 11897
        set PRIMES[1425] = 11903
        set PRIMES[1426] = 11909
        set PRIMES[1427] = 11923
        set PRIMES[1428] = 11927
        set PRIMES[1429] = 11933
        set PRIMES[1430] = 11939
        set PRIMES[1431] = 11941
        set PRIMES[1432] = 11953
        set PRIMES[1433] = 11959
        set PRIMES[1434] = 11969
        set PRIMES[1435] = 11971
        set PRIMES[1436] = 11981
        set PRIMES[1437] = 11987
        set PRIMES[1438] = 12007
        set PRIMES[1439] = 12011
        set PRIMES[1440] = 12037
        set PRIMES[1441] = 12041
        set PRIMES[1442] = 12043
        set PRIMES[1443] = 12049
        set PRIMES[1444] = 12071
        set PRIMES[1445] = 12073
        set PRIMES[1446] = 12097
        set PRIMES[1447] = 12101
        set PRIMES[1448] = 12107
        set PRIMES[1449] = 12109
        set PRIMES[1450] = 12113
        set PRIMES[1451] = 12119
        set PRIMES[1452] = 12143
        set PRIMES[1453] = 12149
        set PRIMES[1454] = 12157
        set PRIMES[1455] = 12161
        set PRIMES[1456] = 12163
        set PRIMES[1457] = 12197
        set PRIMES[1458] = 12203
        set PRIMES[1459] = 12211
        set PRIMES[1460] = 12227
        set PRIMES[1461] = 12239
        set PRIMES[1462] = 12241
        set PRIMES[1463] = 12251
        set PRIMES[1464] = 12253
        set PRIMES[1465] = 12263
        set PRIMES[1466] = 12269
        set PRIMES[1467] = 12277
        set PRIMES[1468] = 12281
        set PRIMES[1469] = 12289
        set PRIMES[1470] = 12301
        set PRIMES[1471] = 12323
        set PRIMES[1472] = 12329
        set PRIMES[1473] = 12343
        set PRIMES[1474] = 12347
        set PRIMES[1475] = 12373
        set PRIMES[1476] = 12377
        set PRIMES[1477] = 12379
        set PRIMES[1478] = 12391
        set PRIMES[1479] = 12401
        set PRIMES[1480] = 12409
        set PRIMES[1481] = 12413
        set PRIMES[1482] = 12421
        set PRIMES[1483] = 12433
        set PRIMES[1484] = 12437
        set PRIMES[1485] = 12451
        set PRIMES[1486] = 12457
        set PRIMES[1487] = 12473
        set PRIMES[1488] = 12479
        set PRIMES[1489] = 12487
        set PRIMES[1490] = 12491
        set PRIMES[1491] = 12497
        set PRIMES[1492] = 12503
        set PRIMES[1493] = 12511
        set PRIMES[1494] = 12517
        set PRIMES[1495] = 12527
        set PRIMES[1496] = 12539
        set PRIMES[1497] = 12541
        set PRIMES[1498] = 12547
        set PRIMES[1499] = 12553
        set PRIMES[1500] = 12569
        set PRIMES[1501] = 12577
        set PRIMES[1502] = 12583
        set PRIMES[1503] = 12589
        set PRIMES[1504] = 12601
        set PRIMES[1505] = 12611
        set PRIMES[1506] = 12613
        set PRIMES[1507] = 12619
        set PRIMES[1508] = 12637
        set PRIMES[1509] = 12641
        set PRIMES[1510] = 12647
        set PRIMES[1511] = 12653
        set PRIMES[1512] = 12659
        set PRIMES[1513] = 12671
        set PRIMES[1514] = 12689
        set PRIMES[1515] = 12697
        set PRIMES[1516] = 12703
        set PRIMES[1517] = 12713
        set PRIMES[1518] = 12721
        set PRIMES[1519] = 12739
        set PRIMES[1520] = 12743
        set PRIMES[1521] = 12757
        set PRIMES[1522] = 12763
        set PRIMES[1523] = 12781
        set PRIMES[1524] = 12791
        set PRIMES[1525] = 12799
        set PRIMES[1526] = 12809
        set PRIMES[1527] = 12821
        set PRIMES[1528] = 12823
        set PRIMES[1529] = 12829
        set PRIMES[1530] = 12841
        set PRIMES[1531] = 12853
        set PRIMES[1532] = 12889
        set PRIMES[1533] = 12893
        set PRIMES[1534] = 12899
        set PRIMES[1535] = 12907
        set PRIMES[1536] = 12911
        set PRIMES[1537] = 12917
        set PRIMES[1538] = 12919
        set PRIMES[1539] = 12923
        set PRIMES[1540] = 12941
        set PRIMES[1541] = 12953
        set PRIMES[1542] = 12959
        set PRIMES[1543] = 12967
        set PRIMES[1544] = 12973
        set PRIMES[1545] = 12979
        set PRIMES[1546] = 12983
        set PRIMES[1547] = 13001
        set PRIMES[1548] = 13003
        set PRIMES[1549] = 13007
        set PRIMES[1550] = 13009
        set PRIMES[1551] = 13033
        set PRIMES[1552] = 13037
        set PRIMES[1553] = 13043
        set PRIMES[1554] = 13049
        set PRIMES[1555] = 13063
        set PRIMES[1556] = 13093
        set PRIMES[1557] = 13099
        set PRIMES[1558] = 13103
        set PRIMES[1559] = 13109
        set PRIMES[1560] = 13121
        set PRIMES[1561] = 13127
        set PRIMES[1562] = 13147
        set PRIMES[1563] = 13151
        set PRIMES[1564] = 13159
        set PRIMES[1565] = 13163
        set PRIMES[1566] = 13171
        set PRIMES[1567] = 13177
        set PRIMES[1568] = 13183
        set PRIMES[1569] = 13187
        set PRIMES[1570] = 13217
        set PRIMES[1571] = 13219
        set PRIMES[1572] = 13229
        set PRIMES[1573] = 13241
        set PRIMES[1574] = 13249
        set PRIMES[1575] = 13259
        set PRIMES[1576] = 13267
        set PRIMES[1577] = 13291
        set PRIMES[1578] = 13297
        set PRIMES[1579] = 13309
        set PRIMES[1580] = 13313
        set PRIMES[1581] = 13327
        set PRIMES[1582] = 13331
        set PRIMES[1583] = 13337
        set PRIMES[1584] = 13339
        set PRIMES[1585] = 13367
        set PRIMES[1586] = 13381
        set PRIMES[1587] = 13397
        set PRIMES[1588] = 13399
        set PRIMES[1589] = 13411
        set PRIMES[1590] = 13417
        set PRIMES[1591] = 13421
        set PRIMES[1592] = 13441
        set PRIMES[1593] = 13451
        set PRIMES[1594] = 13457
        set PRIMES[1595] = 13463
        set PRIMES[1596] = 13469
        set PRIMES[1597] = 13477
        set PRIMES[1598] = 13487
        set PRIMES[1599] = 13499
        set PRIMES[1600] = 13513
        set PRIMES[1601] = 13523
        set PRIMES[1602] = 13537
        set PRIMES[1603] = 13553
        set PRIMES[1604] = 13567
        set PRIMES[1605] = 13577
        set PRIMES[1606] = 13591
        set PRIMES[1607] = 13597
        set PRIMES[1608] = 13613
        set PRIMES[1609] = 13619
        set PRIMES[1610] = 13627
        set PRIMES[1611] = 13633
        set PRIMES[1612] = 13649
        set PRIMES[1613] = 13669
        set PRIMES[1614] = 13679
        set PRIMES[1615] = 13681
        set PRIMES[1616] = 13687
        set PRIMES[1617] = 13691
        set PRIMES[1618] = 13693
        set PRIMES[1619] = 13697
        set PRIMES[1620] = 13709
        set PRIMES[1621] = 13711
        set PRIMES[1622] = 13721
        set PRIMES[1623] = 13723
        set PRIMES[1624] = 13729
        set PRIMES[1625] = 13751
        set PRIMES[1626] = 13757
        set PRIMES[1627] = 13759
        set PRIMES[1628] = 13763
        set PRIMES[1629] = 13781
        set PRIMES[1630] = 13789
        set PRIMES[1631] = 13799
        set PRIMES[1632] = 13807
        set PRIMES[1633] = 13829
        set PRIMES[1634] = 13831
        set PRIMES[1635] = 13841
        set PRIMES[1636] = 13859
        set PRIMES[1637] = 13873
        set PRIMES[1638] = 13877
        set PRIMES[1639] = 13879
        set PRIMES[1640] = 13883
        set PRIMES[1641] = 13901
        set PRIMES[1642] = 13903
        set PRIMES[1643] = 13907
        set PRIMES[1644] = 13913
        set PRIMES[1645] = 13921
        set PRIMES[1646] = 13931
        set PRIMES[1647] = 13933
        set PRIMES[1648] = 13963
        set PRIMES[1649] = 13967
        set PRIMES[1650] = 13997
        set PRIMES[1651] = 13999
        set PRIMES[1652] = 14009
        set PRIMES[1653] = 14011
        set PRIMES[1654] = 14029
        set PRIMES[1655] = 14033
        set PRIMES[1656] = 14051
        set PRIMES[1657] = 14057
        set PRIMES[1658] = 14071
        set PRIMES[1659] = 14081
        set PRIMES[1660] = 14083
        set PRIMES[1661] = 14087
        set PRIMES[1662] = 14107
        set PRIMES[1663] = 14143
        set PRIMES[1664] = 14149
        set PRIMES[1665] = 14153
        set PRIMES[1666] = 14159
        set PRIMES[1667] = 14173
        set PRIMES[1668] = 14177
        set PRIMES[1669] = 14197
        set PRIMES[1670] = 14207
        set PRIMES[1671] = 14221
        set PRIMES[1672] = 14243
        set PRIMES[1673] = 14249
        set PRIMES[1674] = 14251
        set PRIMES[1675] = 14281
        set PRIMES[1676] = 14293
        set PRIMES[1677] = 14303
        set PRIMES[1678] = 14321
        set PRIMES[1679] = 14323
        set PRIMES[1680] = 14327
        set PRIMES[1681] = 14341
        set PRIMES[1682] = 14347
        set PRIMES[1683] = 14369
        set PRIMES[1684] = 14387
        set PRIMES[1685] = 14389
        set PRIMES[1686] = 14401
        set PRIMES[1687] = 14407
        set PRIMES[1688] = 14411
        set PRIMES[1689] = 14419
        set PRIMES[1690] = 14423
        set PRIMES[1691] = 14431
        set PRIMES[1692] = 14437
        set PRIMES[1693] = 14447
        set PRIMES[1694] = 14449
        set PRIMES[1695] = 14461
        set PRIMES[1696] = 14479
        set PRIMES[1697] = 14489
        set PRIMES[1698] = 14503
        set PRIMES[1699] = 14519
        set PRIMES[1700] = 14533
        set PRIMES[1701] = 14537
        set PRIMES[1702] = 14543
        set PRIMES[1703] = 14549
        set PRIMES[1704] = 14551
        set PRIMES[1705] = 14557
        set PRIMES[1706] = 14561
        set PRIMES[1707] = 14563
        set PRIMES[1708] = 14591
        set PRIMES[1709] = 14593
        set PRIMES[1710] = 14621
        set PRIMES[1711] = 14627
        set PRIMES[1712] = 14629
        set PRIMES[1713] = 14633
        set PRIMES[1714] = 14639
        set PRIMES[1715] = 14653
        set PRIMES[1716] = 14657
        set PRIMES[1717] = 14669
        set PRIMES[1718] = 14683
        set PRIMES[1719] = 14699
        set PRIMES[1720] = 14713
        set PRIMES[1721] = 14717
        set PRIMES[1722] = 14723
        set PRIMES[1723] = 14731
        set PRIMES[1724] = 14737
        set PRIMES[1725] = 14741
        set PRIMES[1726] = 14747
        set PRIMES[1727] = 14753
        set PRIMES[1728] = 14759
        set PRIMES[1729] = 14767
        set PRIMES[1730] = 14771
        set PRIMES[1731] = 14779
        set PRIMES[1732] = 14783
        set PRIMES[1733] = 14797
        set PRIMES[1734] = 14813
        set PRIMES[1735] = 14821
        set PRIMES[1736] = 14827
        set PRIMES[1737] = 14831
        set PRIMES[1738] = 14843
        set PRIMES[1739] = 14851
        set PRIMES[1740] = 14867
        set PRIMES[1741] = 14869
        set PRIMES[1742] = 14879
        set PRIMES[1743] = 14887
        set PRIMES[1744] = 14891
        set PRIMES[1745] = 14897
        set PRIMES[1746] = 14923
        set PRIMES[1747] = 14929
        set PRIMES[1748] = 14939
        set PRIMES[1749] = 14947
        set PRIMES[1750] = 14951
        set PRIMES[1751] = 14957
        set PRIMES[1752] = 14969
        set PRIMES[1753] = 14983
        set PRIMES[1754] = 15013
        set PRIMES[1755] = 15017
        set PRIMES[1756] = 15031
        set PRIMES[1757] = 15053
        set PRIMES[1758] = 15061
        set PRIMES[1759] = 15073
        set PRIMES[1760] = 15077
        set PRIMES[1761] = 15083
        set PRIMES[1762] = 15091
        set PRIMES[1763] = 15101
        set PRIMES[1764] = 15107
        set PRIMES[1765] = 15121
        set PRIMES[1766] = 15131
        set PRIMES[1767] = 15137
        set PRIMES[1768] = 15139
        set PRIMES[1769] = 15149
        set PRIMES[1770] = 15161
        set PRIMES[1771] = 15173
        set PRIMES[1772] = 15187
        set PRIMES[1773] = 15193
        set PRIMES[1774] = 15199
        set PRIMES[1775] = 15217
        set PRIMES[1776] = 15227
        set PRIMES[1777] = 15233
        set PRIMES[1778] = 15241
        set PRIMES[1779] = 15259
        set PRIMES[1780] = 15263
        set PRIMES[1781] = 15269
        set PRIMES[1782] = 15271
        set PRIMES[1783] = 15277
        set PRIMES[1784] = 15287
        set PRIMES[1785] = 15289
        set PRIMES[1786] = 15299
        set PRIMES[1787] = 15307
        set PRIMES[1788] = 15313
        set PRIMES[1789] = 15319
        set PRIMES[1790] = 15329
        set PRIMES[1791] = 15331
        set PRIMES[1792] = 15349
        set PRIMES[1793] = 15359
        set PRIMES[1794] = 15361
        set PRIMES[1795] = 15373
        set PRIMES[1796] = 15377
        set PRIMES[1797] = 15383
        set PRIMES[1798] = 15391
        set PRIMES[1799] = 15401
        set PRIMES[1800] = 15413
        set PRIMES[1801] = 15427
        set PRIMES[1802] = 15439
        set PRIMES[1803] = 15443
        set PRIMES[1804] = 15451
        set PRIMES[1805] = 15461
        set PRIMES[1806] = 15467
        set PRIMES[1807] = 15473
        set PRIMES[1808] = 15493
        set PRIMES[1809] = 15497
        set PRIMES[1810] = 15511
        set PRIMES[1811] = 15527
        set PRIMES[1812] = 15541
        set PRIMES[1813] = 15551
        set PRIMES[1814] = 15559
        set PRIMES[1815] = 15569
        set PRIMES[1816] = 15581
        set PRIMES[1817] = 15583
        set PRIMES[1818] = 15601
        set PRIMES[1819] = 15607
        set PRIMES[1820] = 15619
        set PRIMES[1821] = 15629
        set PRIMES[1822] = 15641
        set PRIMES[1823] = 15643
        set PRIMES[1824] = 15647
        set PRIMES[1825] = 15649
        set PRIMES[1826] = 15661
        set PRIMES[1827] = 15667
        set PRIMES[1828] = 15671
        set PRIMES[1829] = 15679
        set PRIMES[1830] = 15683
        set PRIMES[1831] = 15727
        set PRIMES[1832] = 15731
        set PRIMES[1833] = 15733
        set PRIMES[1834] = 15737
        set PRIMES[1835] = 15739
        set PRIMES[1836] = 15749
        set PRIMES[1837] = 15761
        set PRIMES[1838] = 15767
        set PRIMES[1839] = 15773
        set PRIMES[1840] = 15787
        set PRIMES[1841] = 15791
        set PRIMES[1842] = 15797
        set PRIMES[1843] = 15803
        set PRIMES[1844] = 15809
        set PRIMES[1845] = 15817
        set PRIMES[1846] = 15823
        set PRIMES[1847] = 15859
        set PRIMES[1848] = 15877
        set PRIMES[1849] = 15881
        set PRIMES[1850] = 15887
        set PRIMES[1851] = 15889
        set PRIMES[1852] = 15901
        set PRIMES[1853] = 15907
        set PRIMES[1854] = 15913
        set PRIMES[1855] = 15919
        set PRIMES[1856] = 15923
        set PRIMES[1857] = 15937
        set PRIMES[1858] = 15959
        set PRIMES[1859] = 15971
        set PRIMES[1860] = 15973
        set PRIMES[1861] = 15991
        set PRIMES[1862] = 16001
        set PRIMES[1863] = 16007
        set PRIMES[1864] = 16033
        set PRIMES[1865] = 16057
        set PRIMES[1866] = 16061
        set PRIMES[1867] = 16063
        set PRIMES[1868] = 16067
        set PRIMES[1869] = 16069
        set PRIMES[1870] = 16073
        set PRIMES[1871] = 16087
        set PRIMES[1872] = 16091
        set PRIMES[1873] = 16097
        set PRIMES[1874] = 16103
        set PRIMES[1875] = 16111
        set PRIMES[1876] = 16127
        set PRIMES[1877] = 16139
        set PRIMES[1878] = 16141
        set PRIMES[1879] = 16183
        set PRIMES[1880] = 16187
        set PRIMES[1881] = 16189
        set PRIMES[1882] = 16193
        set PRIMES[1883] = 16217
        set PRIMES[1884] = 16223
        set PRIMES[1885] = 16229
        set PRIMES[1886] = 16231
        set PRIMES[1887] = 16249
        set PRIMES[1888] = 16253
        set PRIMES[1889] = 16267
        set PRIMES[1890] = 16273
        set PRIMES[1891] = 16301
        set PRIMES[1892] = 16319
        set PRIMES[1893] = 16333
        set PRIMES[1894] = 16339
        set PRIMES[1895] = 16349
        set PRIMES[1896] = 16361
        set PRIMES[1897] = 16363
        set PRIMES[1898] = 16369
        set PRIMES[1899] = 16381
        set PRIMES[1900] = 16411
        set PRIMES[1901] = 16417
        set PRIMES[1902] = 16421
        set PRIMES[1903] = 16427
        set PRIMES[1904] = 16433
        set PRIMES[1905] = 16447
        set PRIMES[1906] = 16451
        set PRIMES[1907] = 16453
        set PRIMES[1908] = 16477
        set PRIMES[1909] = 16481
        set PRIMES[1910] = 16487
        set PRIMES[1911] = 16493
        set PRIMES[1912] = 16519
        set PRIMES[1913] = 16529
        set PRIMES[1914] = 16547
        set PRIMES[1915] = 16553
        set PRIMES[1916] = 16561
        set PRIMES[1917] = 16567
        set PRIMES[1918] = 16573
        set PRIMES[1919] = 16603
        set PRIMES[1920] = 16607
        set PRIMES[1921] = 16619
        set PRIMES[1922] = 16631
        set PRIMES[1923] = 16633
        set PRIMES[1924] = 16649
        set PRIMES[1925] = 16651
        set PRIMES[1926] = 16657
        set PRIMES[1927] = 16661
        set PRIMES[1928] = 16673
        set PRIMES[1929] = 16691
        set PRIMES[1930] = 16693
        set PRIMES[1931] = 16699
        set PRIMES[1932] = 16703
        set PRIMES[1933] = 16729
        set PRIMES[1934] = 16741
        set PRIMES[1935] = 16747
        set PRIMES[1936] = 16759
        set PRIMES[1937] = 16763
        set PRIMES[1938] = 16787
        set PRIMES[1939] = 16811
        set PRIMES[1940] = 16823
        set PRIMES[1941] = 16829
        set PRIMES[1942] = 16831
        set PRIMES[1943] = 16843
        set PRIMES[1944] = 16871
        set PRIMES[1945] = 16879
        set PRIMES[1946] = 16883
        set PRIMES[1947] = 16889
        set PRIMES[1948] = 16901
        set PRIMES[1949] = 16903
        set PRIMES[1950] = 16921
        set PRIMES[1951] = 16927
        set PRIMES[1952] = 16931
        set PRIMES[1953] = 16937
        set PRIMES[1954] = 16943
        set PRIMES[1955] = 16963
        set PRIMES[1956] = 16979
        set PRIMES[1957] = 16981
        set PRIMES[1958] = 16987
        set PRIMES[1959] = 16993
        set PRIMES[1960] = 17011
        set PRIMES[1961] = 17021
        set PRIMES[1962] = 17027
        set PRIMES[1963] = 17029
        set PRIMES[1964] = 17033
        set PRIMES[1965] = 17041
        set PRIMES[1966] = 17047
        set PRIMES[1967] = 17053
        set PRIMES[1968] = 17077
        set PRIMES[1969] = 17093
        set PRIMES[1970] = 17099
        set PRIMES[1971] = 17107
        set PRIMES[1972] = 17117
        set PRIMES[1973] = 17123
        set PRIMES[1974] = 17137
        set PRIMES[1975] = 17159
        set PRIMES[1976] = 17167
        set PRIMES[1977] = 17183
        set PRIMES[1978] = 17189
        set PRIMES[1979] = 17191
        set PRIMES[1980] = 17203
        set PRIMES[1981] = 17207
        set PRIMES[1982] = 17209
        set PRIMES[1983] = 17231
        set PRIMES[1984] = 17239
        set PRIMES[1985] = 17257
        set PRIMES[1986] = 17291
        set PRIMES[1987] = 17293
        set PRIMES[1988] = 17299
        set PRIMES[1989] = 17317
        set PRIMES[1990] = 17321
        set PRIMES[1991] = 17327
        set PRIMES[1992] = 17333
        set PRIMES[1993] = 17341
        set PRIMES[1994] = 17351
        set PRIMES[1995] = 17359
        set PRIMES[1996] = 17377
        set PRIMES[1997] = 17383
        set PRIMES[1998] = 17387
        set PRIMES[1999] = 17389
        set PRIMES[2000] = 17393
        set PRIMES[2001] = 17401
        set PRIMES[2002] = 17417
        set PRIMES[2003] = 17419
        set PRIMES[2004] = 17431
        set PRIMES[2005] = 17443
        set PRIMES[2006] = 17449
        set PRIMES[2007] = 17467
        set PRIMES[2008] = 17471
        set PRIMES[2009] = 17477
        set PRIMES[2010] = 17483
        set PRIMES[2011] = 17489
        set PRIMES[2012] = 17491
        set PRIMES[2013] = 17497
        set PRIMES[2014] = 17509
        set PRIMES[2015] = 17519
        set PRIMES[2016] = 17539
        set PRIMES[2017] = 17551
        set PRIMES[2018] = 17569
        set PRIMES[2019] = 17573
        set PRIMES[2020] = 17579
        set PRIMES[2021] = 17581
        set PRIMES[2022] = 17597
        set PRIMES[2023] = 17599
        set PRIMES[2024] = 17609
        set PRIMES[2025] = 17623
        set PRIMES[2026] = 17627
        set PRIMES[2027] = 17657
        set PRIMES[2028] = 17659
        set PRIMES[2029] = 17669
        set PRIMES[2030] = 17681
        set PRIMES[2031] = 17683
        set PRIMES[2032] = 17707
        set PRIMES[2033] = 17713
        set PRIMES[2034] = 17729
        set PRIMES[2035] = 17737
        set PRIMES[2036] = 17747
        set PRIMES[2037] = 17749
        set PRIMES[2038] = 17761
        set PRIMES[2039] = 17783
        set PRIMES[2040] = 17789
        set PRIMES[2041] = 17791
        set PRIMES[2042] = 17807
        set PRIMES[2043] = 17827
        set PRIMES[2044] = 17837
        set PRIMES[2045] = 17839
        set PRIMES[2046] = 17851
        set PRIMES[2047] = 17863
        set PRIMES[2048] = 17881
        set PRIMES[2049] = 17891
        set PRIMES[2050] = 17903
        set PRIMES[2051] = 17909
        set PRIMES[2052] = 17911
        set PRIMES[2053] = 17921
        set PRIMES[2054] = 17923
        set PRIMES[2055] = 17929
        set PRIMES[2056] = 17939
        set PRIMES[2057] = 17957
        set PRIMES[2058] = 17959
        set PRIMES[2059] = 17971
        set PRIMES[2060] = 17977
        set PRIMES[2061] = 17981
        set PRIMES[2062] = 17987
        set PRIMES[2063] = 17989
        set PRIMES[2064] = 18013
        set PRIMES[2065] = 18041
        set PRIMES[2066] = 18043
        set PRIMES[2067] = 18047
        set PRIMES[2068] = 18049
        set PRIMES[2069] = 18059
        set PRIMES[2070] = 18061
        set PRIMES[2071] = 18077
        set PRIMES[2072] = 18089
        set PRIMES[2073] = 18097
        set PRIMES[2074] = 18119
        set PRIMES[2075] = 18121
        set PRIMES[2076] = 18127
        set PRIMES[2077] = 18131
        set PRIMES[2078] = 18133
        set PRIMES[2079] = 18143
        set PRIMES[2080] = 18149
        set PRIMES[2081] = 18169
        set PRIMES[2082] = 18181
        set PRIMES[2083] = 18191
        set PRIMES[2084] = 18199
        set PRIMES[2085] = 18211
        set PRIMES[2086] = 18217
        set PRIMES[2087] = 18223
        set PRIMES[2088] = 18229
        set PRIMES[2089] = 18233
        set PRIMES[2090] = 18251
        set PRIMES[2091] = 18253
        set PRIMES[2092] = 18257
        set PRIMES[2093] = 18269
        set PRIMES[2094] = 18287
        set PRIMES[2095] = 18289
        set PRIMES[2096] = 18301
        set PRIMES[2097] = 18307
        set PRIMES[2098] = 18311
        set PRIMES[2099] = 18313
        set PRIMES[2100] = 18329
        set PRIMES[2101] = 18341
        set PRIMES[2102] = 18353
        set PRIMES[2103] = 18367
        set PRIMES[2104] = 18371
        set PRIMES[2105] = 18379
        set PRIMES[2106] = 18397
        set PRIMES[2107] = 18401
        set PRIMES[2108] = 18413
        set PRIMES[2109] = 18427
        set PRIMES[2110] = 18433
        set PRIMES[2111] = 18439
        set PRIMES[2112] = 18443
        set PRIMES[2113] = 18451
        set PRIMES[2114] = 18457
        set PRIMES[2115] = 18461
        set PRIMES[2116] = 18481
        set PRIMES[2117] = 18493
        set PRIMES[2118] = 18503
        set PRIMES[2119] = 18517
        set PRIMES[2120] = 18521
        set PRIMES[2121] = 18523
        set PRIMES[2122] = 18539
        set PRIMES[2123] = 18541
        set PRIMES[2124] = 18553
        set PRIMES[2125] = 18583
        set PRIMES[2126] = 18587
        set PRIMES[2127] = 18593
        set PRIMES[2128] = 18617
        set PRIMES[2129] = 18637
        set PRIMES[2130] = 18661
        set PRIMES[2131] = 18671
        set PRIMES[2132] = 18679
        set PRIMES[2133] = 18691
        set PRIMES[2134] = 18701
        set PRIMES[2135] = 18713
        set PRIMES[2136] = 18719
        set PRIMES[2137] = 18731
        set PRIMES[2138] = 18743
        set PRIMES[2139] = 18749
        set PRIMES[2140] = 18757
        set PRIMES[2141] = 18773
        set PRIMES[2142] = 18787
        set PRIMES[2143] = 18793
        set PRIMES[2144] = 18797
        set PRIMES[2145] = 18803
        set PRIMES[2146] = 18839
        set PRIMES[2147] = 18859
        set PRIMES[2148] = 18869
        set PRIMES[2149] = 18899
        set PRIMES[2150] = 18911
        set PRIMES[2151] = 18913
        set PRIMES[2152] = 18917
        set PRIMES[2153] = 18919
        set PRIMES[2154] = 18947
        set PRIMES[2155] = 18959
        set PRIMES[2156] = 18973
        set PRIMES[2157] = 18979
        set PRIMES[2158] = 19001
        set PRIMES[2159] = 19009
        set PRIMES[2160] = 19013
        set PRIMES[2161] = 19031
        set PRIMES[2162] = 19037
        set PRIMES[2163] = 19051
        set PRIMES[2164] = 19069
        set PRIMES[2165] = 19073
        set PRIMES[2166] = 19079
        set PRIMES[2167] = 19081
        set PRIMES[2168] = 19087
        set PRIMES[2169] = 19121
        set PRIMES[2170] = 19139
        set PRIMES[2171] = 19141
        set PRIMES[2172] = 19157
        set PRIMES[2173] = 19163
        set PRIMES[2174] = 19181
        set PRIMES[2175] = 19183
        set PRIMES[2176] = 19207
        set PRIMES[2177] = 19211
        set PRIMES[2178] = 19213
        set PRIMES[2179] = 19219
        set PRIMES[2180] = 19231
        set PRIMES[2181] = 19237
        set PRIMES[2182] = 19249
        set PRIMES[2183] = 19259
        set PRIMES[2184] = 19267
        set PRIMES[2185] = 19273
        set PRIMES[2186] = 19289
        set PRIMES[2187] = 19301
        set PRIMES[2188] = 19309
        set PRIMES[2189] = 19319
        set PRIMES[2190] = 19333
        set PRIMES[2191] = 19373
        set PRIMES[2192] = 19379
        set PRIMES[2193] = 19381
        set PRIMES[2194] = 19387
        set PRIMES[2195] = 19391
        set PRIMES[2196] = 19403
        set PRIMES[2197] = 19417
        set PRIMES[2198] = 19421
        set PRIMES[2199] = 19423
        set PRIMES[2200] = 19427
        set PRIMES[2201] = 19429
        set PRIMES[2202] = 19433
        set PRIMES[2203] = 19441
        set PRIMES[2204] = 19447
        set PRIMES[2205] = 19457
        set PRIMES[2206] = 19463
        set PRIMES[2207] = 19469
        set PRIMES[2208] = 19471
        set PRIMES[2209] = 19477
        set PRIMES[2210] = 19483
        set PRIMES[2211] = 19489
        set PRIMES[2212] = 19501
        set PRIMES[2213] = 19507
        set PRIMES[2214] = 19531
        set PRIMES[2215] = 19541
        set PRIMES[2216] = 19543
        set PRIMES[2217] = 19553
        set PRIMES[2218] = 19559
        set PRIMES[2219] = 19571
        set PRIMES[2220] = 19577
        set PRIMES[2221] = 19583
        set PRIMES[2222] = 19597
        set PRIMES[2223] = 19603
        set PRIMES[2224] = 19609
        set PRIMES[2225] = 19661
        set PRIMES[2226] = 19681
        set PRIMES[2227] = 19687
        set PRIMES[2228] = 19697
        set PRIMES[2229] = 19699
        set PRIMES[2230] = 19709
        set PRIMES[2231] = 19717
        set PRIMES[2232] = 19727
        set PRIMES[2233] = 19739
        set PRIMES[2234] = 19751
        set PRIMES[2235] = 19753
        set PRIMES[2236] = 19759
        set PRIMES[2237] = 19763
        set PRIMES[2238] = 19777
        set PRIMES[2239] = 19793
        set PRIMES[2240] = 19801
        set PRIMES[2241] = 19813
        set PRIMES[2242] = 19819
        set PRIMES[2243] = 19841
        set PRIMES[2244] = 19843
        set PRIMES[2245] = 19853
        set PRIMES[2246] = 19861
        set PRIMES[2247] = 19867
        set PRIMES[2248] = 19889
        set PRIMES[2249] = 19891
        set PRIMES[2250] = 19913
        set PRIMES[2251] = 19919
        set PRIMES[2252] = 19927
        set PRIMES[2253] = 19937
        set PRIMES[2254] = 19949
        set PRIMES[2255] = 19961
        set PRIMES[2256] = 19963
        set PRIMES[2257] = 19973
        set PRIMES[2258] = 19979
        set PRIMES[2259] = 19991
        set PRIMES[2260] = 19993
        set PRIMES[2261] = 19997
        set PRIMES[2262] = 20011
        set PRIMES[2263] = 20021
        set PRIMES[2264] = 20023
        set PRIMES[2265] = 20029
        set PRIMES[2266] = 20047
        set PRIMES[2267] = 20051
        set PRIMES[2268] = 20063
        set PRIMES[2269] = 20071
        set PRIMES[2270] = 20089
        set PRIMES[2271] = 20101
        set PRIMES[2272] = 20107
        set PRIMES[2273] = 20113
        set PRIMES[2274] = 20117
        set PRIMES[2275] = 20123
        set PRIMES[2276] = 20129
        set PRIMES[2277] = 20143
        set PRIMES[2278] = 20147
        set PRIMES[2279] = 20149
        set PRIMES[2280] = 20161
        set PRIMES[2281] = 20173
        set PRIMES[2282] = 20177
        set PRIMES[2283] = 20183
        set PRIMES[2284] = 20201
        set PRIMES[2285] = 20219
        set PRIMES[2286] = 20231
        set PRIMES[2287] = 20233
        set PRIMES[2288] = 20249
        set PRIMES[2289] = 20261
        set PRIMES[2290] = 20269
        set PRIMES[2291] = 20287
        set PRIMES[2292] = 20297
        set PRIMES[2293] = 20323
        set PRIMES[2294] = 20327
        set PRIMES[2295] = 20333
        set PRIMES[2296] = 20341
        set PRIMES[2297] = 20347
        set PRIMES[2298] = 20353
        set PRIMES[2299] = 20357
        set PRIMES[2300] = 20359
        set PRIMES[2301] = 20369
        set PRIMES[2302] = 20389
        set PRIMES[2303] = 20393
        set PRIMES[2304] = 20399
        set PRIMES[2305] = 20407
        set PRIMES[2306] = 20411
        set PRIMES[2307] = 20431
        set PRIMES[2308] = 20441
        set PRIMES[2309] = 20443
        set PRIMES[2310] = 20477
        set PRIMES[2311] = 20479
        set PRIMES[2312] = 20483
        set PRIMES[2313] = 20507
        set PRIMES[2314] = 20509
        set PRIMES[2315] = 20521
        set PRIMES[2316] = 20533
        set PRIMES[2317] = 20543
        set PRIMES[2318] = 20549
        set PRIMES[2319] = 20551
        set PRIMES[2320] = 20563
        set PRIMES[2321] = 20593
        set PRIMES[2322] = 20599
        set PRIMES[2323] = 20611
        set PRIMES[2324] = 20627
        set PRIMES[2325] = 20639
        set PRIMES[2326] = 20641
        set PRIMES[2327] = 20663
        set PRIMES[2328] = 20681
        set PRIMES[2329] = 20693
        set PRIMES[2330] = 20707
        set PRIMES[2331] = 20717
        set PRIMES[2332] = 20719
        set PRIMES[2333] = 20731
        set PRIMES[2334] = 20743
        set PRIMES[2335] = 20747
        set PRIMES[2336] = 20749
        set PRIMES[2337] = 20753
        set PRIMES[2338] = 20759
        set PRIMES[2339] = 20771
        set PRIMES[2340] = 20773
        set PRIMES[2341] = 20789
        set PRIMES[2342] = 20807
        set PRIMES[2343] = 20809
        set PRIMES[2344] = 20849
        set PRIMES[2345] = 20857
        set PRIMES[2346] = 20873
        set PRIMES[2347] = 20879
        set PRIMES[2348] = 20887
        set PRIMES[2349] = 20897
        set PRIMES[2350] = 20899
        set PRIMES[2351] = 20903
        set PRIMES[2352] = 20921
        set PRIMES[2353] = 20929
        set PRIMES[2354] = 20939
        set PRIMES[2355] = 20947
        set PRIMES[2356] = 20959
        set PRIMES[2357] = 20963
        set PRIMES[2358] = 20981
        set PRIMES[2359] = 20983
        set PRIMES[2360] = 21001
        set PRIMES[2361] = 21011
        set PRIMES[2362] = 21013
        set PRIMES[2363] = 21017
        set PRIMES[2364] = 21019
        set PRIMES[2365] = 21023
        set PRIMES[2366] = 21031
        set PRIMES[2367] = 21059
        set PRIMES[2368] = 21061
        set PRIMES[2369] = 21067
        set PRIMES[2370] = 21089
        set PRIMES[2371] = 21101
        set PRIMES[2372] = 21107
        set PRIMES[2373] = 21121
        set PRIMES[2374] = 21139
        set PRIMES[2375] = 21143
        set PRIMES[2376] = 21149
        set PRIMES[2377] = 21157
        set PRIMES[2378] = 21163
        set PRIMES[2379] = 21169
        set PRIMES[2380] = 21179
        set PRIMES[2381] = 21187
        set PRIMES[2382] = 21191
        set PRIMES[2383] = 21193
        set PRIMES[2384] = 21211
        set PRIMES[2385] = 21221
        set PRIMES[2386] = 21227
        set PRIMES[2387] = 21247
        set PRIMES[2388] = 21269
        set PRIMES[2389] = 21277
        set PRIMES[2390] = 21283
        set PRIMES[2391] = 21313
        set PRIMES[2392] = 21317
        set PRIMES[2393] = 21319
        set PRIMES[2394] = 21323
        set PRIMES[2395] = 21341
        set PRIMES[2396] = 21347
        set PRIMES[2397] = 21377
        set PRIMES[2398] = 21379
        set PRIMES[2399] = 21383
        set PRIMES[2400] = 21391
        set PRIMES[2401] = 21397
        set PRIMES[2402] = 21401
        set PRIMES[2403] = 21407
        set PRIMES[2404] = 21419
        set PRIMES[2405] = 21433
        set PRIMES[2406] = 21467
        set PRIMES[2407] = 21481
        set PRIMES[2408] = 21487
        set PRIMES[2409] = 21491
        set PRIMES[2410] = 21493
        set PRIMES[2411] = 21499
        set PRIMES[2412] = 21503
        set PRIMES[2413] = 21517
        set PRIMES[2414] = 21521
        set PRIMES[2415] = 21523
        set PRIMES[2416] = 21529
        set PRIMES[2417] = 21557
        set PRIMES[2418] = 21559
        set PRIMES[2419] = 21563
        set PRIMES[2420] = 21569
        set PRIMES[2421] = 21577
        set PRIMES[2422] = 21587
        set PRIMES[2423] = 21589
        set PRIMES[2424] = 21599
        set PRIMES[2425] = 21601
        set PRIMES[2426] = 21611
        set PRIMES[2427] = 21613
        set PRIMES[2428] = 21617
        set PRIMES[2429] = 21647
        set PRIMES[2430] = 21649
        set PRIMES[2431] = 21661
        set PRIMES[2432] = 21673
        set PRIMES[2433] = 21683
        set PRIMES[2434] = 21701
        set PRIMES[2435] = 21713
        set PRIMES[2436] = 21727
        set PRIMES[2437] = 21737
        set PRIMES[2438] = 21739
        set PRIMES[2439] = 21751
        set PRIMES[2440] = 21757
        set PRIMES[2441] = 21767
        set PRIMES[2442] = 21773
        set PRIMES[2443] = 21787
        set PRIMES[2444] = 21799
        set PRIMES[2445] = 21803
        set PRIMES[2446] = 21817
        set PRIMES[2447] = 21821
        set PRIMES[2448] = 21839
        set PRIMES[2449] = 21841
        set PRIMES[2450] = 21851
        set PRIMES[2451] = 21859
        set PRIMES[2452] = 21863
        set PRIMES[2453] = 21871
        set PRIMES[2454] = 21881
        set PRIMES[2455] = 21893
        set PRIMES[2456] = 21911
        set PRIMES[2457] = 21929
        set PRIMES[2458] = 21937
        set PRIMES[2459] = 21943
        set PRIMES[2460] = 21961
        set PRIMES[2461] = 21977
        set PRIMES[2462] = 21991
        set PRIMES[2463] = 21997
        set PRIMES[2464] = 22003
        set PRIMES[2465] = 22013
        set PRIMES[2466] = 22027
        set PRIMES[2467] = 22031
        set PRIMES[2468] = 22037
        set PRIMES[2469] = 22039
        set PRIMES[2470] = 22051
        set PRIMES[2471] = 22063
        set PRIMES[2472] = 22067
        set PRIMES[2473] = 22073
        set PRIMES[2474] = 22079
        set PRIMES[2475] = 22091
        set PRIMES[2476] = 22093
        set PRIMES[2477] = 22109
        set PRIMES[2478] = 22111
        set PRIMES[2479] = 22123
        set PRIMES[2480] = 22129
        set PRIMES[2481] = 22133
        set PRIMES[2482] = 22147
        set PRIMES[2483] = 22153
        set PRIMES[2484] = 22157
        set PRIMES[2485] = 22159
        set PRIMES[2486] = 22171
        set PRIMES[2487] = 22189
        set PRIMES[2488] = 22193
        set PRIMES[2489] = 22229
        set PRIMES[2490] = 22247
        set PRIMES[2491] = 22259
        set PRIMES[2492] = 22271
        set PRIMES[2493] = 22273
        set PRIMES[2494] = 22277
        set PRIMES[2495] = 22279
        set PRIMES[2496] = 22283
        set PRIMES[2497] = 22291
        set PRIMES[2498] = 22303
        set PRIMES[2499] = 22307
        set PRIMES[2500] = 22343
        set PRIMES[2501] = 22349
        set PRIMES[2502] = 22367
        set PRIMES[2503] = 22369
        set PRIMES[2504] = 22381
        set PRIMES[2505] = 22391
        set PRIMES[2506] = 22397
        set PRIMES[2507] = 22409
        set PRIMES[2508] = 22433
        set PRIMES[2509] = 22441
        set PRIMES[2510] = 22447
        set PRIMES[2511] = 22453
        set PRIMES[2512] = 22469
        set PRIMES[2513] = 22481
        set PRIMES[2514] = 22483
        set PRIMES[2515] = 22501
        set PRIMES[2516] = 22511
        set PRIMES[2517] = 22531
        set PRIMES[2518] = 22541
        set PRIMES[2519] = 22543
        set PRIMES[2520] = 22549
        set PRIMES[2521] = 22567
        set PRIMES[2522] = 22571
        set PRIMES[2523] = 22573
        set PRIMES[2524] = 22613
        set PRIMES[2525] = 22619
        set PRIMES[2526] = 22621
        set PRIMES[2527] = 22637
        set PRIMES[2528] = 22639
        set PRIMES[2529] = 22643
        set PRIMES[2530] = 22651
        set PRIMES[2531] = 22669
        set PRIMES[2532] = 22679
        set PRIMES[2533] = 22691
        set PRIMES[2534] = 22697
        set PRIMES[2535] = 22699
        set PRIMES[2536] = 22709
        set PRIMES[2537] = 22717
        set PRIMES[2538] = 22721
        set PRIMES[2539] = 22727
        set PRIMES[2540] = 22739
        set PRIMES[2541] = 22741
        set PRIMES[2542] = 22751
        set PRIMES[2543] = 22769
        set PRIMES[2544] = 22777
        set PRIMES[2545] = 22783
        set PRIMES[2546] = 22787
        set PRIMES[2547] = 22807
        set PRIMES[2548] = 22811
        set PRIMES[2549] = 22817
        set PRIMES[2550] = 22853
        set PRIMES[2551] = 22859
        set PRIMES[2552] = 22861
        set PRIMES[2553] = 22871
        set PRIMES[2554] = 22877
        set PRIMES[2555] = 22901
        set PRIMES[2556] = 22907
        set PRIMES[2557] = 22921
        set PRIMES[2558] = 22937
        set PRIMES[2559] = 22943
        set PRIMES[2560] = 22961
        set PRIMES[2561] = 22963
        set PRIMES[2562] = 22973
        set PRIMES[2563] = 22993
        set PRIMES[2564] = 23003
        set PRIMES[2565] = 23011
        set PRIMES[2566] = 23017
        set PRIMES[2567] = 23021
        set PRIMES[2568] = 23027
        set PRIMES[2569] = 23029
        set PRIMES[2570] = 23039
        set PRIMES[2571] = 23041
        set PRIMES[2572] = 23053
        set PRIMES[2573] = 23057
        set PRIMES[2574] = 23059
        set PRIMES[2575] = 23063
        set PRIMES[2576] = 23071
        set PRIMES[2577] = 23081
        set PRIMES[2578] = 23087
        set PRIMES[2579] = 23099
        set PRIMES[2580] = 23117
        set PRIMES[2581] = 23131
        set PRIMES[2582] = 23143
        set PRIMES[2583] = 23159
        set PRIMES[2584] = 23167
        set PRIMES[2585] = 23173
        set PRIMES[2586] = 23189
        set PRIMES[2587] = 23197
        set PRIMES[2588] = 23201
        set PRIMES[2589] = 23203
        set PRIMES[2590] = 23209
        set PRIMES[2591] = 23227
        set PRIMES[2592] = 23251
        set PRIMES[2593] = 23269
        set PRIMES[2594] = 23279
        set PRIMES[2595] = 23291
        set PRIMES[2596] = 23293
        set PRIMES[2597] = 23297
        set PRIMES[2598] = 23311
        set PRIMES[2599] = 23321
        set PRIMES[2600] = 23327
        set PRIMES[2601] = 23333
        set PRIMES[2602] = 23339
        set PRIMES[2603] = 23357
        set PRIMES[2604] = 23369
        set PRIMES[2605] = 23371
        set PRIMES[2606] = 23399
        set PRIMES[2607] = 23417
        set PRIMES[2608] = 23431
        set PRIMES[2609] = 23447
        set PRIMES[2610] = 23459
        set PRIMES[2611] = 23473
        set PRIMES[2612] = 23497
        set PRIMES[2613] = 23509
        set PRIMES[2614] = 23531
        set PRIMES[2615] = 23537
        set PRIMES[2616] = 23539
        set PRIMES[2617] = 23549
        set PRIMES[2618] = 23557
        set PRIMES[2619] = 23561
        set PRIMES[2620] = 23563
        set PRIMES[2621] = 23567
        set PRIMES[2622] = 23581
        set PRIMES[2623] = 23593
        set PRIMES[2624] = 23599
        set PRIMES[2625] = 23603
        set PRIMES[2626] = 23609
        set PRIMES[2627] = 23623
        set PRIMES[2628] = 23627
        set PRIMES[2629] = 23629
        set PRIMES[2630] = 23633
        set PRIMES[2631] = 23663
        set PRIMES[2632] = 23669
        set PRIMES[2633] = 23671
        set PRIMES[2634] = 23677
        set PRIMES[2635] = 23687
        set PRIMES[2636] = 23689
        set PRIMES[2637] = 23719
        set PRIMES[2638] = 23741
        set PRIMES[2639] = 23743
        set PRIMES[2640] = 23747
        set PRIMES[2641] = 23753
        set PRIMES[2642] = 23761
        set PRIMES[2643] = 23767
        set PRIMES[2644] = 23773
        set PRIMES[2645] = 23789
        set PRIMES[2646] = 23801
        set PRIMES[2647] = 23813
        set PRIMES[2648] = 23819
        set PRIMES[2649] = 23827
        set PRIMES[2650] = 23831
        set PRIMES[2651] = 23833
        set PRIMES[2652] = 23857
        set PRIMES[2653] = 23869
        set PRIMES[2654] = 23873
        set PRIMES[2655] = 23879
        set PRIMES[2656] = 23887
        set PRIMES[2657] = 23893
        set PRIMES[2658] = 23899
        set PRIMES[2659] = 23909
        set PRIMES[2660] = 23911
        set PRIMES[2661] = 23917
        set PRIMES[2662] = 23929
        set PRIMES[2663] = 23957
        set PRIMES[2664] = 23971
        set PRIMES[2665] = 23977
        set PRIMES[2666] = 23981
        set PRIMES[2667] = 23993
        set PRIMES[2668] = 24001
        set PRIMES[2669] = 24007
        set PRIMES[2670] = 24019
        set PRIMES[2671] = 24023
        set PRIMES[2672] = 24029
        set PRIMES[2673] = 24043
        set PRIMES[2674] = 24049
        set PRIMES[2675] = 24061
        set PRIMES[2676] = 24071
        set PRIMES[2677] = 24077
        set PRIMES[2678] = 24083
        set PRIMES[2679] = 24091
        set PRIMES[2680] = 24097
        set PRIMES[2681] = 24103
        set PRIMES[2682] = 24107
        set PRIMES[2683] = 24109
        set PRIMES[2684] = 24113
        set PRIMES[2685] = 24121
        set PRIMES[2686] = 24133
        set PRIMES[2687] = 24137
        set PRIMES[2688] = 24151
        set PRIMES[2689] = 24169
        set PRIMES[2690] = 24179
        set PRIMES[2691] = 24181
        set PRIMES[2692] = 24197
        set PRIMES[2693] = 24203
        set PRIMES[2694] = 24223
        set PRIMES[2695] = 24229
        set PRIMES[2696] = 24239
        set PRIMES[2697] = 24247
        set PRIMES[2698] = 24251
        set PRIMES[2699] = 24281
        set PRIMES[2700] = 24317
        set PRIMES[2701] = 24329
        set PRIMES[2702] = 24337
        set PRIMES[2703] = 24359
        set PRIMES[2704] = 24371
        set PRIMES[2705] = 24373
        set PRIMES[2706] = 24379
        set PRIMES[2707] = 24391
        set PRIMES[2708] = 24407
        set PRIMES[2709] = 24413
        set PRIMES[2710] = 24419
        set PRIMES[2711] = 24421
        set PRIMES[2712] = 24439
        set PRIMES[2713] = 24443
        set PRIMES[2714] = 24469
        set PRIMES[2715] = 24473
        set PRIMES[2716] = 24481
        set PRIMES[2717] = 24499
        set PRIMES[2718] = 24509
        set PRIMES[2719] = 24517
        set PRIMES[2720] = 24527
        set PRIMES[2721] = 24533
        set PRIMES[2722] = 24547
        set PRIMES[2723] = 24551
        set PRIMES[2724] = 24571
        set PRIMES[2725] = 24593
        set PRIMES[2726] = 24611
        set PRIMES[2727] = 24623
        set PRIMES[2728] = 24631
        set PRIMES[2729] = 24659
        set PRIMES[2730] = 24671
        set PRIMES[2731] = 24677
        set PRIMES[2732] = 24683
        set PRIMES[2733] = 24691
        set PRIMES[2734] = 24697
        set PRIMES[2735] = 24709
        set PRIMES[2736] = 24733
        set PRIMES[2737] = 24749
        set PRIMES[2738] = 24763
        set PRIMES[2739] = 24767
        set PRIMES[2740] = 24781
        set PRIMES[2741] = 24793
        set PRIMES[2742] = 24799
        set PRIMES[2743] = 24809
        set PRIMES[2744] = 24821
        set PRIMES[2745] = 24841
        set PRIMES[2746] = 24847
        set PRIMES[2747] = 24851
        set PRIMES[2748] = 24859
        set PRIMES[2749] = 24877
        set PRIMES[2750] = 24889
        set PRIMES[2751] = 24907
        set PRIMES[2752] = 24917
        set PRIMES[2753] = 24919
        set PRIMES[2754] = 24923
        set PRIMES[2755] = 24943
        set PRIMES[2756] = 24953
        set PRIMES[2757] = 24967
        set PRIMES[2758] = 24971
        set PRIMES[2759] = 24977
        set PRIMES[2760] = 24979
        set PRIMES[2761] = 24989
        set PRIMES[2762] = 25013
        set PRIMES[2763] = 25031
        set PRIMES[2764] = 25033
        set PRIMES[2765] = 25037
        set PRIMES[2766] = 25057
        set PRIMES[2767] = 25073
        set PRIMES[2768] = 25087
        set PRIMES[2769] = 25097
        set PRIMES[2770] = 25111
        set PRIMES[2771] = 25117
        set PRIMES[2772] = 25121
        set PRIMES[2773] = 25127
        set PRIMES[2774] = 25147
        set PRIMES[2775] = 25153
        set PRIMES[2776] = 25163
        set PRIMES[2777] = 25169
        set PRIMES[2778] = 25171
        set PRIMES[2779] = 25183
        set PRIMES[2780] = 25189
        set PRIMES[2781] = 25219
        set PRIMES[2782] = 25229
        set PRIMES[2783] = 25237
        set PRIMES[2784] = 25243
        set PRIMES[2785] = 25247
        set PRIMES[2786] = 25253
        set PRIMES[2787] = 25261
        set PRIMES[2788] = 25301
        set PRIMES[2789] = 25303
        set PRIMES[2790] = 25307
        set PRIMES[2791] = 25309
        set PRIMES[2792] = 25321
        set PRIMES[2793] = 25339
        set PRIMES[2794] = 25343
        set PRIMES[2795] = 25349
        set PRIMES[2796] = 25357
        set PRIMES[2797] = 25367
        set PRIMES[2798] = 25373
        set PRIMES[2799] = 25391
        set PRIMES[2800] = 25409
        set PRIMES[2801] = 25411
        set PRIMES[2802] = 25423
        set PRIMES[2803] = 25439
        set PRIMES[2804] = 25447
        set PRIMES[2805] = 25453
        set PRIMES[2806] = 25457
        set PRIMES[2807] = 25463
        set PRIMES[2808] = 25469
        set PRIMES[2809] = 25471
        set PRIMES[2810] = 25523
        set PRIMES[2811] = 25537
        set PRIMES[2812] = 25541
        set PRIMES[2813] = 25561
        set PRIMES[2814] = 25577
        set PRIMES[2815] = 25579
        set PRIMES[2816] = 25583
        set PRIMES[2817] = 25589
        set PRIMES[2818] = 25601
        set PRIMES[2819] = 25603
        set PRIMES[2820] = 25609
        set PRIMES[2821] = 25621
        set PRIMES[2822] = 25633
        set PRIMES[2823] = 25639
        set PRIMES[2824] = 25643
        set PRIMES[2825] = 25657
        set PRIMES[2826] = 25667
        set PRIMES[2827] = 25673
        set PRIMES[2828] = 25679
        set PRIMES[2829] = 25693
        set PRIMES[2830] = 25703
        set PRIMES[2831] = 25717
        set PRIMES[2832] = 25733
        set PRIMES[2833] = 25741
        set PRIMES[2834] = 25747
        set PRIMES[2835] = 25759
        set PRIMES[2836] = 25763
        set PRIMES[2837] = 25771
        set PRIMES[2838] = 25793
        set PRIMES[2839] = 25799
        set PRIMES[2840] = 25801
        set PRIMES[2841] = 25819
        set PRIMES[2842] = 25841
        set PRIMES[2843] = 25847
        set PRIMES[2844] = 25849
        set PRIMES[2845] = 25867
        set PRIMES[2846] = 25873
        set PRIMES[2847] = 25889
        set PRIMES[2848] = 25903
        set PRIMES[2849] = 25913
        set PRIMES[2850] = 25919
        set PRIMES[2851] = 25931
        set PRIMES[2852] = 25933
        set PRIMES[2853] = 25939
        set PRIMES[2854] = 25943
        set PRIMES[2855] = 25951
        set PRIMES[2856] = 25969
        set PRIMES[2857] = 25981
        set PRIMES[2858] = 25997
        set PRIMES[2859] = 25999
        set PRIMES[2860] = 26003
        set PRIMES[2861] = 26017
        set PRIMES[2862] = 26021
        set PRIMES[2863] = 26029
        set PRIMES[2864] = 26041
        set PRIMES[2865] = 26053
        set PRIMES[2866] = 26083
        set PRIMES[2867] = 26099
        set PRIMES[2868] = 26107
        set PRIMES[2869] = 26111
        set PRIMES[2870] = 26113
        set PRIMES[2871] = 26119
        set PRIMES[2872] = 26141
        set PRIMES[2873] = 26153
        set PRIMES[2874] = 26161
        set PRIMES[2875] = 26171
        set PRIMES[2876] = 26177
        set PRIMES[2877] = 26183
        set PRIMES[2878] = 26189
        set PRIMES[2879] = 26203
        set PRIMES[2880] = 26209
        set PRIMES[2881] = 26227
        set PRIMES[2882] = 26237
        set PRIMES[2883] = 26249
        set PRIMES[2884] = 26251
        set PRIMES[2885] = 26261
        set PRIMES[2886] = 26263
        set PRIMES[2887] = 26267
        set PRIMES[2888] = 26293
        set PRIMES[2889] = 26297
        set PRIMES[2890] = 26309
        set PRIMES[2891] = 26317
        set PRIMES[2892] = 26321
        set PRIMES[2893] = 26339
        set PRIMES[2894] = 26347
        set PRIMES[2895] = 26357
        set PRIMES[2896] = 26371
        set PRIMES[2897] = 26387
        set PRIMES[2898] = 26393
        set PRIMES[2899] = 26399
        set PRIMES[2900] = 26407
        set PRIMES[2901] = 26417
        set PRIMES[2902] = 26423
        set PRIMES[2903] = 26431
        set PRIMES[2904] = 26437
        set PRIMES[2905] = 26449
        set PRIMES[2906] = 26459
        set PRIMES[2907] = 26479
        set PRIMES[2908] = 26489
        set PRIMES[2909] = 26497
        set PRIMES[2910] = 26501
        set PRIMES[2911] = 26513
        set PRIMES[2912] = 26539
        set PRIMES[2913] = 26557
        set PRIMES[2914] = 26561
        set PRIMES[2915] = 26573
        set PRIMES[2916] = 26591
        set PRIMES[2917] = 26597
        set PRIMES[2918] = 26627
        set PRIMES[2919] = 26633
        set PRIMES[2920] = 26641
        set PRIMES[2921] = 26647
        set PRIMES[2922] = 26669
        set PRIMES[2923] = 26681
        set PRIMES[2924] = 26683
        set PRIMES[2925] = 26687
        set PRIMES[2926] = 26693
        set PRIMES[2927] = 26699
        set PRIMES[2928] = 26701
        set PRIMES[2929] = 26711
        set PRIMES[2930] = 26713
        set PRIMES[2931] = 26717
        set PRIMES[2932] = 26723
        set PRIMES[2933] = 26729
        set PRIMES[2934] = 26731
        set PRIMES[2935] = 26737
        set PRIMES[2936] = 26759
        set PRIMES[2937] = 26777
        set PRIMES[2938] = 26783
        set PRIMES[2939] = 26801
        set PRIMES[2940] = 26813
        set PRIMES[2941] = 26821
        set PRIMES[2942] = 26833
        set PRIMES[2943] = 26839
        set PRIMES[2944] = 26849
        set PRIMES[2945] = 26861
        set PRIMES[2946] = 26863
        set PRIMES[2947] = 26879
        set PRIMES[2948] = 26881
        set PRIMES[2949] = 26891
        set PRIMES[2950] = 26893
        set PRIMES[2951] = 26903
        set PRIMES[2952] = 26921
        set PRIMES[2953] = 26927
        set PRIMES[2954] = 26947
        set PRIMES[2955] = 26951
        set PRIMES[2956] = 26953
        set PRIMES[2957] = 26959
        set PRIMES[2958] = 26981
        set PRIMES[2959] = 26987
        set PRIMES[2960] = 26993
        set PRIMES[2961] = 27011
        set PRIMES[2962] = 27017
        set PRIMES[2963] = 27031
        set PRIMES[2964] = 27043
        set PRIMES[2965] = 27059
        set PRIMES[2966] = 27061
        set PRIMES[2967] = 27067
        set PRIMES[2968] = 27073
        set PRIMES[2969] = 27077
        set PRIMES[2970] = 27091
        set PRIMES[2971] = 27103
        set PRIMES[2972] = 27107
        set PRIMES[2973] = 27109
        set PRIMES[2974] = 27127
        set PRIMES[2975] = 27143
        set PRIMES[2976] = 27179
        set PRIMES[2977] = 27191
        set PRIMES[2978] = 27197
        set PRIMES[2979] = 27211
        set PRIMES[2980] = 27239
        set PRIMES[2981] = 27241
        set PRIMES[2982] = 27253
        set PRIMES[2983] = 27259
        set PRIMES[2984] = 27271
        set PRIMES[2985] = 27277
        set PRIMES[2986] = 27281
        set PRIMES[2987] = 27283
        set PRIMES[2988] = 27299
        set PRIMES[2989] = 27329
        set PRIMES[2990] = 27337
        set PRIMES[2991] = 27361
        set PRIMES[2992] = 27367
        set PRIMES[2993] = 27397
        set PRIMES[2994] = 27407
        set PRIMES[2995] = 27409
        set PRIMES[2996] = 27427
        set PRIMES[2997] = 27431
        set PRIMES[2998] = 27437
        set PRIMES[2999] = 27449
        set PRIMES[3000] = 27457
        set PRIMES[3001] = 27479
        set PRIMES[3002] = 27481
        set PRIMES[3003] = 27487
        set PRIMES[3004] = 27509
        set PRIMES[3005] = 27527
        set PRIMES[3006] = 27529
        set PRIMES[3007] = 27539
        set PRIMES[3008] = 27541
        set PRIMES[3009] = 27551
        set PRIMES[3010] = 27581
        set PRIMES[3011] = 27583
        set PRIMES[3012] = 27611
        set PRIMES[3013] = 27617
        set PRIMES[3014] = 27631
        set PRIMES[3015] = 27647
        set PRIMES[3016] = 27653
        set PRIMES[3017] = 27673
        set PRIMES[3018] = 27689
        set PRIMES[3019] = 27691
        set PRIMES[3020] = 27697
        set PRIMES[3021] = 27701
        set PRIMES[3022] = 27733
        set PRIMES[3023] = 27737
        set PRIMES[3024] = 27739
        set PRIMES[3025] = 27743
        set PRIMES[3026] = 27749
        set PRIMES[3027] = 27751
        set PRIMES[3028] = 27763
        set PRIMES[3029] = 27767
        set PRIMES[3030] = 27773
        set PRIMES[3031] = 27779
        set PRIMES[3032] = 27791
        set PRIMES[3033] = 27793
        set PRIMES[3034] = 27799
        set PRIMES[3035] = 27803
        set PRIMES[3036] = 27809
        set PRIMES[3037] = 27817
        set PRIMES[3038] = 27823
        set PRIMES[3039] = 27827
        set PRIMES[3040] = 27847
        set PRIMES[3041] = 27851
        set PRIMES[3042] = 27883
        set PRIMES[3043] = 27893
        set PRIMES[3044] = 27901
        set PRIMES[3045] = 27917
        set PRIMES[3046] = 27919
        set PRIMES[3047] = 27941
        set PRIMES[3048] = 27943
        set PRIMES[3049] = 27947
        set PRIMES[3050] = 27953
        set PRIMES[3051] = 27961
        set PRIMES[3052] = 27967
        set PRIMES[3053] = 27983
        set PRIMES[3054] = 27997
        set PRIMES[3055] = 28001
        set PRIMES[3056] = 28019
        set PRIMES[3057] = 28027
        set PRIMES[3058] = 28031
        set PRIMES[3059] = 28051
        set PRIMES[3060] = 28057
        set PRIMES[3061] = 28069
        set PRIMES[3062] = 28081
        set PRIMES[3063] = 28087
        set PRIMES[3064] = 28097
        set PRIMES[3065] = 28099
        set PRIMES[3066] = 28109
        set PRIMES[3067] = 28111
        set PRIMES[3068] = 28123
        set PRIMES[3069] = 28151
        set PRIMES[3070] = 28163
        set PRIMES[3071] = 28181
        set PRIMES[3072] = 28183
        set PRIMES[3073] = 28201
        set PRIMES[3074] = 28211
        set PRIMES[3075] = 28219
        set PRIMES[3076] = 28229
        set PRIMES[3077] = 28277
        set PRIMES[3078] = 28279
        set PRIMES[3079] = 28283
        set PRIMES[3080] = 28289
        set PRIMES[3081] = 28297
        set PRIMES[3082] = 28307
        set PRIMES[3083] = 28309
        set PRIMES[3084] = 28319
        set PRIMES[3085] = 28349
        set PRIMES[3086] = 28351
        set PRIMES[3087] = 28387
        set PRIMES[3088] = 28393
        set PRIMES[3089] = 28403
        set PRIMES[3090] = 28409
        set PRIMES[3091] = 28411
        set PRIMES[3092] = 28429
        set PRIMES[3093] = 28433
        set PRIMES[3094] = 28439
        set PRIMES[3095] = 28447
        set PRIMES[3096] = 28463
        set PRIMES[3097] = 28477
        set PRIMES[3098] = 28493
        set PRIMES[3099] = 28499
        set PRIMES[3100] = 28513
        set PRIMES[3101] = 28517
        set PRIMES[3102] = 28537
        set PRIMES[3103] = 28541
        set PRIMES[3104] = 28547
        set PRIMES[3105] = 28549
        set PRIMES[3106] = 28559
        set PRIMES[3107] = 28571
        set PRIMES[3108] = 28573
        set PRIMES[3109] = 28579
        set PRIMES[3110] = 28591
        set PRIMES[3111] = 28597
        set PRIMES[3112] = 28603
        set PRIMES[3113] = 28607
        set PRIMES[3114] = 28619
        set PRIMES[3115] = 28621
        set PRIMES[3116] = 28627
        set PRIMES[3117] = 28631
        set PRIMES[3118] = 28643
        set PRIMES[3119] = 28649
        set PRIMES[3120] = 28657
        set PRIMES[3121] = 28661
        set PRIMES[3122] = 28663
        set PRIMES[3123] = 28669
        set PRIMES[3124] = 28687
        set PRIMES[3125] = 28697
        set PRIMES[3126] = 28703
        set PRIMES[3127] = 28711
        set PRIMES[3128] = 28723
        set PRIMES[3129] = 28729
        set PRIMES[3130] = 28751
        set PRIMES[3131] = 28753
        set PRIMES[3132] = 28759
        set PRIMES[3133] = 28771
        set PRIMES[3134] = 28789
        set PRIMES[3135] = 28793
        set PRIMES[3136] = 28807
        set PRIMES[3137] = 28813
        set PRIMES[3138] = 28817
        set PRIMES[3139] = 28837
        set PRIMES[3140] = 28843
        set PRIMES[3141] = 28859
        set PRIMES[3142] = 28867
        set PRIMES[3143] = 28871
        set PRIMES[3144] = 28879
        set PRIMES[3145] = 28901
        set PRIMES[3146] = 28909
        set PRIMES[3147] = 28921
        set PRIMES[3148] = 28927
        set PRIMES[3149] = 28933
        set PRIMES[3150] = 28949
        set PRIMES[3151] = 28961
        set PRIMES[3152] = 28979
        set PRIMES[3153] = 29009
        set PRIMES[3154] = 29017
        set PRIMES[3155] = 29021
        set PRIMES[3156] = 29023
        set PRIMES[3157] = 29027
        set PRIMES[3158] = 29033
        set PRIMES[3159] = 29059
        set PRIMES[3160] = 29063
        set PRIMES[3161] = 29077
        set PRIMES[3162] = 29101
        set PRIMES[3163] = 29123
        set PRIMES[3164] = 29129
        set PRIMES[3165] = 29131
        set PRIMES[3166] = 29137
        set PRIMES[3167] = 29147
        set PRIMES[3168] = 29153
        set PRIMES[3169] = 29167
        set PRIMES[3170] = 29173
        set PRIMES[3171] = 29179
        set PRIMES[3172] = 29191
        set PRIMES[3173] = 29201
        set PRIMES[3174] = 29207
        set PRIMES[3175] = 29209
        set PRIMES[3176] = 29221
        set PRIMES[3177] = 29231
        set PRIMES[3178] = 29243
        set PRIMES[3179] = 29251
        set PRIMES[3180] = 29269
        set PRIMES[3181] = 29287
        set PRIMES[3182] = 29297
        set PRIMES[3183] = 29303
        set PRIMES[3184] = 29311
        set PRIMES[3185] = 29327
        set PRIMES[3186] = 29333
        set PRIMES[3187] = 29339
        set PRIMES[3188] = 29347
        set PRIMES[3189] = 29363
        set PRIMES[3190] = 29383
        set PRIMES[3191] = 29387
        set PRIMES[3192] = 29389
        set PRIMES[3193] = 29399
        set PRIMES[3194] = 29401
        set PRIMES[3195] = 29411
        set PRIMES[3196] = 29423
        set PRIMES[3197] = 29429
        set PRIMES[3198] = 29437
        set PRIMES[3199] = 29443
        set PRIMES[3200] = 29453
        set PRIMES[3201] = 29473
        set PRIMES[3202] = 29483
        set PRIMES[3203] = 29501
        set PRIMES[3204] = 29527
        set PRIMES[3205] = 29531
        set PRIMES[3206] = 29537
        set PRIMES[3207] = 29567
        set PRIMES[3208] = 29569
        set PRIMES[3209] = 29573
        set PRIMES[3210] = 29581
        set PRIMES[3211] = 29587
        set PRIMES[3212] = 29599
        set PRIMES[3213] = 29611
        set PRIMES[3214] = 29629
        set PRIMES[3215] = 29633
        set PRIMES[3216] = 29641
        set PRIMES[3217] = 29663
        set PRIMES[3218] = 29669
        set PRIMES[3219] = 29671
        set PRIMES[3220] = 29683
        set PRIMES[3221] = 29717
        set PRIMES[3222] = 29723
        set PRIMES[3223] = 29741
        set PRIMES[3224] = 29753
        set PRIMES[3225] = 29759
        set PRIMES[3226] = 29761
        set PRIMES[3227] = 29789
        set PRIMES[3228] = 29803
        set PRIMES[3229] = 29819
        set PRIMES[3230] = 29833
        set PRIMES[3231] = 29837
        set PRIMES[3232] = 29851
        set PRIMES[3233] = 29863
        set PRIMES[3234] = 29867
        set PRIMES[3235] = 29873
        set PRIMES[3236] = 29879
        set PRIMES[3237] = 29881
        set PRIMES[3238] = 29917
        set PRIMES[3239] = 29921
        set PRIMES[3240] = 29927
        set PRIMES[3241] = 29947
        set PRIMES[3242] = 29959
        set PRIMES[3243] = 29983
        set PRIMES[3244] = 29989
        set PRIMES[3245] = 30011
        set PRIMES[3246] = 30013
        set PRIMES[3247] = 30029
        set PRIMES[3248] = 30047
        set PRIMES[3249] = 30059
        set PRIMES[3250] = 30071
        set PRIMES[3251] = 30089
        set PRIMES[3252] = 30091
        set PRIMES[3253] = 30097
        set PRIMES[3254] = 30103
        set PRIMES[3255] = 30109
        set PRIMES[3256] = 30113
        set PRIMES[3257] = 30119
        set PRIMES[3258] = 30133
        set PRIMES[3259] = 30137
        set PRIMES[3260] = 30139
        set PRIMES[3261] = 30161
        set PRIMES[3262] = 30169
        set PRIMES[3263] = 30181
        set PRIMES[3264] = 30187
        set PRIMES[3265] = 30197
        set PRIMES[3266] = 30203
        set PRIMES[3267] = 30211
        set PRIMES[3268] = 30223
        set PRIMES[3269] = 30241
        set PRIMES[3270] = 30253
        set PRIMES[3271] = 30259
        set PRIMES[3272] = 30269
        set PRIMES[3273] = 30271
        set PRIMES[3274] = 30293
        set PRIMES[3275] = 30307
        set PRIMES[3276] = 30313
        set PRIMES[3277] = 30319
        set PRIMES[3278] = 30323
        set PRIMES[3279] = 30341
        set PRIMES[3280] = 30347
        set PRIMES[3281] = 30367
        set PRIMES[3282] = 30389
        set PRIMES[3283] = 30391
        set PRIMES[3284] = 30403
        set PRIMES[3285] = 30427
        set PRIMES[3286] = 30431
        set PRIMES[3287] = 30449
        set PRIMES[3288] = 30467
        set PRIMES[3289] = 30469
        set PRIMES[3290] = 30491
        set PRIMES[3291] = 30493
        set PRIMES[3292] = 30497
        set PRIMES[3293] = 30509
        set PRIMES[3294] = 30517
        set PRIMES[3295] = 30529
        set PRIMES[3296] = 30539
        set PRIMES[3297] = 30553
        set PRIMES[3298] = 30557
        set PRIMES[3299] = 30559
        set PRIMES[3300] = 30577
        set PRIMES[3301] = 30593
        set PRIMES[3302] = 30631
        set PRIMES[3303] = 30637
        set PRIMES[3304] = 30643
        set PRIMES[3305] = 30649
        set PRIMES[3306] = 30661
        set PRIMES[3307] = 30671
        set PRIMES[3308] = 30677
        set PRIMES[3309] = 30689
        set PRIMES[3310] = 30697
        set PRIMES[3311] = 30703
        set PRIMES[3312] = 30707
        set PRIMES[3313] = 30713
        set PRIMES[3314] = 30727
        set PRIMES[3315] = 30757
        set PRIMES[3316] = 30763
        set PRIMES[3317] = 30773
        set PRIMES[3318] = 30781
        set PRIMES[3319] = 30803
        set PRIMES[3320] = 30809
        set PRIMES[3321] = 30817
        set PRIMES[3322] = 30829
        set PRIMES[3323] = 30839
        set PRIMES[3324] = 30841
        set PRIMES[3325] = 30851
        set PRIMES[3326] = 30853
        set PRIMES[3327] = 30859
        set PRIMES[3328] = 30869
        set PRIMES[3329] = 30871
        set PRIMES[3330] = 30881
        set PRIMES[3331] = 30893
        set PRIMES[3332] = 30911
        set PRIMES[3333] = 30931
        set PRIMES[3334] = 30937
        set PRIMES[3335] = 30941
        set PRIMES[3336] = 30949
        set PRIMES[3337] = 30971
        set PRIMES[3338] = 30977
        set PRIMES[3339] = 30983
        set PRIMES[3340] = 31013
        set PRIMES[3341] = 31019
        set PRIMES[3342] = 31033
        set PRIMES[3343] = 31039
        set PRIMES[3344] = 31051
        set PRIMES[3345] = 31063
        set PRIMES[3346] = 31069
        set PRIMES[3347] = 31079
        set PRIMES[3348] = 31081
        set PRIMES[3349] = 31091
        set PRIMES[3350] = 31121
        set PRIMES[3351] = 31123
        set PRIMES[3352] = 31139
        set PRIMES[3353] = 31147
        set PRIMES[3354] = 31151
        set PRIMES[3355] = 31153
        set PRIMES[3356] = 31159
        set PRIMES[3357] = 31177
        set PRIMES[3358] = 31181
        set PRIMES[3359] = 31183
        set PRIMES[3360] = 31189
        set PRIMES[3361] = 31193
        set PRIMES[3362] = 31219
        set PRIMES[3363] = 31223
        set PRIMES[3364] = 31231
        set PRIMES[3365] = 31237
        set PRIMES[3366] = 31247
        set PRIMES[3367] = 31249
        set PRIMES[3368] = 31253
        set PRIMES[3369] = 31259
        set PRIMES[3370] = 31267
        set PRIMES[3371] = 31271
        set PRIMES[3372] = 31277
        set PRIMES[3373] = 31307
        set PRIMES[3374] = 31319
        set PRIMES[3375] = 31321
        set PRIMES[3376] = 31327
        set PRIMES[3377] = 31333
        set PRIMES[3378] = 31337
        set PRIMES[3379] = 31357
        set PRIMES[3380] = 31379
        set PRIMES[3381] = 31387
        set PRIMES[3382] = 31391
        set PRIMES[3383] = 31393
        set PRIMES[3384] = 31397
        set PRIMES[3385] = 31469
        set PRIMES[3386] = 31477
        set PRIMES[3387] = 31481
        set PRIMES[3388] = 31489
        set PRIMES[3389] = 31511
        set PRIMES[3390] = 31513
        set PRIMES[3391] = 31517
        set PRIMES[3392] = 31531
        set PRIMES[3393] = 31541
        set PRIMES[3394] = 31543
        set PRIMES[3395] = 31547
        set PRIMES[3396] = 31567
        set PRIMES[3397] = 31573
        set PRIMES[3398] = 31583
        set PRIMES[3399] = 31601
        set PRIMES[3400] = 31607
        set PRIMES[3401] = 31627
        set PRIMES[3402] = 31643
        set PRIMES[3403] = 31649
        set PRIMES[3404] = 31657
        set PRIMES[3405] = 31663
        set PRIMES[3406] = 31667
        set PRIMES[3407] = 31687
        set PRIMES[3408] = 31699
        set PRIMES[3409] = 31721
        set PRIMES[3410] = 31723
        set PRIMES[3411] = 31727
        set PRIMES[3412] = 31729
        set PRIMES[3413] = 31741
        set PRIMES[3414] = 31751
        set PRIMES[3415] = 31769
        set PRIMES[3416] = 31771
        set PRIMES[3417] = 31793
        set PRIMES[3418] = 31799
        set PRIMES[3419] = 31817
        set PRIMES[3420] = 31847
        set PRIMES[3421] = 31849
        set PRIMES[3422] = 31859
        set PRIMES[3423] = 31873
        set PRIMES[3424] = 31883
        set PRIMES[3425] = 31891
        set PRIMES[3426] = 31907
        set PRIMES[3427] = 31957
        set PRIMES[3428] = 31963
        set PRIMES[3429] = 31973
        set PRIMES[3430] = 31981
        set PRIMES[3431] = 31991
        set PRIMES[3432] = 32003
        set PRIMES[3433] = 32009
        set PRIMES[3434] = 32027
        set PRIMES[3435] = 32029
        set PRIMES[3436] = 32051
        set PRIMES[3437] = 32057
        set PRIMES[3438] = 32059
        set PRIMES[3439] = 32063
        set PRIMES[3440] = 32069
        set PRIMES[3441] = 32077
        set PRIMES[3442] = 32083
        set PRIMES[3443] = 32089
        set PRIMES[3444] = 32099
        set PRIMES[3445] = 32117
        set PRIMES[3446] = 32119
        set PRIMES[3447] = 32141
        set PRIMES[3448] = 32143
        set PRIMES[3449] = 32159
        set PRIMES[3450] = 32173
        set PRIMES[3451] = 32183
        set PRIMES[3452] = 32189
        set PRIMES[3453] = 32191
        set PRIMES[3454] = 32203
        set PRIMES[3455] = 32213
        set PRIMES[3456] = 32233
        set PRIMES[3457] = 32237
        set PRIMES[3458] = 32251
        set PRIMES[3459] = 32257
        set PRIMES[3460] = 32261
        set PRIMES[3461] = 32297
        set PRIMES[3462] = 32299
        set PRIMES[3463] = 32303
        set PRIMES[3464] = 32309
        set PRIMES[3465] = 32321
        set PRIMES[3466] = 32323
        set PRIMES[3467] = 32327
        set PRIMES[3468] = 32341
        set PRIMES[3469] = 32353
        set PRIMES[3470] = 32359
        set PRIMES[3471] = 32363
        set PRIMES[3472] = 32369
        set PRIMES[3473] = 32371
        set PRIMES[3474] = 32377
        set PRIMES[3475] = 32381
        set PRIMES[3476] = 32401
        set PRIMES[3477] = 32411
        set PRIMES[3478] = 32413
        set PRIMES[3479] = 32423
        set PRIMES[3480] = 32429
        set PRIMES[3481] = 32441
        set PRIMES[3482] = 32443
        set PRIMES[3483] = 32467
        set PRIMES[3484] = 32479
        set PRIMES[3485] = 32491
        set PRIMES[3486] = 32497
        set PRIMES[3487] = 32503
        set PRIMES[3488] = 32507
        set PRIMES[3489] = 32531
        set PRIMES[3490] = 32533
        set PRIMES[3491] = 32537
        set PRIMES[3492] = 32561
        set PRIMES[3493] = 32563
        set PRIMES[3494] = 32569
        set PRIMES[3495] = 32573
        set PRIMES[3496] = 32579
        set PRIMES[3497] = 32587
        set PRIMES[3498] = 32603
        set PRIMES[3499] = 32609
        set PRIMES[3500] = 32611
        set PRIMES[3501] = 32621
        set PRIMES[3502] = 32633
        set PRIMES[3503] = 32647
        set PRIMES[3504] = 32653
        set PRIMES[3505] = 32687
        set PRIMES[3506] = 32693
        set PRIMES[3507] = 32707
        set PRIMES[3508] = 32713
        set PRIMES[3509] = 32717
        set PRIMES[3510] = 32719
        set PRIMES[3511] = 32749
        set PRIMES[3512] = 32771
        set PRIMES[3513] = 32779
        set PRIMES[3514] = 32783
        set PRIMES[3515] = 32789
        set PRIMES[3516] = 32797
        set PRIMES[3517] = 32801
        set PRIMES[3518] = 32803
        set PRIMES[3519] = 32831
        set PRIMES[3520] = 32833
        set PRIMES[3521] = 32839
        set PRIMES[3522] = 32843
        set PRIMES[3523] = 32869
        set PRIMES[3524] = 32887
        set PRIMES[3525] = 32909
        set PRIMES[3526] = 32911
        set PRIMES[3527] = 32917
        set PRIMES[3528] = 32933
        set PRIMES[3529] = 32939
        set PRIMES[3530] = 32941
        set PRIMES[3531] = 32957
        set PRIMES[3532] = 32969
        set PRIMES[3533] = 32971
        set PRIMES[3534] = 32983
        set PRIMES[3535] = 32987
        set PRIMES[3536] = 32993
        set PRIMES[3537] = 32999
        set PRIMES[3538] = 33013
        set PRIMES[3539] = 33023
        set PRIMES[3540] = 33029
        set PRIMES[3541] = 33037
        set PRIMES[3542] = 33049
        set PRIMES[3543] = 33053
        set PRIMES[3544] = 33071
        set PRIMES[3545] = 33073
        set PRIMES[3546] = 33083
        set PRIMES[3547] = 33091
        set PRIMES[3548] = 33107
        set PRIMES[3549] = 33113
        set PRIMES[3550] = 33119
        set PRIMES[3551] = 33149
        set PRIMES[3552] = 33151
        set PRIMES[3553] = 33161
        set PRIMES[3554] = 33179
        set PRIMES[3555] = 33181
        set PRIMES[3556] = 33191
        set PRIMES[3557] = 33199
        set PRIMES[3558] = 33203
        set PRIMES[3559] = 33211
        set PRIMES[3560] = 33223
        set PRIMES[3561] = 33247
        set PRIMES[3562] = 33287
        set PRIMES[3563] = 33289
        set PRIMES[3564] = 33301
        set PRIMES[3565] = 33311
        set PRIMES[3566] = 33317
        set PRIMES[3567] = 33329
        set PRIMES[3568] = 33331
        set PRIMES[3569] = 33343
        set PRIMES[3570] = 33347
        set PRIMES[3571] = 33349
        set PRIMES[3572] = 33353
        set PRIMES[3573] = 33359
        set PRIMES[3574] = 33377
        set PRIMES[3575] = 33391
        set PRIMES[3576] = 33403
        set PRIMES[3577] = 33409
        set PRIMES[3578] = 33413
        set PRIMES[3579] = 33427
        set PRIMES[3580] = 33457
        set PRIMES[3581] = 33461
        set PRIMES[3582] = 33469
        set PRIMES[3583] = 33479
        set PRIMES[3584] = 33487
        set PRIMES[3585] = 33493
        set PRIMES[3586] = 33503
        set PRIMES[3587] = 33521
        set PRIMES[3588] = 33529
        set PRIMES[3589] = 33533
        set PRIMES[3590] = 33547
        set PRIMES[3591] = 33563
        set PRIMES[3592] = 33569
        set PRIMES[3593] = 33577
        set PRIMES[3594] = 33581
        set PRIMES[3595] = 33587
        set PRIMES[3596] = 33589
        set PRIMES[3597] = 33599
        set PRIMES[3598] = 33601
        set PRIMES[3599] = 33613
        set PRIMES[3600] = 33617
        set PRIMES[3601] = 33619
        set PRIMES[3602] = 33623
        set PRIMES[3603] = 33629
        set PRIMES[3604] = 33637
        set PRIMES[3605] = 33641
        set PRIMES[3606] = 33647
        set PRIMES[3607] = 33679
        set PRIMES[3608] = 33703
        set PRIMES[3609] = 33713
        set PRIMES[3610] = 33721
        set PRIMES[3611] = 33739
        set PRIMES[3612] = 33749
        set PRIMES[3613] = 33751
        set PRIMES[3614] = 33757
        set PRIMES[3615] = 33767
        set PRIMES[3616] = 33769
        set PRIMES[3617] = 33773
        set PRIMES[3618] = 33791
        set PRIMES[3619] = 33797
        set PRIMES[3620] = 33809
        set PRIMES[3621] = 33811
        set PRIMES[3622] = 33827
        set PRIMES[3623] = 33829
        set PRIMES[3624] = 33851
        set PRIMES[3625] = 33857
        set PRIMES[3626] = 33863
        set PRIMES[3627] = 33871
        set PRIMES[3628] = 33889
        set PRIMES[3629] = 33893
        set PRIMES[3630] = 33911
        set PRIMES[3631] = 33923
        set PRIMES[3632] = 33931
        set PRIMES[3633] = 33937
        set PRIMES[3634] = 33941
        set PRIMES[3635] = 33961
        set PRIMES[3636] = 33967
        set PRIMES[3637] = 33997
        set PRIMES[3638] = 34019
        set PRIMES[3639] = 34031
        set PRIMES[3640] = 34033
        set PRIMES[3641] = 34039
        set PRIMES[3642] = 34057
        set PRIMES[3643] = 34061
        set PRIMES[3644] = 34123
        set PRIMES[3645] = 34127
        set PRIMES[3646] = 34129
        set PRIMES[3647] = 34141
        set PRIMES[3648] = 34147
        set PRIMES[3649] = 34157
        set PRIMES[3650] = 34159
        set PRIMES[3651] = 34171
        set PRIMES[3652] = 34183
        set PRIMES[3653] = 34211
        set PRIMES[3654] = 34213
        set PRIMES[3655] = 34217
        set PRIMES[3656] = 34231
        set PRIMES[3657] = 34253
        set PRIMES[3658] = 34259
        set PRIMES[3659] = 34261
        set PRIMES[3660] = 34267
        set PRIMES[3661] = 34273
        set PRIMES[3662] = 34283
        set PRIMES[3663] = 34297
        set PRIMES[3664] = 34301
        set PRIMES[3665] = 34303
        set PRIMES[3666] = 34313
        set PRIMES[3667] = 34319
        set PRIMES[3668] = 34327
        set PRIMES[3669] = 34337
        set PRIMES[3670] = 34351
        set PRIMES[3671] = 34361
        set PRIMES[3672] = 34367
        set PRIMES[3673] = 34369
        set PRIMES[3674] = 34381
        set PRIMES[3675] = 34403
        set PRIMES[3676] = 34421
        set PRIMES[3677] = 34429
        set PRIMES[3678] = 34439
        set PRIMES[3679] = 34457
        set PRIMES[3680] = 34469
        set PRIMES[3681] = 34471
        set PRIMES[3682] = 34483
        set PRIMES[3683] = 34487
        set PRIMES[3684] = 34499
        set PRIMES[3685] = 34501
        set PRIMES[3686] = 34511
        set PRIMES[3687] = 34513
        set PRIMES[3688] = 34519
        set PRIMES[3689] = 34537
        set PRIMES[3690] = 34543
        set PRIMES[3691] = 34549
        set PRIMES[3692] = 34583
        set PRIMES[3693] = 34589
        set PRIMES[3694] = 34591
        set PRIMES[3695] = 34603
        set PRIMES[3696] = 34607
        set PRIMES[3697] = 34613
        set PRIMES[3698] = 34631
        set PRIMES[3699] = 34649
        set PRIMES[3700] = 34651
        set PRIMES[3701] = 34667
        set PRIMES[3702] = 34673
        set PRIMES[3703] = 34679
        set PRIMES[3704] = 34687
        set PRIMES[3705] = 34693
        set PRIMES[3706] = 34703
        set PRIMES[3707] = 34721
        set PRIMES[3708] = 34729
        set PRIMES[3709] = 34739
        set PRIMES[3710] = 34747
        set PRIMES[3711] = 34757
        set PRIMES[3712] = 34759
        set PRIMES[3713] = 34763
        set PRIMES[3714] = 34781
        set PRIMES[3715] = 34807
        set PRIMES[3716] = 34819
        set PRIMES[3717] = 34841
        set PRIMES[3718] = 34843
        set PRIMES[3719] = 34847
        set PRIMES[3720] = 34849
        set PRIMES[3721] = 34871
        set PRIMES[3722] = 34877
        set PRIMES[3723] = 34883
        set PRIMES[3724] = 34897
        set PRIMES[3725] = 34913
        set PRIMES[3726] = 34919
        set PRIMES[3727] = 34939
        set PRIMES[3728] = 34949
        set PRIMES[3729] = 34961
        set PRIMES[3730] = 34963
        set PRIMES[3731] = 34981
        set PRIMES[3732] = 35023
        set PRIMES[3733] = 35027
        set PRIMES[3734] = 35051
        set PRIMES[3735] = 35053
        set PRIMES[3736] = 35059
        set PRIMES[3737] = 35069
        set PRIMES[3738] = 35081
        set PRIMES[3739] = 35083
        set PRIMES[3740] = 35089
        set PRIMES[3741] = 35099
        set PRIMES[3742] = 35107
        set PRIMES[3743] = 35111
        set PRIMES[3744] = 35117
        set PRIMES[3745] = 35129
        set PRIMES[3746] = 35141
        set PRIMES[3747] = 35149
        set PRIMES[3748] = 35153
        set PRIMES[3749] = 35159
        set PRIMES[3750] = 35171
        set PRIMES[3751] = 35201
        set PRIMES[3752] = 35221
        set PRIMES[3753] = 35227
        set PRIMES[3754] = 35251
        set PRIMES[3755] = 35257
        set PRIMES[3756] = 35267
        set PRIMES[3757] = 35279
        set PRIMES[3758] = 35281
        set PRIMES[3759] = 35291
        set PRIMES[3760] = 35311
        set PRIMES[3761] = 35317
        set PRIMES[3762] = 35323
        set PRIMES[3763] = 35327
        set PRIMES[3764] = 35339
        set PRIMES[3765] = 35353
        set PRIMES[3766] = 35363
        set PRIMES[3767] = 35381
        set PRIMES[3768] = 35393
        set PRIMES[3769] = 35401
        set PRIMES[3770] = 35407
        set PRIMES[3771] = 35419
        set PRIMES[3772] = 35423
        set PRIMES[3773] = 35437
        set PRIMES[3774] = 35447
        set PRIMES[3775] = 35449
        set PRIMES[3776] = 35461
        set PRIMES[3777] = 35491
        set PRIMES[3778] = 35507
        set PRIMES[3779] = 35509
        set PRIMES[3780] = 35521
        set PRIMES[3781] = 35527
        set PRIMES[3782] = 35531
        set PRIMES[3783] = 35533
        set PRIMES[3784] = 35537
        set PRIMES[3785] = 35543
        set PRIMES[3786] = 35569
        set PRIMES[3787] = 35573
        set PRIMES[3788] = 35591
        set PRIMES[3789] = 35593
        set PRIMES[3790] = 35597
        set PRIMES[3791] = 35603
        set PRIMES[3792] = 35617
        set PRIMES[3793] = 35671
        set PRIMES[3794] = 35677
        set PRIMES[3795] = 35729
        set PRIMES[3796] = 35731
        set PRIMES[3797] = 35747
        set PRIMES[3798] = 35753
        set PRIMES[3799] = 35759
        set PRIMES[3800] = 35771
        set PRIMES[3801] = 35797
        set PRIMES[3802] = 35801
        set PRIMES[3803] = 35803
        set PRIMES[3804] = 35809
        set PRIMES[3805] = 35831
        set PRIMES[3806] = 35837
        set PRIMES[3807] = 35839
        set PRIMES[3808] = 35851
        set PRIMES[3809] = 35863
        set PRIMES[3810] = 35869
        set PRIMES[3811] = 35879
        set PRIMES[3812] = 35897
        set PRIMES[3813] = 35899
        set PRIMES[3814] = 35911
        set PRIMES[3815] = 35923
        set PRIMES[3816] = 35933
        set PRIMES[3817] = 35951
        set PRIMES[3818] = 35963
        set PRIMES[3819] = 35969
        set PRIMES[3820] = 35977
        set PRIMES[3821] = 35983
        set PRIMES[3822] = 35993
        set PRIMES[3823] = 35999
        set PRIMES[3824] = 36007
        set PRIMES[3825] = 36011
        set PRIMES[3826] = 36013
        set PRIMES[3827] = 36017
        set PRIMES[3828] = 36037
        set PRIMES[3829] = 36061
        set PRIMES[3830] = 36067
        set PRIMES[3831] = 36073
        set PRIMES[3832] = 36083
        set PRIMES[3833] = 36097
        set PRIMES[3834] = 36107
        set PRIMES[3835] = 36109
        set PRIMES[3836] = 36131
        set PRIMES[3837] = 36137
        set PRIMES[3838] = 36151
        set PRIMES[3839] = 36161
        set PRIMES[3840] = 36187
        set PRIMES[3841] = 36191
        set PRIMES[3842] = 36209
        set PRIMES[3843] = 36217
        set PRIMES[3844] = 36229
        set PRIMES[3845] = 36241
        set PRIMES[3846] = 36251
        set PRIMES[3847] = 36263
        set PRIMES[3848] = 36269
        set PRIMES[3849] = 36277
        set PRIMES[3850] = 36293
        set PRIMES[3851] = 36299
        set PRIMES[3852] = 36307
        set PRIMES[3853] = 36313
        set PRIMES[3854] = 36319
        set PRIMES[3855] = 36341
        set PRIMES[3856] = 36343
        set PRIMES[3857] = 36353
        set PRIMES[3858] = 36373
        set PRIMES[3859] = 36383
        set PRIMES[3860] = 36389
        set PRIMES[3861] = 36433
        set PRIMES[3862] = 36451
        set PRIMES[3863] = 36457
        set PRIMES[3864] = 36467
        set PRIMES[3865] = 36469
        set PRIMES[3866] = 36473
        set PRIMES[3867] = 36479
        set PRIMES[3868] = 36493
        set PRIMES[3869] = 36497
        set PRIMES[3870] = 36523
        set PRIMES[3871] = 36527
        set PRIMES[3872] = 36529
        set PRIMES[3873] = 36541
        set PRIMES[3874] = 36551
        set PRIMES[3875] = 36559
        set PRIMES[3876] = 36563
        set PRIMES[3877] = 36571
        set PRIMES[3878] = 36583
        set PRIMES[3879] = 36587
        set PRIMES[3880] = 36599
        set PRIMES[3881] = 36607
        set PRIMES[3882] = 36629
        set PRIMES[3883] = 36637
        set PRIMES[3884] = 36643
        set PRIMES[3885] = 36653
        set PRIMES[3886] = 36671
        set PRIMES[3887] = 36677
        set PRIMES[3888] = 36683
        set PRIMES[3889] = 36691
        set PRIMES[3890] = 36697
        set PRIMES[3891] = 36709
        set PRIMES[3892] = 36713
        set PRIMES[3893] = 36721
        set PRIMES[3894] = 36739
        set PRIMES[3895] = 36749
        set PRIMES[3896] = 36761
        set PRIMES[3897] = 36767
        set PRIMES[3898] = 36779
        set PRIMES[3899] = 36781
        set PRIMES[3900] = 36787
        set PRIMES[3901] = 36791
        set PRIMES[3902] = 36793
        set PRIMES[3903] = 36809
        set PRIMES[3904] = 36821
        set PRIMES[3905] = 36833
        set PRIMES[3906] = 36847
        set PRIMES[3907] = 36857
        set PRIMES[3908] = 36871
        set PRIMES[3909] = 36877
        set PRIMES[3910] = 36887
        set PRIMES[3911] = 36899
        set PRIMES[3912] = 36901
        set PRIMES[3913] = 36913
        set PRIMES[3914] = 36919
        set PRIMES[3915] = 36923
        set PRIMES[3916] = 36929
        set PRIMES[3917] = 36931
        set PRIMES[3918] = 36943
        set PRIMES[3919] = 36947
        set PRIMES[3920] = 36973
        set PRIMES[3921] = 36979
        set PRIMES[3922] = 36997
        set PRIMES[3923] = 37003
        set PRIMES[3924] = 37013
        set PRIMES[3925] = 37019
        set PRIMES[3926] = 37021
        set PRIMES[3927] = 37039
        set PRIMES[3928] = 37049
        set PRIMES[3929] = 37057
        set PRIMES[3930] = 37061
        set PRIMES[3931] = 37087
        set PRIMES[3932] = 37097
        set PRIMES[3933] = 37117
        set PRIMES[3934] = 37123
        set PRIMES[3935] = 37139
        set PRIMES[3936] = 37159
        set PRIMES[3937] = 37171
        set PRIMES[3938] = 37181
        set PRIMES[3939] = 37189
        set PRIMES[3940] = 37199
        set PRIMES[3941] = 37201
        set PRIMES[3942] = 37217
        set PRIMES[3943] = 37223
        set PRIMES[3944] = 37243
        set PRIMES[3945] = 37253
        set PRIMES[3946] = 37273
        set PRIMES[3947] = 37277
        set PRIMES[3948] = 37307
        set PRIMES[3949] = 37309
        set PRIMES[3950] = 37313
        set PRIMES[3951] = 37321
        set PRIMES[3952] = 37337
        set PRIMES[3953] = 37339
        set PRIMES[3954] = 37357
        set PRIMES[3955] = 37361
        set PRIMES[3956] = 37363
        set PRIMES[3957] = 37369
        set PRIMES[3958] = 37379
        set PRIMES[3959] = 37397
        set PRIMES[3960] = 37409
        set PRIMES[3961] = 37423
        set PRIMES[3962] = 37441
        set PRIMES[3963] = 37447
        set PRIMES[3964] = 37463
        set PRIMES[3965] = 37483
        set PRIMES[3966] = 37489
        set PRIMES[3967] = 37493
        set PRIMES[3968] = 37501
        set PRIMES[3969] = 37507
        set PRIMES[3970] = 37511
        set PRIMES[3971] = 37517
        set PRIMES[3972] = 37529
        set PRIMES[3973] = 37537
        set PRIMES[3974] = 37547
        set PRIMES[3975] = 37549
        set PRIMES[3976] = 37561
        set PRIMES[3977] = 37567
        set PRIMES[3978] = 37571
        set PRIMES[3979] = 37573
        set PRIMES[3980] = 37579
        set PRIMES[3981] = 37589
        set PRIMES[3982] = 37591
        set PRIMES[3983] = 37607
        set PRIMES[3984] = 37619
        set PRIMES[3985] = 37633
        set PRIMES[3986] = 37643
        set PRIMES[3987] = 37649
        set PRIMES[3988] = 37657
        set PRIMES[3989] = 37663
        set PRIMES[3990] = 37691
        set PRIMES[3991] = 37693
        set PRIMES[3992] = 37699
        set PRIMES[3993] = 37717
        set PRIMES[3994] = 37747
        set PRIMES[3995] = 37781
        set PRIMES[3996] = 37783
        set PRIMES[3997] = 37799
        set PRIMES[3998] = 37811
        set PRIMES[3999] = 37813
        set PRIMES[4000] = 37831
        set PRIMES[4001] = 37847
        set PRIMES[4002] = 37853
        set PRIMES[4003] = 37861
        set PRIMES[4004] = 37871
        set PRIMES[4005] = 37879
        set PRIMES[4006] = 37889
        set PRIMES[4007] = 37897
        set PRIMES[4008] = 37907
        set PRIMES[4009] = 37951
        set PRIMES[4010] = 37957
        set PRIMES[4011] = 37963
        set PRIMES[4012] = 37967
        set PRIMES[4013] = 37987
        set PRIMES[4014] = 37991
        set PRIMES[4015] = 37993
        set PRIMES[4016] = 37997
        set PRIMES[4017] = 38011
        set PRIMES[4018] = 38039
        set PRIMES[4019] = 38047
        set PRIMES[4020] = 38053
        set PRIMES[4021] = 38069
        set PRIMES[4022] = 38083
        set PRIMES[4023] = 38113
        set PRIMES[4024] = 38119
        set PRIMES[4025] = 38149
        set PRIMES[4026] = 38153
        set PRIMES[4027] = 38167
        set PRIMES[4028] = 38177
        set PRIMES[4029] = 38183
        set PRIMES[4030] = 38189
        set PRIMES[4031] = 38197
        set PRIMES[4032] = 38201
        set PRIMES[4033] = 38219
        set PRIMES[4034] = 38231
        set PRIMES[4035] = 38237
        set PRIMES[4036] = 38239
        set PRIMES[4037] = 38261
        set PRIMES[4038] = 38273
        set PRIMES[4039] = 38281
        set PRIMES[4040] = 38287
        set PRIMES[4041] = 38299
        set PRIMES[4042] = 38303
        set PRIMES[4043] = 38317
        set PRIMES[4044] = 38321
        set PRIMES[4045] = 38327
        set PRIMES[4046] = 38329
        set PRIMES[4047] = 38333
        set PRIMES[4048] = 38351
        set PRIMES[4049] = 38371
        set PRIMES[4050] = 38377
        set PRIMES[4051] = 38393
        set PRIMES[4052] = 38431
        set PRIMES[4053] = 38447
        set PRIMES[4054] = 38449
        set PRIMES[4055] = 38453
        set PRIMES[4056] = 38459
        set PRIMES[4057] = 38461
        set PRIMES[4058] = 38501
        set PRIMES[4059] = 38543
        set PRIMES[4060] = 38557
        set PRIMES[4061] = 38561
        set PRIMES[4062] = 38567
        set PRIMES[4063] = 38569
        set PRIMES[4064] = 38593
        set PRIMES[4065] = 38603
        set PRIMES[4066] = 38609
        set PRIMES[4067] = 38611
        set PRIMES[4068] = 38629
        set PRIMES[4069] = 38639
        set PRIMES[4070] = 38651
        set PRIMES[4071] = 38653
        set PRIMES[4072] = 38669
        set PRIMES[4073] = 38671
        set PRIMES[4074] = 38677
        set PRIMES[4075] = 38693
        set PRIMES[4076] = 38699
        set PRIMES[4077] = 38707
        set PRIMES[4078] = 38711
        set PRIMES[4079] = 38713
        set PRIMES[4080] = 38723
        set PRIMES[4081] = 38729
        set PRIMES[4082] = 38737
        set PRIMES[4083] = 38747
        set PRIMES[4084] = 38749
        set PRIMES[4085] = 38767
        set PRIMES[4086] = 38783
        set PRIMES[4087] = 38791
        set PRIMES[4088] = 38803
        set PRIMES[4089] = 38821
        set PRIMES[4090] = 38833
        set PRIMES[4091] = 38839
        set PRIMES[4092] = 38851
        set PRIMES[4093] = 38861
        set PRIMES[4094] = 38867
        set PRIMES[4095] = 38873
        set PRIMES[4096] = 38891
        set PRIMES[4097] = 38903
        set PRIMES[4098] = 38917
        set PRIMES[4099] = 38921
        set PRIMES[4100] = 38923
        set PRIMES[4101] = 38933
        set PRIMES[4102] = 38953
        set PRIMES[4103] = 38959
        set PRIMES[4104] = 38971
        set PRIMES[4105] = 38977
        set PRIMES[4106] = 38993
        set PRIMES[4107] = 39019
        set PRIMES[4108] = 39023
        set PRIMES[4109] = 39041
        set PRIMES[4110] = 39043
        set PRIMES[4111] = 39047
        set PRIMES[4112] = 39079
        set PRIMES[4113] = 39089
        set PRIMES[4114] = 39097
        set PRIMES[4115] = 39103
        set PRIMES[4116] = 39107
        set PRIMES[4117] = 39113
        set PRIMES[4118] = 39119
        set PRIMES[4119] = 39133
        set PRIMES[4120] = 39139
        set PRIMES[4121] = 39157
        set PRIMES[4122] = 39161
        set PRIMES[4123] = 39163
        set PRIMES[4124] = 39181
        set PRIMES[4125] = 39191
        set PRIMES[4126] = 39199
        set PRIMES[4127] = 39209
        set PRIMES[4128] = 39217
        set PRIMES[4129] = 39227
        set PRIMES[4130] = 39229
        set PRIMES[4131] = 39233
        set PRIMES[4132] = 39239
        set PRIMES[4133] = 39241
        set PRIMES[4134] = 39251
        set PRIMES[4135] = 39293
        set PRIMES[4136] = 39301
        set PRIMES[4137] = 39313
        set PRIMES[4138] = 39317
        set PRIMES[4139] = 39323
        set PRIMES[4140] = 39341
        set PRIMES[4141] = 39343
        set PRIMES[4142] = 39359
        set PRIMES[4143] = 39367
        set PRIMES[4144] = 39371
        set PRIMES[4145] = 39373
        set PRIMES[4146] = 39383
        set PRIMES[4147] = 39397
        set PRIMES[4148] = 39409
        set PRIMES[4149] = 39419
        set PRIMES[4150] = 39439
        set PRIMES[4151] = 39443
        set PRIMES[4152] = 39451
        set PRIMES[4153] = 39461
        set PRIMES[4154] = 39499
        set PRIMES[4155] = 39503
        set PRIMES[4156] = 39509
        set PRIMES[4157] = 39511
        set PRIMES[4158] = 39521
        set PRIMES[4159] = 39541
        set PRIMES[4160] = 39551
        set PRIMES[4161] = 39563
        set PRIMES[4162] = 39569
        set PRIMES[4163] = 39581
        set PRIMES[4164] = 39607
        set PRIMES[4165] = 39619
        set PRIMES[4166] = 39623
        set PRIMES[4167] = 39631
        set PRIMES[4168] = 39659
        set PRIMES[4169] = 39667
        set PRIMES[4170] = 39671
        set PRIMES[4171] = 39679
        set PRIMES[4172] = 39703
        set PRIMES[4173] = 39709
        set PRIMES[4174] = 39719
        set PRIMES[4175] = 39727
        set PRIMES[4176] = 39733
        set PRIMES[4177] = 39749
        set PRIMES[4178] = 39761
        set PRIMES[4179] = 39769
        set PRIMES[4180] = 39779
        set PRIMES[4181] = 39791
        set PRIMES[4182] = 39799
        set PRIMES[4183] = 39821
        set PRIMES[4184] = 39827
        set PRIMES[4185] = 39829
        set PRIMES[4186] = 39839
        set PRIMES[4187] = 39841
        set PRIMES[4188] = 39847
        set PRIMES[4189] = 39857
        set PRIMES[4190] = 39863
        set PRIMES[4191] = 39869
        set PRIMES[4192] = 39877
        set PRIMES[4193] = 39883
        set PRIMES[4194] = 39887
        set PRIMES[4195] = 39901
        set PRIMES[4196] = 39929
        set PRIMES[4197] = 39937
        set PRIMES[4198] = 39953
        set PRIMES[4199] = 39971
        set PRIMES[4200] = 39979
        set PRIMES[4201] = 39983
        set PRIMES[4202] = 39989
        set PRIMES[4203] = 40009
        set PRIMES[4204] = 40013
        set PRIMES[4205] = 40031
        set PRIMES[4206] = 40037
        set PRIMES[4207] = 40039
        set PRIMES[4208] = 40063
        set PRIMES[4209] = 40087
        set PRIMES[4210] = 40093
        set PRIMES[4211] = 40099
        set PRIMES[4212] = 40111
        set PRIMES[4213] = 40123
        set PRIMES[4214] = 40127
        set PRIMES[4215] = 40129
        set PRIMES[4216] = 40151
        set PRIMES[4217] = 40153
        set PRIMES[4218] = 40163
        set PRIMES[4219] = 40169
        set PRIMES[4220] = 40177
        set PRIMES[4221] = 40189
        set PRIMES[4222] = 40193
        set PRIMES[4223] = 40213
        set PRIMES[4224] = 40231
        set PRIMES[4225] = 40237
        set PRIMES[4226] = 40241
        set PRIMES[4227] = 40253
        set PRIMES[4228] = 40277
        set PRIMES[4229] = 40283
        set PRIMES[4230] = 40289
        set PRIMES[4231] = 40343
        set PRIMES[4232] = 40351
        set PRIMES[4233] = 40357
        set PRIMES[4234] = 40361
        set PRIMES[4235] = 40387
        set PRIMES[4236] = 40423
        set PRIMES[4237] = 40427
        set PRIMES[4238] = 40429
        set PRIMES[4239] = 40433
        set PRIMES[4240] = 40459
        set PRIMES[4241] = 40471
        set PRIMES[4242] = 40483
        set PRIMES[4243] = 40487
        set PRIMES[4244] = 40493
        set PRIMES[4245] = 40499
        set PRIMES[4246] = 40507
        set PRIMES[4247] = 40519
        set PRIMES[4248] = 40529
        set PRIMES[4249] = 40531
        set PRIMES[4250] = 40543
        set PRIMES[4251] = 40559
        set PRIMES[4252] = 40577
        set PRIMES[4253] = 40583
        set PRIMES[4254] = 40591
        set PRIMES[4255] = 40597
        set PRIMES[4256] = 40609
        set PRIMES[4257] = 40627
        set PRIMES[4258] = 40637
        set PRIMES[4259] = 40639
        set PRIMES[4260] = 40693
        set PRIMES[4261] = 40697
        set PRIMES[4262] = 40699
        set PRIMES[4263] = 40709
        set PRIMES[4264] = 40739
        set PRIMES[4265] = 40751
        set PRIMES[4266] = 40759
        set PRIMES[4267] = 40763
        set PRIMES[4268] = 40771
        set PRIMES[4269] = 40787
        set PRIMES[4270] = 40801
        set PRIMES[4271] = 40813
        set PRIMES[4272] = 40819
        set PRIMES[4273] = 40823
        set PRIMES[4274] = 40829
        set PRIMES[4275] = 40841
        set PRIMES[4276] = 40847
        set PRIMES[4277] = 40849
        set PRIMES[4278] = 40853
        set PRIMES[4279] = 40867
        set PRIMES[4280] = 40879
        set PRIMES[4281] = 40883
        set PRIMES[4282] = 40897
        set PRIMES[4283] = 40903
        set PRIMES[4284] = 40927
        set PRIMES[4285] = 40933
        set PRIMES[4286] = 40939
        set PRIMES[4287] = 40949
        set PRIMES[4288] = 40961
        set PRIMES[4289] = 40973
        set PRIMES[4290] = 40993
        set PRIMES[4291] = 41011
        set PRIMES[4292] = 41017
        set PRIMES[4293] = 41023
        set PRIMES[4294] = 41039
        set PRIMES[4295] = 41047
        set PRIMES[4296] = 41051
        set PRIMES[4297] = 41057
        set PRIMES[4298] = 41077
        set PRIMES[4299] = 41081
        set PRIMES[4300] = 41113
        set PRIMES[4301] = 41117
        set PRIMES[4302] = 41131
        set PRIMES[4303] = 41141
        set PRIMES[4304] = 41143
        set PRIMES[4305] = 41149
        set PRIMES[4306] = 41161
        set PRIMES[4307] = 41177
        set PRIMES[4308] = 41179
        set PRIMES[4309] = 41183
        set PRIMES[4310] = 41189
        set PRIMES[4311] = 41201
        set PRIMES[4312] = 41203
        set PRIMES[4313] = 41213
        set PRIMES[4314] = 41221
        set PRIMES[4315] = 41227
        set PRIMES[4316] = 41231
        set PRIMES[4317] = 41233
        set PRIMES[4318] = 41243
        set PRIMES[4319] = 41257
        set PRIMES[4320] = 41263
        set PRIMES[4321] = 41269
        set PRIMES[4322] = 41281
        set PRIMES[4323] = 41299
        set PRIMES[4324] = 41333
        set PRIMES[4325] = 41341
        set PRIMES[4326] = 41351
        set PRIMES[4327] = 41357
        set PRIMES[4328] = 41381
        set PRIMES[4329] = 41387
        set PRIMES[4330] = 41389
        set PRIMES[4331] = 41399
        set PRIMES[4332] = 41411
        set PRIMES[4333] = 41413
        set PRIMES[4334] = 41443
        set PRIMES[4335] = 41453
        set PRIMES[4336] = 41467
        set PRIMES[4337] = 41479
        set PRIMES[4338] = 41491
        set PRIMES[4339] = 41507
        set PRIMES[4340] = 41513
        set PRIMES[4341] = 41519
        set PRIMES[4342] = 41521
        set PRIMES[4343] = 41539
        set PRIMES[4344] = 41543
        set PRIMES[4345] = 41549
        set PRIMES[4346] = 41579
        set PRIMES[4347] = 41593
        set PRIMES[4348] = 41597
        set PRIMES[4349] = 41603
        set PRIMES[4350] = 41609
        set PRIMES[4351] = 41611
        set PRIMES[4352] = 41617
        set PRIMES[4353] = 41621
        set PRIMES[4354] = 41627
        set PRIMES[4355] = 41641
        set PRIMES[4356] = 41647
        set PRIMES[4357] = 41651
        set PRIMES[4358] = 41659
        set PRIMES[4359] = 41669
        set PRIMES[4360] = 41681
        set PRIMES[4361] = 41687
        set PRIMES[4362] = 41719
        set PRIMES[4363] = 41729
        set PRIMES[4364] = 41737
        set PRIMES[4365] = 41759
        set PRIMES[4366] = 41761
        set PRIMES[4367] = 41771
        set PRIMES[4368] = 41777
        set PRIMES[4369] = 41801
        set PRIMES[4370] = 41809
        set PRIMES[4371] = 41813
        set PRIMES[4372] = 41843
        set PRIMES[4373] = 41849
        set PRIMES[4374] = 41851
        set PRIMES[4375] = 41863
        set PRIMES[4376] = 41879
        set PRIMES[4377] = 41887
        set PRIMES[4378] = 41893
        set PRIMES[4379] = 41897
        set PRIMES[4380] = 41903
        set PRIMES[4381] = 41911
        set PRIMES[4382] = 41927
        set PRIMES[4383] = 41941
        set PRIMES[4384] = 41947
        set PRIMES[4385] = 41953
        set PRIMES[4386] = 41957
        set PRIMES[4387] = 41959
        set PRIMES[4388] = 41969
        set PRIMES[4389] = 41981
        set PRIMES[4390] = 41983
        set PRIMES[4391] = 41999
        set PRIMES[4392] = 42013
        set PRIMES[4393] = 42017
        set PRIMES[4394] = 42019
        set PRIMES[4395] = 42023
        set PRIMES[4396] = 42043
        set PRIMES[4397] = 42061
        set PRIMES[4398] = 42071
        set PRIMES[4399] = 42073
        set PRIMES[4400] = 42083
        set PRIMES[4401] = 42089
        set PRIMES[4402] = 42101
        set PRIMES[4403] = 42131
        set PRIMES[4404] = 42139
        set PRIMES[4405] = 42157
        set PRIMES[4406] = 42169
        set PRIMES[4407] = 42179
        set PRIMES[4408] = 42181
        set PRIMES[4409] = 42187
        set PRIMES[4410] = 42193
        set PRIMES[4411] = 42197
        set PRIMES[4412] = 42209
        set PRIMES[4413] = 42221
        set PRIMES[4414] = 42223
        set PRIMES[4415] = 42227
        set PRIMES[4416] = 42239
        set PRIMES[4417] = 42257
        set PRIMES[4418] = 42281
        set PRIMES[4419] = 42283
        set PRIMES[4420] = 42293
        set PRIMES[4421] = 42299
        set PRIMES[4422] = 42307
        set PRIMES[4423] = 42323
        set PRIMES[4424] = 42331
        set PRIMES[4425] = 42337
        set PRIMES[4426] = 42349
        set PRIMES[4427] = 42359
        set PRIMES[4428] = 42373
        set PRIMES[4429] = 42379
        set PRIMES[4430] = 42391
        set PRIMES[4431] = 42397
        set PRIMES[4432] = 42403
        set PRIMES[4433] = 42407
        set PRIMES[4434] = 42409
        set PRIMES[4435] = 42433
        set PRIMES[4436] = 42437
        set PRIMES[4437] = 42443
        set PRIMES[4438] = 42451
        set PRIMES[4439] = 42457
        set PRIMES[4440] = 42461
        set PRIMES[4441] = 42463
        set PRIMES[4442] = 42467
        set PRIMES[4443] = 42473
        set PRIMES[4444] = 42487
        set PRIMES[4445] = 42491
        set PRIMES[4446] = 42499
        set PRIMES[4447] = 42509
        set PRIMES[4448] = 42533
        set PRIMES[4449] = 42557
        set PRIMES[4450] = 42569
        set PRIMES[4451] = 42571
        set PRIMES[4452] = 42577
        set PRIMES[4453] = 42589
        set PRIMES[4454] = 42611
        set PRIMES[4455] = 42641
        set PRIMES[4456] = 42643
        set PRIMES[4457] = 42649
        set PRIMES[4458] = 42667
        set PRIMES[4459] = 42677
        set PRIMES[4460] = 42683
        set PRIMES[4461] = 42689
        set PRIMES[4462] = 42697
        set PRIMES[4463] = 42701
        set PRIMES[4464] = 42703
        set PRIMES[4465] = 42709
        set PRIMES[4466] = 42719
        set PRIMES[4467] = 42727
        set PRIMES[4468] = 42737
        set PRIMES[4469] = 42743
        set PRIMES[4470] = 42751
        set PRIMES[4471] = 42767
        set PRIMES[4472] = 42773
        set PRIMES[4473] = 42787
        set PRIMES[4474] = 42793
        set PRIMES[4475] = 42797
        set PRIMES[4476] = 42821
        set PRIMES[4477] = 42829
        set PRIMES[4478] = 42839
        set PRIMES[4479] = 42841
        set PRIMES[4480] = 42853
        set PRIMES[4481] = 42859
        set PRIMES[4482] = 42863
        set PRIMES[4483] = 42899
        set PRIMES[4484] = 42901
        set PRIMES[4485] = 42923
        set PRIMES[4486] = 42929
        set PRIMES[4487] = 42937
        set PRIMES[4488] = 42943
        set PRIMES[4489] = 42953
        set PRIMES[4490] = 42961
        set PRIMES[4491] = 42967
        set PRIMES[4492] = 42979
        set PRIMES[4493] = 42989
        set PRIMES[4494] = 43003
        set PRIMES[4495] = 43013
        set PRIMES[4496] = 43019
        set PRIMES[4497] = 43037
        set PRIMES[4498] = 43049
        set PRIMES[4499] = 43051
        set PRIMES[4500] = 43063
        set PRIMES[4501] = 43067
        set PRIMES[4502] = 43093
        set PRIMES[4503] = 43103
        set PRIMES[4504] = 43117
        set PRIMES[4505] = 43133
        set PRIMES[4506] = 43151
        set PRIMES[4507] = 43159
        set PRIMES[4508] = 43177
        set PRIMES[4509] = 43189
        set PRIMES[4510] = 43201
        set PRIMES[4511] = 43207
        set PRIMES[4512] = 43223
        set PRIMES[4513] = 43237
        set PRIMES[4514] = 43261
        set PRIMES[4515] = 43271
        set PRIMES[4516] = 43283
        set PRIMES[4517] = 43291
        set PRIMES[4518] = 43313
        set PRIMES[4519] = 43319
        set PRIMES[4520] = 43321
        set PRIMES[4521] = 43331
        set PRIMES[4522] = 43391
        set PRIMES[4523] = 43397
        set PRIMES[4524] = 43399
        set PRIMES[4525] = 43403
        set PRIMES[4526] = 43411
        set PRIMES[4527] = 43427
        set PRIMES[4528] = 43441
        set PRIMES[4529] = 43451
        set PRIMES[4530] = 43457
        set PRIMES[4531] = 43481
        set PRIMES[4532] = 43487
        set PRIMES[4533] = 43499
        set PRIMES[4534] = 43517
        set PRIMES[4535] = 43541
        set PRIMES[4536] = 43543
        set PRIMES[4537] = 43573
        set PRIMES[4538] = 43577
        set PRIMES[4539] = 43579
        set PRIMES[4540] = 43591
        set PRIMES[4541] = 43597
        set PRIMES[4542] = 43607
        set PRIMES[4543] = 43609
        set PRIMES[4544] = 43613
        set PRIMES[4545] = 43627
        set PRIMES[4546] = 43633
        set PRIMES[4547] = 43649
        set PRIMES[4548] = 43651
        set PRIMES[4549] = 43661
        set PRIMES[4550] = 43669
        set PRIMES[4551] = 43691
        set PRIMES[4552] = 43711
        set PRIMES[4553] = 43717
        set PRIMES[4554] = 43721
        set PRIMES[4555] = 43753
        set PRIMES[4556] = 43759
        set PRIMES[4557] = 43777
        set PRIMES[4558] = 43781
        set PRIMES[4559] = 43783
        set PRIMES[4560] = 43787
        set PRIMES[4561] = 43789
        set PRIMES[4562] = 43793
        set PRIMES[4563] = 43801
        set PRIMES[4564] = 43853
        set PRIMES[4565] = 43867
        set PRIMES[4566] = 43889
        set PRIMES[4567] = 43891
        set PRIMES[4568] = 43913
        set PRIMES[4569] = 43933
        set PRIMES[4570] = 43943
        set PRIMES[4571] = 43951
        set PRIMES[4572] = 43961
        set PRIMES[4573] = 43963
        set PRIMES[4574] = 43969
        set PRIMES[4575] = 43973
        set PRIMES[4576] = 43987
        set PRIMES[4577] = 43991
        set PRIMES[4578] = 43997
        set PRIMES[4579] = 44017
        set PRIMES[4580] = 44021
        set PRIMES[4581] = 44027
        set PRIMES[4582] = 44029
        set PRIMES[4583] = 44041
        set PRIMES[4584] = 44053
        set PRIMES[4585] = 44059
        set PRIMES[4586] = 44071
        set PRIMES[4587] = 44087
        set PRIMES[4588] = 44089
        set PRIMES[4589] = 44101
        set PRIMES[4590] = 44111
        set PRIMES[4591] = 44119
        set PRIMES[4592] = 44123
        set PRIMES[4593] = 44129
        set PRIMES[4594] = 44131
        set PRIMES[4595] = 44159
        set PRIMES[4596] = 44171
        set PRIMES[4597] = 44179
        set PRIMES[4598] = 44189
        set PRIMES[4599] = 44201
        set PRIMES[4600] = 44203
        set PRIMES[4601] = 44207
        set PRIMES[4602] = 44221
        set PRIMES[4603] = 44249
        set PRIMES[4604] = 44257
        set PRIMES[4605] = 44263
        set PRIMES[4606] = 44267
        set PRIMES[4607] = 44269
        set PRIMES[4608] = 44273
        set PRIMES[4609] = 44279
        set PRIMES[4610] = 44281
        set PRIMES[4611] = 44293
        set PRIMES[4612] = 44351
        set PRIMES[4613] = 44357
        set PRIMES[4614] = 44371
        set PRIMES[4615] = 44381
        set PRIMES[4616] = 44383
        set PRIMES[4617] = 44389
        set PRIMES[4618] = 44417
        set PRIMES[4619] = 44449
        set PRIMES[4620] = 44453
        set PRIMES[4621] = 44483
        set PRIMES[4622] = 44491
        set PRIMES[4623] = 44497
        set PRIMES[4624] = 44501
        set PRIMES[4625] = 44507
        set PRIMES[4626] = 44519
        set PRIMES[4627] = 44531
        set PRIMES[4628] = 44533
        set PRIMES[4629] = 44537
        set PRIMES[4630] = 44543
        set PRIMES[4631] = 44549
        set PRIMES[4632] = 44563
        set PRIMES[4633] = 44579
        set PRIMES[4634] = 44587
        set PRIMES[4635] = 44617
        set PRIMES[4636] = 44621
        set PRIMES[4637] = 44623
        set PRIMES[4638] = 44633
        set PRIMES[4639] = 44641
        set PRIMES[4640] = 44647
        set PRIMES[4641] = 44651
        set PRIMES[4642] = 44657
        set PRIMES[4643] = 44683
        set PRIMES[4644] = 44687
        set PRIMES[4645] = 44699
        set PRIMES[4646] = 44701
        set PRIMES[4647] = 44711
        set PRIMES[4648] = 44729
        set PRIMES[4649] = 44741
        set PRIMES[4650] = 44753
        set PRIMES[4651] = 44771
        set PRIMES[4652] = 44773
        set PRIMES[4653] = 44777
        set PRIMES[4654] = 44789
        set PRIMES[4655] = 44797
        set PRIMES[4656] = 44809
        set PRIMES[4657] = 44819
        set PRIMES[4658] = 44839
        set PRIMES[4659] = 44843
        set PRIMES[4660] = 44851
        set PRIMES[4661] = 44867
        set PRIMES[4662] = 44879
        set PRIMES[4663] = 44887
        set PRIMES[4664] = 44893
        set PRIMES[4665] = 44909
        set PRIMES[4666] = 44917
        set PRIMES[4667] = 44927
        set PRIMES[4668] = 44939
        set PRIMES[4669] = 44953
        set PRIMES[4670] = 44959
        set PRIMES[4671] = 44963
        set PRIMES[4672] = 44971
        set PRIMES[4673] = 44983
        set PRIMES[4674] = 44987
        set PRIMES[4675] = 45007
        set PRIMES[4676] = 45013
        set PRIMES[4677] = 45053
        set PRIMES[4678] = 45061
        set PRIMES[4679] = 45077
        set PRIMES[4680] = 45083
        set PRIMES[4681] = 45119
        set PRIMES[4682] = 45121
        set PRIMES[4683] = 45127
        set PRIMES[4684] = 45131
        set PRIMES[4685] = 45137
        set PRIMES[4686] = 45139
        set PRIMES[4687] = 45161
        set PRIMES[4688] = 45179
        set PRIMES[4689] = 45181
        set PRIMES[4690] = 45191
        set PRIMES[4691] = 45197
        set PRIMES[4692] = 45233
        set PRIMES[4693] = 45247
        set PRIMES[4694] = 45259
        set PRIMES[4695] = 45263
        set PRIMES[4696] = 45281
        set PRIMES[4697] = 45289
        set PRIMES[4698] = 45293
        set PRIMES[4699] = 45307
        set PRIMES[4700] = 45317
        set PRIMES[4701] = 45319
        set PRIMES[4702] = 45329
        set PRIMES[4703] = 45337
        set PRIMES[4704] = 45341
        set PRIMES[4705] = 45343
        set PRIMES[4706] = 45361
        set PRIMES[4707] = 45377
        set PRIMES[4708] = 45389
        set PRIMES[4709] = 45403
        set PRIMES[4710] = 45413
        set PRIMES[4711] = 45427
        set PRIMES[4712] = 45433
        set PRIMES[4713] = 45439
        set PRIMES[4714] = 45481
        set PRIMES[4715] = 45491
        set PRIMES[4716] = 45497
        set PRIMES[4717] = 45503
        set PRIMES[4718] = 45523
        set PRIMES[4719] = 45533
        set PRIMES[4720] = 45541
        set PRIMES[4721] = 45553
        set PRIMES[4722] = 45557
        set PRIMES[4723] = 45569
        set PRIMES[4724] = 45587
        set PRIMES[4725] = 45589
        set PRIMES[4726] = 45599
        set PRIMES[4727] = 45613
        set PRIMES[4728] = 45631
        set PRIMES[4729] = 45641
        set PRIMES[4730] = 45659
        set PRIMES[4731] = 45667
        set PRIMES[4732] = 45673
        set PRIMES[4733] = 45677
        set PRIMES[4734] = 45691
        set PRIMES[4735] = 45697
        set PRIMES[4736] = 45707
        set PRIMES[4737] = 45737
        set PRIMES[4738] = 45751
        set PRIMES[4739] = 45757
        set PRIMES[4740] = 45763
        set PRIMES[4741] = 45767
        set PRIMES[4742] = 45779
        set PRIMES[4743] = 45817
        set PRIMES[4744] = 45821
        set PRIMES[4745] = 45823
        set PRIMES[4746] = 45827
        set PRIMES[4747] = 45833
        set PRIMES[4748] = 45841
        set PRIMES[4749] = 45853
        set PRIMES[4750] = 45863
        set PRIMES[4751] = 45869
        set PRIMES[4752] = 45887
        set PRIMES[4753] = 45893
        set PRIMES[4754] = 45943
        set PRIMES[4755] = 45949
        set PRIMES[4756] = 45953
        set PRIMES[4757] = 45959
        set PRIMES[4758] = 45971
        set PRIMES[4759] = 45979
        set PRIMES[4760] = 45989
        set PRIMES[4761] = 46021
        set PRIMES[4762] = 46027
        set PRIMES[4763] = 46049
        set PRIMES[4764] = 46051
        set PRIMES[4765] = 46061
        set PRIMES[4766] = 46073
        set PRIMES[4767] = 46091
        set PRIMES[4768] = 46093
        set PRIMES[4769] = 46099
        set PRIMES[4770] = 46103
        set PRIMES[4771] = 46133
        set PRIMES[4772] = 46141
        set PRIMES[4773] = 46147
        set PRIMES[4774] = 46153
        set PRIMES[4775] = 46171
        set PRIMES[4776] = 46181
        set PRIMES[4777] = 46183
        set PRIMES[4778] = 46187
        set PRIMES[4779] = 46199
        set PRIMES[4780] = 46219
        set PRIMES[4781] = 46229
        set PRIMES[4782] = 46237
        set PRIMES[4783] = 46261
        set PRIMES[4784] = 46271
        set PRIMES[4785] = 46273
        set PRIMES[4786] = 46279
        set PRIMES[4787] = 46301
        set PRIMES[4788] = 46307
        set PRIMES[4789] = 46309
        set PRIMES[4790] = 46327
        set PRIMES[4791] = 46337
    endfunction
Another approach is to store all primes until 2^31-1 in a hashtable (because there are more than 8190) and check if num is equal to that value... but who cares.

also
JASS:
        //Returns the x-root of base
        static method root takes real base, real x returns real
            return Pow(base, 1/x)
        endmethod
 
Last edited:
Level 14
Joined
Dec 12, 2012
Messages
1,007
I am sorry for not trying to understand your "isPrime", but as far as I can see, mine is much easier to understand and may be quite a bit faster.

Well, just lets benchmark it then:


JASS:
scope MyScope initializer onInit
	private function onInit takes nothing returns nothing
		local integer i = 0
		local player p = GetLocalPlayer()
		local integer prime = 90127 // Change prime number here
		
		loop
			set i = i + 1
			call Math.isPrime(prime) // Insert isPrime method here
			call DisplayTimedTextToPlayer(p, 0.0, 0.0, 60.0, I2S(i))
		endloop
	endfunction
endscope


We evaluate it on three different primes, a "very small" one (17), a "quite big" one (8093) and a "very big" one (90127). Results show the OP limit of the benchmark above:

Code:
n              Math.isPrime(n)          isPrime(n)
--------------------------------------------------
17             2173                     2117
8093           2027                     194
90127          1998                     60

At "very small" primes, the algorithms perform almost equal with Math.prime still being a bit faster. However, such small prime numbers are quite uninteresting.

Looking at larger primes it becomes quite obvious which algorithm is superior in terms of performance and scale. Math.isPrime is more than 10 times faster than your approach for "quite big" numbers like 8093 and more than 33 times faster at "very big" numbers like 90127. Also note that the performance stays very stable for a huge range of numbers, while your approach rapidly decreases in performances, already coming close to the OP limit for the biggest test number.

It might be a bit easier to understand since its the "naive" approach, but the Math library aims for maximum performance and accuracy, not as a math tutorial.

Another approach is to store all primes until 2^31-1 in a hashtable (because there are more than 8190) and check if num is equal to that value...

That would be about 105097565 primes. Given that each integer would require 32 bit, that would be more than 420 MB of RAM. However, since a hashtable always requires a key/value pair it would be at least the double, meaning 840 MB of RAM. I don't think that it would be desireable to waste almost 1 GB of RAM for doing prime calculations. And you would also have to somehow fill the hashtable, which would already cause a lot of problems (if possible at all).
 
Top