Τετάρτη 1 Απριλίου 2026

TURTLE GRAPHICS

A program to run Turtle Graphics program. The Render engine can draw the program with various rotations and positions and sizes in screen. Video was from the Greek version.


This program was written with Greek commands here:

https://georgekarras.blogspot.com/2025/03/36-13.html


You can use this for the parameters too (instead of the use of if valid()...):

MODULE TURTLE_GRAPHICS (USE_STEPS=FALSE, CLEAN=TRUE, DELAY=100, NORTH=90, ZOOM=1, XPOS=0,  YPOS=0) {
FLUSH
CONST PI AS SINGLE=3.1415926
//....continue............//
}




MODULE TURTLE_GRAPHICS {
FLUSH
IF NOT VALID(USE_STEPS) THEN USE_STEPS=FALSE
IF NOT VALID(CLEAN) THEN CLEAN=TRUE
IF NOT VALID(DELAY) THEN DELAY=100
IF NOT VALID(NORTH) THEN NORTH=90
IF NOT VALID(ZOOM) THEN ZOOM=1
IF NOT VALID(XPOS) THEN XPOS=0
IF NOT VALID(YPOS) THEN YPOS=0
CONST PI AS SINGLE=3.1415926
BOOLEAN pen_draw=TRUE
SINGLE pen_angle=(NORTH-90)*PI/180
INTEGER line_width=1
ENUM PEN.COLOR {
BLACK=#000000
RED=#FF0000
GREEN=#00FF00
BLUE=#0000FF
}
FUNCTION PIC(CO){
DRAWING 3000, 3000 {
MOVE 0,0
WIDTH 4{
DRAW TO 3000, 1500, CO
DRAW TO 0, 3000, CO
DRAW TO 1000, 1500, CO
DRAW TO 0,0, CO
}
} AS ARROW
=ARROW
}
SMOOTH ON
ARROW=PIC(0)
IF CLEAN THEN CLS,0
HOLD
IF MODULE(DRAWTHIS) THEN CALL LOCAL DRAWTHIS
RELEASE
REFRESH 25
PEN 0
END

SUB DRAW.LETTER(G$, WHERE, CO=0&, SIZE=100, rotation=0)
SET_BACK()
WHERE-=NORTH+rotation
STEP ANGLE -WHERE/180*PI, 300*SIZE/100*ZOOM
PEN CO {LEGEND G$,FONTNAME$,MODE*SIZE/100*ZOOM, (NORTH-90+rotation)*PI/180, 2}
STEP ANGLE -WHERE/180*PI, -300*SIZE/100*ZOOM
PUT_ARROW()
END SUB
SUB PEN.BLACK()
PEN #000000
ARROW=PIC(PEN)
END SUB
SUB PEN.RED()
PEN #FF0000
ARROW=PIC(PEN)
END SUB
SUB PEN.GREEN()
PEN #00FF00
ARROW=PIC(PEN)
END SUB
SUB PEN.BLUE()
PEN #0000FF
ARROW=PIC(PEN)
END SUB
SUB CENTER.SCREEN()
SET_BACK()
MOVE (SCALE.X DIV 2)+XPOS, (SCALE.Y DIV 2)+YPOS
PUT_ARROW()
END SUB
SUB MOVE.ARROW(Χ, Υ)
SET_BACK()
MOVE Χ+XPOS, Υ+YPOS
PUT_ARROW()
END SUB
SUB LINE.WIDTH(that AS INTEGER)
IF that<1 THEN that=1
IF that>15 ΤΌΤΕ that=15
line_width=that
END SUB
SUB PEN.UP()
pen_draw=FALSE
END SUB
SUB PEN.DOWN()
pen_draw=TRUE
END SUB
SUB DRAW.CIRCLE(radius)
SET_BACK()
IF pen_draw THEN
WIDTH line_width {
CIRCLE radius
}
END IF
PUT_ARROW()
END SUB
SUB DRAW.ARC(radius, st=0, en=360, rotation=0)
SET_BACK()`
IF pen_draw THEN
WIDTH line_width {
CIRCLE radius,1,PEN,(NORTH-st+rotation)/180*PI, (NORTH-en+rotation)/180*PI;
}
END IF
PUT_ARROW()
END SUB
SUB GO.FORWARD(distance)
distance*=ZOOM
SET_BACK()
IF pen_draw THEN
WIDTH line_width {
IF USE_STEPS THEN
LOCAL STP=ABS(distance) DIV 300
IF STP>0 THEN
LOCAL STP1=300*SGN(distance)
STEP ANGLE pen_angle, distance
LOCAL i AS INTEGER, XP=POS.X, YP=POS.Y
STEP ANGLE pen_angle, -distance
FOR i=1 TO STP
DRAW ANGLE pen_angle, STP1
PUT_ARROW()
SET_BACK()
NEXT i
DRAW TO XP, YP
ELSE
DRAW ANGLE pen_angle, distance
END IF
ELSE
DRAW ANGLE pen_angle, distance
END IF
}
ELSE
IF USE_STEPS THEN
LOCAL STP=ABS(distance) DIV 300
IF STP>0 THEN
LOCAL STP1=300*SGN(distance)
STEP ANGLE pen_angle, distance
LOCAL i AS INTEGER, XP=POS.X, YP=POS.Y
STEP ANGLE pen_angle, -distance
FOR i=1 TO STP
STEP ANGLE pen_angle, STP1
PUT_ARROW()
SET_BACK()
NEXT i
MOVE XP, YP
ELSE
STEP ANGLE pen_angle, distance
END IF
ELSE
STEP ANGLE pen_angle, distance
END IF
END IF
PUT_ARROW()
END SUB

SUB DRAW.REAR(distance)
GO.FORWARD(-distance)
END SUB

SUB TURN.RIGHT(angle_in_degrees)
SET_BACK()
pen_angle-=angle_in_degrees/180*PI
PUT_ARROW()
END SUB

SUB TURN.TO(angle_in_degrees)
SET_BACK()
pen_angle=(angle_in_degrees+NORTH-90)/180*PI
PUT_ARROW()
END SUB

SUB SET_BACK()
RELEASE
END SUB

SUB PUT_ARROW()
HOLD
IMAGE ARROW, 600,,pen_angle*180/PI
REFRESH 1000
WAIT DELAY
END SUB
}
MODULE PRG1 {
CENTER.SCREEN()
LINE.WIDTH(4)
PEN.RED()
ZZ=13
TURN.RIGHT(ZZ)
DRAW.LETTER("Α", 225,,,-ZZ)
GO.FORWARD(4000)
DRAW.LETTER("90°     ", -20, BLUE,200, -ZZ)
PEN.BLACK()
DRAW.ARC(300, -5, 275, -ZZ)
PEN.RED()
DRAW.LETTER("Β", 135,,,-ZZ)
TURN.RIGHT(270)
GO.FORWARD(3000)
DRAW.LETTER("Γ",45,,,-ZZ)
TURN.RIGHT(270-ATN(3000/4000))
GO.FORWARD(5000)
TURN.TO(180)
PEN.UP()
GO.FORWARD(6000)
PEN.DOWN()
PEN.GREEN()
HOUSE(5000)
SUB HOUSE(n)
LOCAL i
FOR i=1 TO 3
TURN.RIGHT(120)
GO.FORWARD(n)
NEXT
TURN.RIGHT(90)
PARALLELOGRAM(n, n)
TURN.RIGHT(90)
END SUB
SUB PARALLELOGRAM(w, h)
LOCAL i
FOR i=1 TO 2
TURN.RIGHT(90)
GO.FORWARD(h)
TURN.RIGHT(90)
GO.FORWARD(w)
NEXT
END SUB
}
BACKGROUND {CLS 15, 0}
CLS 15,0
PEN 0
A$=KEY$
TURTLE_GRAPHICS %USE_STEPS=TRUE, %DELAY=30, %XPOS=-SCALE.X / 2.8, %NORTH=190, %ZOOM=0.9; DRAWTHIS AS PRG1
TURTLE_GRAPHICS %USE_STEPS=TRUE, %DELAY=30, %CLEAN=FALSE, %XPOS=SCALE.X / 2.8, %NORTH=10, %ZOOM=0.9; DRAWTHIS AS PRG1
TURTLE_GRAPHICS %USE_STEPS=TRUE, %DELAY=30, %CLEAN=FALSE, %YPOS=-SCALE.Y / 3.8, %NORTH=100, %ZOOM=0.7; DRAWTHIS AS PRG1
TURTLE_GRAPHICS %USE_STEPS=TRUE, %DELAY=30, %CLEAN=FALSE, %YPOS=SCALE.Y / 3.8, %NORTH=280, %ZOOM=0.7; DRAWTHIS AS PRG1
CURSOR 0,0
PRINT "TURTLE GRAPHICS 1.0"
A$=KEY$


Δευτέρα 30 Μαρτίου 2026

Finite State Machine

 A finite State Machine as example. 

https://rosettacode.org/wiki/Finite_state_machine#M2000_Interpreter

A Finite state machine (FSM) is computational abstraction which maps a finite number of states to other states within the same set, via transitions. An FSM can only be in one state at any given moment. Transitions can either be explicit or implicit; explicit transitions are triggered by an input signal and implicit transitions by the internal state of the system (that is, the current state). Implicit transitions thus represent "automatic" or sequenced states that are generally processed between explicit transitions (although they can also be used to provide an optional path when no valid transition exists for a given input signal).

This program use:

  1. Class definition
  2. Event for the logging, so our object, the Model isn't coupled with some specific output.
  3. Use Call Local to call a function as module and as part of "current" module - so we can see any variable of the "current" module. The "current" module is the one which we declare WithEvents the object  (type of Group in M2000). Also note the New clause first in parameter list. This direct the variables to be local. Normally all variables are local in a function, and have no conflict with same names from other functions, but when we call local we get the same environment as the one of the caller so maybe same names exist, and that will be bad for parameter list, but not but for other purposes. See the F variable is local to module FSM but can accessed from Logging(). A Call statement always pass the current stack of values to the callee.
  4. Event function is called like Call Local. The stack of values are different from the one on module FSM. Events called using fresh stack always.
  5. We use a sub for displaying a menu of choices. Calling a sub is like the Call Local but: No need for New in the parameter list (inserted automatic at runtime). We can call it using Gosub name() or name().  We can't call it from Events, but we can call it from modules which we define from current module, but that code run like exist in the caller module, so any name which not defined in sub and used on expressions or for calling must exist, or be visible in calling module. 
  6. We use a label and a Gosub to that label to run the DATA statements, to fill the stack of values, before we use it.
  7. For output text we use Wide clause for output in UTF16LE (without it we use ANSI 8bit). For using UTF8 we have to use a Document object (or we use ANSI and we send String$(theline as Utf8Enc). This send the write data without BOM, the three bytes which mark the UTF8.

Module FSM {
flush
Function Logging(New t as string, NewLine as boolean=true, terminal as boolean=true) {
' this called only using Call Local (like it is part of the calling module)
If terminal Then If NewLine then Print t else Print t;
If F>0 then
if NewLine then Print #F, t else Print #F, t;
end if
}
CLASS FSM {
Events "log"
Private:
String ResetState, CurState
StateList=List
TransitionList=List
Public:
Module AddState (State as string) {
State=filter$(State, ";")
If not Exist(.StateList, State) then Append .StateList, State
}
Module AddTransition (State as string, Transition as string, StateTo as string) {
State=filter$(State, ";")
StateTo=filter$(StateTo, ";")
Transition=filter$(Transition, ";")
If State="" or StateTo="" then Error "Need State from -> State to"
If not Exist(.StateList, State) Then Error "State (from) ";State;" not defined"
If not Exist(.StateList, StateTo) Then Error "State (to) ";StateTo;" not defined"
If not Exist(.TransitionList, State+";"+Transition) then
Append .TransitionList, State+";"+Transition:=StateTo
else
Error "Transtition can't changed"
End if
}
Module SetResetState (State as string){
State=filter$(State, ";")
If not Exist(.StateList, State) then Error "State not defined yet"
.ResetState<=State
}
Module Reset {
Call Event "Log", "Machine Up"
.CurState<=.ResetState
}
Module ShowState {
Call Event "Log" "State: "+.CurState
}
Module Action (Transition as string) {
Transition=filter$(Transition, ";")
If Exist(.TransitionList, .CurState+";"+Transition) then
do
.CurState<=Eval$(.TransitionList)
.ShowState
when Exist(.TransitionList, .CurState+";")
End if
}
}

Group WithEvents Model=FSM()
Function Model_Log (new that) {
Call Local Logging(that)
}
Long i, F
Open "Output.txt" for wide output as #F
Call Local Logging("FINITE STATE MASCHINE")
Gosub GetData
do
read thisstate
if thisstate="" then exit
Model.AddState thisstate
always
Choice=list
N=1
do
read st1, tr1, st2
Print st1, tr1, st2
if st1="" then exit
Model.AddTransition st1, tr1, st2
If tr1<>"" Then if not exist(Choice, tr1) then Append Choice, N:=tr1:N++
always
Model.SetResetState ' value is on stack of values already
Model.Reset
Model.ShowState
Options()
do
Call Local Logging("Choose :", false)
Input "", I
Call Local Logging(""+I, ,false)
If I<0 or I>Len(Choice) then continue
if I=0 then Options() else Model.Action Choice(I)
Until I=2
Close #f
Win "Notepad", dir$+"Output.txt"
End
Sub Options()
local one =each(Choice)
while one
Call Local Logging("  "+eval$(one!)+"."+eval$(one))
end while
End Sub
GetData:
Flush
Data "ready", "waiting", "exit","dispense","refunding", ""
Data "ready" , "deposit","waiting"
Data "ready", "quit", "exit"
Data "waiting","select","dispense"
Data "waiting","refund","refunding"
Data "dispense", "remove", "ready"
Data "refunding","","ready"
data "","",""
data "ready"
Return
}
FSM


Output.txt

FINITE STATE MASCHINE
Machine Up
State: ready
  1.deposit
  2.quit
  3.select
  4.refund
  5.remove
Choose :1
State: waiting
Choose :3
State: dispense
Choose :5
State: ready
Choose :1
State: waiting
Choose :4
State: refunding
State: ready
Choose :2
State: exit

Τετάρτη 25 Μαρτίου 2026

Use of COM Object's Interfaces

This included in INFO file (comes with Setup) 




GLOBAL ENUM HRESULT {
S_OK = 0& ' long type
S_FALSE = 1&
E_NOTIMPL = &H80004001& ' long type hexadecimal signed
E_NOINTERFACE = &H80004002&
E_POINTER = &H80004003&
E_ABORT = &H80004004&
E_FAIL = &H80004005&
E_ACCESSDENIED = &H80070005&
E_HANDLE = &H80070006&
E_OUTOFMEMORY = &H8007000E&
E_INVALIDARG = &H80070057&
E_UNEXPECTED = &H8000FFFF&

DISP_E_MEMBERNOTFOUND = &H80020003&
DISP_E_UNKNOWNNAME = &H80020006&
DISP_E_NONAMEDARGS = &H80020007&
DISP_E_EXCEPTION = &H80020009&
DISP_E_BADINDEX = &H8002000B&
}
class ALFA {
private:
STRUCTURE RIID {
p AS LONG
i AS INTEGER * 2
b AS BYTE * 8
}
STRUCTURE TYPEATTR {
RIID ; ' FLAT
// USING ; tLCID offset is 16, else is 0,
// so without ";" we make union, which is wrong for this
tLCID AS LONG
dwReserved AS LONG
memidConstructor AS LONG
memidDestructor AS LONG
pstrSchema AS LONG
cbSizeInstance AS LONG
typekind AS LONG
cFuncs AS INTEGER
CVars AS INTEGER
cImplTypes AS INTEGER
cbSizeVft AS INTEGER
cbAlignment AS INTEGER
wTypeFlags AS INTEGER
wMajorVerNum AS INTEGER
wMinorVerNum AS INTEGER
tdescAlias AS LONG
idldescType AS LONG
}
public:
DECLARE LCID Lib "kernel32.GetSystemDefaultLCID" { } AS LONG
INTERFACE IUnknown, "{00000000-0000-0000-C000-000000000046}" {
QueryInterface : {LONG riid, LONG myptr}
AddRef
Release
}
INTERFACE Idispatch, "{00020400-0000-0000-C000-000000000046}" {
IUnknown
GetTypeInfoCount
GetTypeInfo : {LONG iTInfo, LONG lcid, LONG ITypeInfo }
GetIDsOfNames
Invoke
}
INTERFACE ITypeInfo, "{00020401-0000-0000-C000-000000000046}" {
IUnknown
GetTypeAttr : {LONG &ppTypeAttr} ' change from example inter. We use by reference
GetTypeComp
GetFuncDesc
GetVarDesc
GetNames : {LONG memid, LONG PTRrgBstrNames, LONG cMaxNames, LONG &pcNames}
GetRefTypeOfImplType
GetImplTypeFlags
GetIDsOfNames
Invoke
GetDocumentation
GetDllEntry
GetRefTypeInfo
AddressOfMember
CreateInstance
GetMops
GetContainingTypeLib
ReleaseTypeAttr : {LONG pTypeAttr} ' void
ReleaseFuncDesc
ReleaseVarDesc
}
FUNCTION new.Attr {
VAR ret as .TYPEATTR
=ret
}
FUNCTION getClassId(iid as riid) {
VAR i, last$=hex$(iid|b[0],1)+hex$(iid|b[1],1)+"-"
for i=2 to 7:last$+=hex$(iid|b[i],1):next
="{"+hex$(iid|p)+"-"+hex$(iid|i[0],2)+"-"+hex$(iid|i[1],2)+"-"+last$+"}"
}
PROPERTY NEW.RIID {
VALUE {
CLEAR ' CLEAR VALUE  (M2000 EXPECT VALUE AS RETURN VALUE))
LINK PARENT RIID TO RIID
VAR VALUE AS RIID
}
}
FUNCTION IDLfromString(st$) {
//VAR riid as RIID   .. same as:
riid=.New.RIID
st$=filter$(st$,"{}")
VAR i, p$=leftpart$(st$, "-"): st$=rightpart$(st$,"-")
riid|p=val("0x"+p$)
p$=leftpart$(st$, "-"): st$=rightpart$(st$,"-")
riid|i[0]=val("0x"+p$)
p$=leftpart$(st$, "-"): st$=rightpart$(st$,"-")
riid|i[1]=val("0x"+p$)
p$=left$(st$,2): st$=mid$(st$,3)
riid|b[0]=val("0x"+p$)
p$=left$(st$,2): st$=mid$(st$,4)
riid|b[1]=val("0x"+p$)
for i=2 to 7
p$=left$(st$,2): st$=mid$(st$,3)
riid|b[i]=val("0x"+p$)
next
=riid
}
}
Z->ALFA()
copyAttr=Z=>new.Attr()
LONG LCID_DEF=Z=>LCID()
DECLARE k "Scripting.Dictionary"
OBJECT Ptr
riid=z=>IDLfromString("{00020400-0000-0000-C000-000000000046}")
IF Z=>IUnknown.QueryInterface(k, riid(0), varptr(ptr))=S_OK then
PRINT type$(ptr)
PRINT "ptr is k  = "; ptr is k
DIM ret(10) as object
PRINT z=>Idispatch.GetTypeInfo(ptr, 0&, LCID_DEF, varptr(ret(0)))
PRINT type$(ret(0))
LONG ppTypeAttr
// we don't pass varptr(ppTypeAttr)
// we change the signature to pass by reference
// but the actual signature of this function is a pointer to long.
// so passing by refernece, M2000 pass the Varptr of  ppTypeAttr
// we can't pass now Varptr(ppTypeAttr) because expect the by reference data
// &ppTypeAttr is actually a string, which have the full name of the variable.
ret11= z=>iTypeInfo.GetTypeAttr(ret(0), &ppTypeAttr)
HEX ret11
IF ret11=S_OK THEN
PRINT "ok", ppTypeAttr
METHOD copyAttr, "FillDataFromMem", ppTypeAttr
PRINT "ok"
PRINT "cFuncs = "+ copyAttr|cFuncs
PRINT "typekind =" + copyAttr|typekind
FOR z {
'  copyAttr|riid[] return buffer of type RIID
PRINT .getClassId(copyAttr|riid[])
'  copyAttr|riid return string as copy of copyAttr|riid
' the getClassId expect a riid type of buffer
' so now make a buffer placing the bytes.
' this is a type of casting (sending bytes in a string)
PRINT .getClassId(copyAttr|riid)
call void .iTypeInfo.ReleaseTypeAttr(ret(0), ppTypeAttr)
}
PRINT "released ok"
ELSE
try {
VAR ret1 AS HRESULT
ret1=ret11
PRINT "fault, result: ";EVAL$(ret1)
}
END IF
END IF
' last, we can get the address of an external function
' but not for that functions of interfaces
' actual these functions hold only the offset, and the RIID, so before we make a call,
' M2000 ask for the specific  RIID and then get the vtable, adding the known offset and make the call
' so without providing the actual object of the specific type, we didn't know the address of the function.
PRINT z=>lcid ' the addres of the function. We can use it from machine code.
try ok {
PRINT z=>IUnknown.QueryInterface
}
IF NOT ok OR ERROR THEN PRINT ERROR$


Κυριακή 22 Μαρτίου 2026

Compute e - 4000 digits

 You can insert a line : Locale 1033 so the decimal point character change to dot ".". The decimal point character return using the Locale$(14). You can see all the values of locale using a loop from 0 to 255 and printing to console using a Print i, ": "+locale$(i) to get all the strings specific to locale value. Locale 1032 is for Greek language, so we get comma "," for decimal point character.



Module FindE {
Function comp_e (n, decimals ){
unit=n:n/=decimals:For i=decimals-1 to 1:n=Unit+n/i:Next i:=n
}
p=4000
k=comp_e(biginteger("1"+string$("0", p)), p)
string t1=str$(k), t=left$(t1, 39)
if len(t1)>39 then
for i=40 to len(t1) step 40
t+={
}+mid$(t1, i, 40)
next
end if
all=(comp_e(1@, 28))+" Decimal"+{
}+(comp_e(1, 19))+" Double"+{
}+(comp_e(1~, 11))+" Float"+{
}+(comp_e(1#, 8))+" Currency"+{
}+ left$(t,1)+locale$(14)+mid$(t,2) +" Arbitrary-precision :"+p
Clipboard all
Report all
}
FindE


2,7182818284590452353602874712 Decimal
2,71828182845905 Double
2,718282 Float
2,7181 Currency
2,71828182845904523536028747135266249775
7247093699959574966967627724076630353547
5945713821785251664274274663919320030599
2181741359662904357290033429526059563073
8132328627943490763233829880753195251019
0115738341879307021540891499348841675092
4476146066808226480016847741185374234544
2437107539077744992069551702761838606261
3313845830007520449338265602976067371132
0070932870912744374704723069697720931014
1692836819025515108657463772111252389784
4250569536967707854499699679468644549059
8793163688923009879312773617821542499922
9576351482208269895193668033182528869398
4964651058209392398294887933203625094431
1730123819706841614039701983767932068328
2376464804295311802328782509819455815301
7567173613320698112509961818815930416903
5159888851934580727386673858942287922849
9892086805825749279610484198444363463244
9684875602336248270419786232090021609902
3530436994184914631409343173814364054625
3152096183690888707016768396424378140592
7145635490613031072085103837505101157477
0417189861068739696552126715468895703503
5402123407849819334321068170121005627880
2351930332247450158539047304199577770935
0366041699732972508868769664035557071622
6844716256079882651787134195124665201030
5921236677194325278675398558944896970964
0975459185695638023637016211204774272283
6489613422516445078182442352948636372141
7402388934412479635743702637552944483379
9801612549227850925778256209262264832627
7933386566481627725164019105900491644998
2893150566047258027786318641551956532442
5869829469593080191529872117255634754639
6447910145904090586298496791287406870504
8958586717479854667757573205681288459205
4133405392200011378630094556068816674001
6984205580403363795376452030402432256613
5278369511778838638744396625322498506549
9588623428189970773327617178392803494650
1434558897071942586398772754710962953741
5211151368350627526023264847287039207643
1005958411661205452970302364725492966693
8115137322753645098889031360205724817658
5118063036442812314965507047510254465011
7272115551948668508003685322818315219600
3735625279449515828418829478761085263981
3955990067376482922443752871846245780361
9298197139914756448826260390338144182326
2515097482798777996437308997038886778227
1383605772978824125611907176639465070633
0452795466185509666618566470971134447401
6070462621568071748187784437143698821855
9670959102596862002353718588748569652200
0503117343920732113908032936344797273559
5527734907178379342163701205005451326383
5440001863239914907054797780566978533580
4896690629511943247309958765523681285904
1383241160722602998330535370876138939639
1779574540161372236187893652605381558415
8718692553860616477983402543512843961294
6035291332594279490433729908573158029095
8631382683291477116396337092400316894586
3606064584592512699465572483918656420975
2685082307544254599376917041977780085362
7309417101634349076964237222943523661255
7250881477922315197477806056967253801718
0776360346245927877846585065605078084421
1529697521890874019660906651803516501792
5046195013665854366327125496399085491442
0001457476081930221206602433009641270489
4390397177195180699086998606636583232278
7093765022601492910115171776359446020232
4930028040186772391028809786660565118326
0043688508817157238669842242201024950551
8816948032210025154264946398128736776589
2768816359831247788652014117411091360116
4995076629077943646005851941998560162647
9076153210387275571269925182756879893027
6176114616254935649590379804583818232336
8612016243736569846703785853305275833337
9399075216606923805336988795651372855938
8349989470741618155012539706464817194670
8348197214488898790676503795903669672494
9925452790337296361626589760394985767413
9735944102374432970935547798262961459144
2936451428617158587339746791897571211956
1873857836447584484235555810500256114923
9151889309946342841393608038309166281881
1503715284967059741625628236092168075150
1777253874025642534708790891372917228286
1151591568372524163077225440633787593105
9826760944203261924285317018781772960235
4130606721360460003896610936470951414171
8577701418060644363681546444005331608778
3143174440811949422975599314011888683314
8328027065538330046932901157441475631399
97 Arbitrary-precision :4000