local math=math;local a={}local b={}local c;local d=1;local e=0;local f=0;while d>f do f=d;d=d<<1;e=e+1 end;c=e-1//2-1;local g=1<<c-1;local h=g;local i=1<<c+1-1;d=nil;e=nil;f=nil;local j={["0"]=0,["1"]=1,["2"]=2,["3"]=3,["4"]=4,["5"]=5,["6"]=6,["7"]=7,["8"]=8,["9"]=9,["A"]=10,["B"]=11,["C"]=12,["D"]=13,["E"]=14,["F"]=15}local k={"0","1","2","3","4","5","6","7","8","9","A","B","C","D","E","F"}local function l(m,n)local function o(m,p)while#m._digits<p do m._digits[#m._digits+1]=0 end end;if type(n)=="number"then o(m,n)return end;if#m._digits>=#n._digits then o(n,#m._digits)else o(m,#n._digits)end end;local function q(m)if#m._digits==0 then m._pos=true;m._digits={0}return end;for r=#m._digits,2,-1 do if m._digits[r]~=0 then break end;table.remove(m._digits,r)end;if#m._digits==1 and m._digits[1]==0 then m._pos=true end end;local function s(m)m._digits={0}m._pos=true end;local function t(m)if a.isbn(m)then m=m:copy()else m=a:new(m)end;return m end;local function u(m,n)m=t(m)n=t(n)return m,n end;local function v(m,n)if m._pos==n._pos then return true end;return false end;local function w(m,n)m=t(m)if n==0 then return m end;for r=1,n do table.insert(m._digits,1,0)end;q(m)return m end;local function x(m,n)m=t(m)if n==0 then return m elseif n>=#m._digits then return a:new()end;for r=1,n do table.remove(m._digits,1)end;q(m)return m end;local function y(m,n)local z=a:new()local A=0;m,n=u(m,n)l(m,n)for r=1,#m._digits do z._digits[r]=m._digits[r]+n._digits[r]+A;A=z._digits[r]>>c;z._digits[r]=z._digits[r]&g end;if A~=0 then z._digits[#z._digits+1]=A end;q(z)return z end;local function B(m,n)local z=a()local A=0;m,n=u(m,n)l(m,n)for r=1,#m._digits do z._digits[r]=m._digits[r]-n._digits[r]-A&i;A=z._digits[r]>>c;z._digits[r]=z._digits[r]&g end;q(z)return z end;local function C(m,n,D)local z;m,n=u(m,n)l(m,n)z=a:new()l(z,m)for r=1,#m._digits do z._digits[r]=D(m._digits[r],n._digits[r])end;q(z)return z end;local function E(m,n)local F;local G;local H;local I;local J;m,n=u(m,n)if m==a.ZERO then return a:new(),a:new()elseif n==a.ZERO then return nil,"divide by 0"elseif n==a:new(1)then return m,a:new()end;I=v(m,n)J=m._pos;m._pos=true;n._pos=true;F=m:len_bits()-1;H=a:new()G=a:new()while F>=0 do H=H<<1;if m&(a:new(1)<<F)>0 then H=H|1 end;if H>=n then H=H-n;G=G|(a:new(1)<<F)end;F=F-1 end;G._pos=I;if H~=0 then H._pos=J end;q(G)q(H)return G,H end;local function K(L,M)local A;local z;local n;local N=10;M=tostring(M)M=M:gsub("%.%d*","")M=M:gsub("U?L?L?$","")if M==""then return true end;if M:sub(1,1)=="-"then L._pos=false;M=M:sub(2)end;M=M:upper()if M:sub(1,2)=="0X"then N=16;M=M:sub(3)end;for r=1,#M do z=M:sub(r,r)n=j[z]if n==nil then s(L)return false end;A=0;for r=1,#L._digits do L._digits[r]=L._digits[r]*N+A;A=L._digits[r]>>c;L._digits[r]=L._digits[r]&g end;if A~=0 then L._digits[#L._digits+1]=A end;L._digits[1]=L._digits[1]+n;A=L._digits[1]>>c;L._digits[1]=L._digits[1]&g;for r=2,#L._digits do if A==0 then break end;L._digits[r]=L._digits[r]+A;A=L._digits[r]>>c;L._digits[r]=L._digits[r]&g end;if A~=0 then L._digits[#L._digits+1]=A end end;q(L)return true end;local function O(L,M)M=math.floor(M)if M>=-h and M<=h then if M<0 then M=-M;L._pos=false end;L._digits[1]=M;return true end;K(L,M)return true end;local function P(m,n)n._pos=m._pos;n._digits={}for r=1,#m._digits do n._digits[r]=m._digits[r]end end;local function Q(m,N)local n;local R={}local S={}local T;local A;local U;if#m._digits==1 and m._digits[1]==0 then return"0"end;if N~=10 and N~=16 then return nil,"base not supported"end;U=m._pos;m=m:copy()while#m._digits>1 or m._digits[1]~=0 do n=a:new()l(n,m)T=0;for r=#m._digits,1,-1 do T=T<<c|m._digits[r]if T>=N then A=T//N;T=T-A*N else A=0 end;n._digits[r]=A end;R[#R+1]=k[T+1]m=n;q(m)end;if not U then R[#R+1]="-"end;for r=#R,1,-1 do S[#S+1]=R[r]end;return table.concat(S)end;b.__index=a;b.__add=function(m,n)local z;local V;local W;m,n=u(m,n)V=m._pos;W=n._pos;m._pos=true;n._pos=true;if V==W then z=y(m,n)z._pos=V elseif m<n then z=B(n,m)z._pos=W else z=B(m,n)z._pos=V end;return z end;b.__sub=function(m,n)local z;local V;local W;m,n=u(m,n)V=m._pos;W=n._pos;m._pos=true;n._pos=true;if V~=W then z=y(m,n)z._pos=V elseif m>=n then z=B(m,n)z._pos=V else z=B(n,m)z._pos=not V end;return z end;b.__mul=function(m,n)local z;local H;local A;m,n=u(m,n)z=a:new()z._pos=v(m,n)l(z,#m._digits+#n._digits+1)for r=1,#m._digits do A=0;for e=1,#n._digits do H=z._digits[r+e-1]+m._digits[r]*n._digits[e]+A;A=H>>c;z._digits[r+e-1]=H&g end;z._digits[r+#n._digits]=A end;q(z)return z end;b.__div=function(m,n)return m//n end;b.__mod=function(m,n)local z;local X;m,n=u(m,n)X,z=E(m,n)if z~=a.ZERO and z._pos~=n._pos then z=n+z end;return z end;b.__pow=function(m,n)local z;local Y;m,n=u(m,n)if n<a.ZERO then return a:new()end;z=a:new(1)Y=a:new(1)while n>0 do if n&1==Y then z=z*m end;n=n>>1;m=m*m end;return z end;b.__unm=function(m)m=t(m)m._pos=not m._pos;return m end;b.__idiv=function(m,n)local z;local X;m,n=u(m,n)z,X=E(m,n)return z end;b.__band=function(m,n)local function D(m,n)return m&n end;return C(m,n,D)end;b.__bor=function(m,n)local function D(m,n)return m|n end;return C(m,n,D)end;b.__bxor=function(m,n)local function D(m,n)return m~n end;return C(m,n,D)end;b.__bnot=function(m)m=t(m)return-(m+1)end;b.__shl=function(m,n)local z;local A;local R;local Z;local _;local a0;m,n=u(m,n)if not n._pos then return nil,"Cannot shift by negative"end;R=n;n=n:asnumber()if a:new(n)~=R then return nil,"Overflow"end;z=n//c;m=w(m,z)z=n%c;if z==0 then return m end;_=1<<z-1;a0=c-z;A=0;for r=1,#m._digits do Z=m._digits[r]>>a0&_;m._digits[r]=m._digits[r]<<z|A&g;A=Z end;if A~=0 then m._digits[#m._digits+1]=A end;q(m)return m end;b.__shr=function(m,n)local z;local A;local R;local Z;local _;local a0;m,n=u(m,n)if not n._pos then return nil,"Cannot shift by negative"end;R=n;n=n:asnumber()if a:new(n)~=R then return nil,"Overflow"end;z=n//c;m=x(m,z)z=n%c;if z==0 then return m end;_=1<<z-1;a0=c-z;A=0;for r=#m._digits,1,-1 do Z=m._digits[r]&_;m._digits[r]=m._digits[r]>>z|(A<<a0)A=Z end;q(m)return m end;b.__concat=function(m,n)if a.isbn(m)then m=tostring(m)end;if a.isbn(n)then n=tostring(n)end;return m..n end;b.__len=function(m)local n;n=#m._digits*c;n=n+8-n%8;return n//8 end;b.__eq=function(m,n)m,n=u(m,n)if m._pos~=n._pos or#m._digits~=#n._digits then return false end;for r=#m._digits,1,-1 do if m._digits[r]~=n._digits[r]then return false end end;return true end;b.__lt=function(m,n)local d;m,n=u(m,n)if not m._pos and n._pos then return true elseif m._pos and not n._pos then return false end;if#m._digits<#n._digits then if m._pos then return true else return false end elseif#m._digits>#n._digits then if m._pos then return false else return true end end;if not m._pos then d=m;m=n;n=d end;for r=#m._digits,1,-1 do if m._digits[r]<n._digits[r]then return true elseif m._digits[r]>n._digits[r]then return false end end;return false end;b.__le=function(m,n)m,n=u(m,n)if m<n or m==n then return true end;return false end;b.__tostring=function(m)return Q(m,10)end;function a:new(M)local a1;if self~=a then return nil,"first argument must be self"end;if M~=nil and a.isbn(M)then return M:copy()end;a1=setmetatable({},b)a1._pos=true;a1._digits={0}if M~=nil then a1:set(M)end;return a1 end;setmetatable(a,{__call=a.new})function a:copy()local M;M=a:new()P(self,M)return M end;function a:abs()local m;m=t(self)m._pos=true;return m end;function a:remain(n)local m;local z;local X;m,n=u(self,n)X,z=E(m,n)return z end;function a:len_bits()local n;local z=0;if self==a.ZERO then return 1 end;n=#self._digits*c;while z<=c-1 and self._digits[#self._digits]&(1<<c-z)==0 do z=z+1;n=n-1 end;return n+1 end;function a:len_bytes()local a2;a2=self:len_bits()if a2<=8 then return 1 end;if a2%8~=0 then a2=a2+8-a2%8 end;return a2//8 end;function a:len_digits(N)local a3;if not N then N=10 end;a3=#Q(self,N)if not self._pos then a3=a3-1 end;return a3 end;function a:set(M)s(self)if M==nil then return true end;if a.isbn(M)then P(M,self)return true end;if type(M)=="number"then return O(self,M)end;return K(self,M)end;function a:ashex(a4)local L;L=Q(self,16)if a.isbn(a4)then a4=a4:asnumber()elseif type(a4)=="string"then a4=tonumber(a4)end;if not self._pos then L=L:sub(2)end;if a4==nil or#L>=a4 then return(self._pos and""or"-")..L end;return(self._pos and""or"-")..string.rep("0",a4-#L)..L end;function a:asnumber()local G=1;local d=0;while G>0 do d=d+1;G=1<<d end;d=d-1;d=math.min(#self._digits,d+c-1//c-1)G=self._digits[d]for r=d-1,1,-1 do G=G<<c|self._digits[r]end;if not self._pos then G=G*-1 end;if a:new(G)~=self then return nil,"Overflow"end;return G end;function a:asbytearray()local R={}for r=self:len_bytes()-1,0,-1 do R[#R+1]=(self>>r*8&0xFF):asnumber()end;return R end;function a:asbytestring()local n;n=self:asbytearray()for r=1,#n do n[r]=string.char(n[r])end;return table.concat(n)end;a.ZERO=a:new()function a.isbn(R)if type(R)=="table"and getmetatable(R)==b then return true end;return false end;return a