Downloading stock
returns data
#install.packages("rstan")
#install.packages("quantmod")
options(mc.cores=4)
options(stringsAsFactors = FALSE)
library("rstan")
## Loading required package: StanHeaders
##
## rstan version 2.32.7 (Stan version 2.32.2)
## For execution on a local, multicore CPU with excess RAM we recommend calling
## options(mc.cores = parallel::detectCores()).
## To avoid recompilation of unchanged Stan programs, we recommend calling
## rstan_options(auto_write = TRUE)
## For within-chain threading using `reduce_sum()` or `map_rect()` Stan functions,
## change `threads_per_chain` option:
## rstan_options(threads_per_chain = 1)
library("quantmod")
## Loading required package: xts
## Loading required package: zoo
##
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
##
## as.Date, as.Date.numeric
## Loading required package: TTR
## Registered S3 method overwritten by 'quantmod':
## method from
## as.zoo.data.frame zoo
getSymbols("AMZN", src = "yahoo", from = "2019-01-01", to = "2025-05-16")
## [1] "AMZN"
amazon = as.double(AMZN$AMZN.Adjusted)
getSymbols("PBR", src = "yahoo", from = "2019-01-01", to = "2025-05-16")
## [1] "PBR"
pbr = as.double(PBR$PBR.Adjusted)
getSymbols("^GSPC", src = "yahoo", from = "2019-01-01", to = "2025-05-16")
## [1] "GSPC"
sp500 = as.double(GSPC$GSPC.Adjusted)
getSymbols("^BVSP", src = "yahoo", from = "2019-01-01", to = "2025-05-16")
## [1] "BVSP"
ibovespa = as.double(BVSP$BVSP.Adjusted)
Closing prices
par(mfrow=c(1,1))
ts.plot(amazon/amazon[1],ylim=c(0.3,3.5))
lines(pbr/pbr[1],col=2)
lines(sp500/sp500[1],col=3)
lines(ibovespa/ibovespa[1],col=4)
abline(h=1,lty=2)
legend("topleft",legend=c("Amazon","Petrobrás","SP500","Ibovespa"),col=1:4,lwd=2,lty=1,bty="n")

Returns
par(mfrow=c(2,2))
ts.plot(diff(log(amazon)),ylim=c(-0.16,0.16),main="Amazon",ylab="Returns")
abline(h=0,col=2)
ts.plot(diff(log(pbr)),main="Petrobrás",ylab="Returns")
abline(h=-0.15,lty=2)
abline(h=0.15,lty=2)
abline(h=0,col=2)
ts.plot(diff(log(sp500)),ylim=c(-0.16,0.16),main="SP500",ylab="Returns")
abline(h=0,col=2)
ts.plot(diff(log(ibovespa)),ylim=c(-0.16,0.16),main="Ibovespa",ylab="Returns")
abline(h=0,col=2)

Petrobrás
n = length(pbr)
ret = pbr[2:n]/pbr[1:(n-1)]-1
par(mfrow=c(1,1))
acf(ret,lag=100,main="Log returns",ylim=c(-0.2,0.2))

acf(ret^2,lag=100,main="Squared log returns",ylim=c(-0.1,0.4))

Stan code
# Filename: garch.stan
data {
int<lower=0> n;
real y[n];
}
parameters {
real<lower=0> alpha0;
real<lower=0,upper=1> alpha1;
real<lower=0,upper=(1-alpha1)> beta1;
real<lower=0> sigma1;
real<lower=2> nu;
}
transformed parameters {
real<lower=0> sigma[n];
sigma[1] = sigma1;
for (t in 2:n)
sigma[t]=sqrt(alpha0+alpha1*pow(y[t-1],2)+beta1*pow(sigma[t-1],2));
}
model {
y ~ student_t(nu,0.0,sigma);
}
Running stan code for
GARCH(1,1)
y = ret
y = (y-mean(y))/sqrt(var(y))
n = length(y)
model = stan_model("garch.stan")
fit = sampling(model,data=list(n=n,y=y),iter=500,chains=4)
params = extract(fit)
qsig = t(apply(params$sigma,2,quantile,c(0.025,0.5,0.975)))
par(mfrow=c(2,4))
ts.plot(params$alpha0,ylab="",xlab="Iteration",main=expression(alpha[0]))
ts.plot(params$alpha1,ylab="",xlab="Iteration",main=expression(alpha[1]))
ts.plot(params$beta1,ylab="",xlab="Iteration",main=expression(beta[1]))
ts.plot(params$nu,ylab="",xlab="Iteration",main=expression(nu))
hist(params$alpha0,prob=TRUE,main="",xlab="")
hist(params$alpha1,prob=TRUE,main="",xlab="")
hist(params$beta1,prob=TRUE,main="",xlab="")
hist(params$nu,prob=TRUE,main="",xlab="")

Posterior of \(\alpha_1+\beta_1\)
par(mfrow=c(1,1))
hist(params$alpha1+params$beta1,prob=TRUE,xlab="",main=expression(alpha[1]+beta[1]))

Time-varying standard
deviations
par(mfrow=c(1,1))
plot(abs(y),type="h",col=grey(0.8),xlab="Days",ylab="Log returns (absolute value)")
lines(qsig[,1],col=3,lwd=3)
lines(qsig[,3],col=3,lwd=3)
lines(qsig[,2],col=2)
abline(h=1,lty=1)

Comparison
price = amazon
n = length(price)
y = price[2:n]/price[1:(n-1)]-1
y = (y-mean(y))/sqrt(var(y))
n = length(y)
model = stan_model("GARCH.stan")
fit = sampling(model,data=list(n=n,y=y),iter=500,chains=4)
## Warning: Bulk Effective Samples Size (ESS) is too low, indicating posterior means and medians may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#bulk-ess
## Warning: Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#tail-ess
par1 = extract(fit)
price = pbr
n = length(price)
y = price[2:n]/price[1:(n-1)]-1
y = (y-mean(y))/sqrt(var(y))
n = length(y)
model = stan_model("GARCH.stan")
fit = sampling(model,data=list(n=n,y=y),iter=500,chains=4)
## Warning: Bulk Effective Samples Size (ESS) is too low, indicating posterior means and medians may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#bulk-ess
## Warning: Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#tail-ess
par2 = extract(fit)
price = sp500
n = length(price)
y = price[2:n]/price[1:(n-1)]-1
y = (y-mean(y))/sqrt(var(y))
n = length(y)
model = stan_model("GARCH.stan")
fit = sampling(model,data=list(n=n,y=y),iter=500,chains=4)
## Warning: Bulk Effective Samples Size (ESS) is too low, indicating posterior means and medians may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#bulk-ess
## Warning: Tail Effective Samples Size (ESS) is too low, indicating posterior variances and tail quantiles may be unreliable.
## Running the chains for more iterations may help. See
## https://mc-stan.org/misc/warnings.html#tail-ess
par3 = extract(fit)
price = ibovespa
n = length(price)
y = price[2:n]/price[1:(n-1)]-1
y = (y-mean(y))/sqrt(var(y))
n = length(y)
model = stan_model("GARCH.stan")
fit = sampling(model,data=list(n=n,y=y),iter=500,chains=4)
par4 = extract(fit)
tab1 = apply(cbind(par1$alpha0,par1$alpha1,par1$beta1,par1$nu),2,quantile,c(0.05,0.5,0.95))
tab2 = apply(cbind(par2$alpha0,par2$alpha1,par2$beta1,par2$nu),2,quantile,c(0.05,0.5,0.95))
tab3 = apply(cbind(par3$alpha0,par3$alpha1,par3$beta1,par3$nu),2,quantile,c(0.05,0.5,0.95))
tab4 = apply(cbind(par4$alpha0,par4$alpha1,par4$beta1,par4$nu),2,quantile,c(0.05,0.5,0.95))
tab.alpha0 = cbind(tab1[,1],tab2[,1],tab3[,1],tab4[,1])
tab.alpha1 = cbind(tab1[,2],tab2[,2],tab3[,2],tab4[,2])
tab.beta1 = cbind(tab1[,3],tab2[,3],tab3[,3],tab4[,3])
tab.nu = cbind(tab1[,4],tab2[,4],tab3[,4],tab4[,4])
colnames(tab.alpha0) = c("apple","petrobras","sp500","ibovespa")
colnames(tab.alpha1) = c("apple","petrobras","sp500","ibovespa")
colnames(tab.beta1) = c("apple","petrobras","sp500","ibovespa")
colnames(tab.nu) = c("apple","petrobras","sp500","ibovespa")
\(\alpha_0\)
tab.alpha0
## apple petrobras sp500 ibovespa
## 5% 0.004352389 0.004676527 0.01095361 0.008952082
## 50% 0.013944802 0.011288371 0.01729598 0.017190574
## 95% 0.032134317 0.024786102 0.02632215 0.028877962
\(\alpha_1\)
tab.alpha1
## apple petrobras sp500 ibovespa
## 5% 0.02880990 0.01985034 0.09586442 0.04744191
## 50% 0.05193612 0.03294889 0.12379141 0.06571933
## 95% 0.09113641 0.05393075 0.15666511 0.09124835
\(\beta_1\)
tab.beta1
## apple petrobras sp500 ibovespa
## 5% 0.8237144 0.8615268 0.7610315 0.8476439
## 50% 0.8994968 0.9192599 0.8060386 0.8902761
## 95% 0.9439138 0.9520891 0.8428494 0.9194046
\(\nu\)
tab.nu
## apple petrobras sp500 ibovespa
## 5% 4.398443 3.901891 5.460582 7.732055
## 50% 5.428589 4.693051 7.010412 10.697054
## 95% 6.890187 5.645143 9.634685 16.126130
\(\alpha_1+\beta_1\)
tab.alpha1+tab.beta1
## apple petrobras sp500 ibovespa
## 5% 0.8525243 0.8813771 0.8568959 0.8950858
## 50% 0.9514329 0.9522088 0.9298300 0.9559954
## 95% 1.0350502 1.0060198 0.9995145 1.0106530
LS0tCnRpdGxlOiAiR0FSQ0goMSwxKSB3aXRoIFN0dWRlbnQncyAkdCQgZXJyb3JzIgpzdWJ0aXRsZTogIkhhbWlsdG9uaWFuIE1DIHZpYSBTVEFOIgphdXRob3I6ICJIZWRpYmVydCBGLiBMb3BlcyIKZGF0ZTogIjE3LzA2LzIwMjUiCm91dHB1dDoKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICB0b2NfZGVwdGg6IDMKICAgIHRvY19jb2xsYXBzZWQ6IHRydWUKICAgIGNvZGVfZG93bmxvYWQ6IHllcwogICAgbnVtYmVyX3NlY3Rpb25zOiB0cnVlCi0tLQoKCiMgRG93bmxvYWRpbmcgc3RvY2sgcmV0dXJucyBkYXRhCgpgYGB7cn0KI2luc3RhbGwucGFja2FnZXMoInJzdGFuIikKI2luc3RhbGwucGFja2FnZXMoInF1YW50bW9kIikKb3B0aW9ucyhtYy5jb3Jlcz00KQpvcHRpb25zKHN0cmluZ3NBc0ZhY3RvcnMgPSBGQUxTRSkKbGlicmFyeSgicnN0YW4iKQpsaWJyYXJ5KCJxdWFudG1vZCIpCgpnZXRTeW1ib2xzKCJBTVpOIiwgc3JjID0gInlhaG9vIiwgZnJvbSA9ICIyMDE5LTAxLTAxIiwgdG8gPSAiMjAyNS0wNS0xNiIpCmFtYXpvbiA9IGFzLmRvdWJsZShBTVpOJEFNWk4uQWRqdXN0ZWQpCmdldFN5bWJvbHMoIlBCUiIsIHNyYyA9ICJ5YWhvbyIsIGZyb20gPSAiMjAxOS0wMS0wMSIsIHRvID0gIjIwMjUtMDUtMTYiKQpwYnIgPSBhcy5kb3VibGUoUEJSJFBCUi5BZGp1c3RlZCkKZ2V0U3ltYm9scygiXkdTUEMiLCBzcmMgPSAieWFob28iLCBmcm9tID0gIjIwMTktMDEtMDEiLCB0byA9ICIyMDI1LTA1LTE2IikKc3A1MDAgPSBhcy5kb3VibGUoR1NQQyRHU1BDLkFkanVzdGVkKQpnZXRTeW1ib2xzKCJeQlZTUCIsIHNyYyA9ICJ5YWhvbyIsIGZyb20gPSAiMjAxOS0wMS0wMSIsIHRvID0gIjIwMjUtMDUtMTYiKQppYm92ZXNwYSA9IGFzLmRvdWJsZShCVlNQJEJWU1AuQWRqdXN0ZWQpCmBgYAoKIyMgQ2xvc2luZyBwcmljZXMKCmBgYHtyIGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9NixmaWcuYWxpZ249J2NlbnRlcicsbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcGFyKG1mcm93PWMoMSwxKSkKdHMucGxvdChhbWF6b24vYW1hem9uWzFdLHlsaW09YygwLjMsMy41KSkKbGluZXMocGJyL3BiclsxXSxjb2w9MikKbGluZXMoc3A1MDAvc3A1MDBbMV0sY29sPTMpCmxpbmVzKGlib3Zlc3BhL2lib3Zlc3BhWzFdLGNvbD00KQphYmxpbmUoaD0xLGx0eT0yKQpsZWdlbmQoInRvcGxlZnQiLGxlZ2VuZD1jKCJBbWF6b24iLCJQZXRyb2Jyw6FzIiwiU1A1MDAiLCJJYm92ZXNwYSIpLGNvbD0xOjQsbHdkPTIsbHR5PTEsYnR5PSJuIikKYGBgCgojIyBSZXR1cm5zCgpgYGB7ciBmaWcud2lkdGg9MTAsZmlnLmhlaWdodD0xMCxmaWcuYWxpZ249J2NlbnRlcicsbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KCnBhcihtZnJvdz1jKDIsMikpCnRzLnBsb3QoZGlmZihsb2coYW1hem9uKSkseWxpbT1jKC0wLjE2LDAuMTYpLG1haW49IkFtYXpvbiIseWxhYj0iUmV0dXJucyIpCmFibGluZShoPTAsY29sPTIpCnRzLnBsb3QoZGlmZihsb2cocGJyKSksbWFpbj0iUGV0cm9icsOhcyIseWxhYj0iUmV0dXJucyIpCmFibGluZShoPS0wLjE1LGx0eT0yKQphYmxpbmUoaD0wLjE1LGx0eT0yKQphYmxpbmUoaD0wLGNvbD0yKQp0cy5wbG90KGRpZmYobG9nKHNwNTAwKSkseWxpbT1jKC0wLjE2LDAuMTYpLG1haW49IlNQNTAwIix5bGFiPSJSZXR1cm5zIikKYWJsaW5lKGg9MCxjb2w9MikKdHMucGxvdChkaWZmKGxvZyhpYm92ZXNwYSkpLHlsaW09YygtMC4xNiwwLjE2KSxtYWluPSJJYm92ZXNwYSIseWxhYj0iUmV0dXJucyIpCmFibGluZShoPTAsY29sPTIpCmBgYAoKIyBQZXRyb2Jyw6FzCgpgYGB7ciBmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTYsZmlnLmFsaWduPSdjZW50ZXInLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9Cm4gICAgICAgID0gbGVuZ3RoKHBicikKcmV0ICAgICAgPSBwYnJbMjpuXS9wYnJbMToobi0xKV0tMQoKcGFyKG1mcm93PWMoMSwxKSkKYWNmKHJldCxsYWc9MTAwLG1haW49IkxvZyByZXR1cm5zIix5bGltPWMoLTAuMiwwLjIpKQphY2YocmV0XjIsbGFnPTEwMCxtYWluPSJTcXVhcmVkIGxvZyByZXR1cm5zIix5bGltPWMoLTAuMSwwLjQpKQpgYGAKCiMjIFN0YW4gY29kZQpgYGB7ciBldmFsPUZBTFNFfQojIEZpbGVuYW1lOiBnYXJjaC5zdGFuCmRhdGEgewogIGludDxsb3dlcj0wPiBuOwogIHJlYWwgeVtuXTsKfQoKcGFyYW1ldGVycyB7CiAgcmVhbDxsb3dlcj0wPiBhbHBoYTA7CiAgcmVhbDxsb3dlcj0wLHVwcGVyPTE+IGFscGhhMTsKICByZWFsPGxvd2VyPTAsdXBwZXI9KDEtYWxwaGExKT4gYmV0YTE7CiAgcmVhbDxsb3dlcj0wPiBzaWdtYTE7CiAgcmVhbDxsb3dlcj0yPiBudTsKfQoKdHJhbnNmb3JtZWQgcGFyYW1ldGVycyB7CiAgcmVhbDxsb3dlcj0wPiBzaWdtYVtuXTsKICBzaWdtYVsxXSA9IHNpZ21hMTsKICBmb3IgKHQgaW4gMjpuKQogICAgc2lnbWFbdF09c3FydChhbHBoYTArYWxwaGExKnBvdyh5W3QtMV0sMikrYmV0YTEqcG93KHNpZ21hW3QtMV0sMikpOwp9Cgptb2RlbCB7CiAgeSB+IHN0dWRlbnRfdChudSwwLjAsc2lnbWEpOwp9CmBgYAoKIyMgUnVubmluZyBzdGFuIGNvZGUgZm9yIEdBUkNIKDEsMSkKCmBgYHtyIGZpZy53aWR0aD0xMCxmaWcuaGVpZ2h0PTcsZmlnLmFsaWduPSdjZW50ZXInLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnkgICAgICA9IHJldAp5ICAgICAgPSAoeS1tZWFuKHkpKS9zcXJ0KHZhcih5KSkKbiAgICAgID0gbGVuZ3RoKHkpCm1vZGVsICA9IHN0YW5fbW9kZWwoImdhcmNoLnN0YW4iKQpmaXQgICAgPSBzYW1wbGluZyhtb2RlbCxkYXRhPWxpc3Qobj1uLHk9eSksaXRlcj01MDAsY2hhaW5zPTQpCnBhcmFtcyA9IGV4dHJhY3QoZml0KQpxc2lnICAgPSB0KGFwcGx5KHBhcmFtcyRzaWdtYSwyLHF1YW50aWxlLGMoMC4wMjUsMC41LDAuOTc1KSkpCgpwYXIobWZyb3c9YygyLDQpKQp0cy5wbG90KHBhcmFtcyRhbHBoYTAseWxhYj0iIix4bGFiPSJJdGVyYXRpb24iLG1haW49ZXhwcmVzc2lvbihhbHBoYVswXSkpCnRzLnBsb3QocGFyYW1zJGFscGhhMSx5bGFiPSIiLHhsYWI9Ikl0ZXJhdGlvbiIsbWFpbj1leHByZXNzaW9uKGFscGhhWzFdKSkKdHMucGxvdChwYXJhbXMkYmV0YTEseWxhYj0iIix4bGFiPSJJdGVyYXRpb24iLG1haW49ZXhwcmVzc2lvbihiZXRhWzFdKSkKdHMucGxvdChwYXJhbXMkbnUseWxhYj0iIix4bGFiPSJJdGVyYXRpb24iLG1haW49ZXhwcmVzc2lvbihudSkpCmhpc3QocGFyYW1zJGFscGhhMCxwcm9iPVRSVUUsbWFpbj0iIix4bGFiPSIiKQpoaXN0KHBhcmFtcyRhbHBoYTEscHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKaGlzdChwYXJhbXMkYmV0YTEscHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKaGlzdChwYXJhbXMkbnUscHJvYj1UUlVFLG1haW49IiIseGxhYj0iIikKYGBgCgojIyBQb3N0ZXJpb3Igb2YgJFxhbHBoYV8xK1xiZXRhXzEkCgpgYGB7ciBmaWcud2lkdGg9OCxmaWcuaGVpZ2h0PTYsZmlnLmFsaWduPSdjZW50ZXInLG1lc3NhZ2U9RkFMU0UsIHdhcm5pbmc9RkFMU0V9CnBhcihtZnJvdz1jKDEsMSkpCmhpc3QocGFyYW1zJGFscGhhMStwYXJhbXMkYmV0YTEscHJvYj1UUlVFLHhsYWI9IiIsbWFpbj1leHByZXNzaW9uKGFscGhhWzFdK2JldGFbMV0pKQpgYGAKCiMjIFRpbWUtdmFyeWluZyBzdGFuZGFyZCBkZXZpYXRpb25zCmBgYHtyIGZpZy53aWR0aD04LGZpZy5oZWlnaHQ9NixmaWcuYWxpZ249J2NlbnRlcicsbWVzc2FnZT1GQUxTRSwgd2FybmluZz1GQUxTRX0KcGFyKG1mcm93PWMoMSwxKSkKcGxvdChhYnMoeSksdHlwZT0iaCIsY29sPWdyZXkoMC44KSx4bGFiPSJEYXlzIix5bGFiPSJMb2cgcmV0dXJucyAoYWJzb2x1dGUgdmFsdWUpIikKbGluZXMocXNpZ1ssMV0sY29sPTMsbHdkPTMpCmxpbmVzKHFzaWdbLDNdLGNvbD0zLGx3ZD0zKQpsaW5lcyhxc2lnWywyXSxjb2w9MikKYWJsaW5lKGg9MSxsdHk9MSkKYGBgCgojIENvbXBhcmlzb24KCmBgYHtyfQpwcmljZSAgID0gYW1hem9uCm4gICAgICAgPSBsZW5ndGgocHJpY2UpCnkgICAgICAgPSBwcmljZVsyOm5dL3ByaWNlWzE6KG4tMSldLTEKeSAgICAgICA9ICh5LW1lYW4oeSkpL3NxcnQodmFyKHkpKQpuICAgICAgID0gbGVuZ3RoKHkpCm1vZGVsICAgPSBzdGFuX21vZGVsKCJHQVJDSC5zdGFuIikKZml0ICAgICA9IHNhbXBsaW5nKG1vZGVsLGRhdGE9bGlzdChuPW4seT15KSxpdGVyPTUwMCxjaGFpbnM9NCkKcGFyMSAgICA9IGV4dHJhY3QoZml0KQoKcHJpY2UgICA9IHBicgpuICAgICAgID0gbGVuZ3RoKHByaWNlKQp5ICAgICAgID0gcHJpY2VbMjpuXS9wcmljZVsxOihuLTEpXS0xCnkgICAgICAgPSAoeS1tZWFuKHkpKS9zcXJ0KHZhcih5KSkKbiAgICAgICA9IGxlbmd0aCh5KQptb2RlbCAgID0gc3Rhbl9tb2RlbCgiR0FSQ0guc3RhbiIpCmZpdCAgICAgPSBzYW1wbGluZyhtb2RlbCxkYXRhPWxpc3Qobj1uLHk9eSksaXRlcj01MDAsY2hhaW5zPTQpCnBhcjIgICAgPSBleHRyYWN0KGZpdCkKCnByaWNlICAgPSBzcDUwMApuICAgICAgID0gbGVuZ3RoKHByaWNlKQp5ICAgICAgID0gcHJpY2VbMjpuXS9wcmljZVsxOihuLTEpXS0xCnkgICAgICAgPSAoeS1tZWFuKHkpKS9zcXJ0KHZhcih5KSkKbiAgICAgICA9IGxlbmd0aCh5KQptb2RlbCAgID0gc3Rhbl9tb2RlbCgiR0FSQ0guc3RhbiIpCmZpdCAgICAgPSBzYW1wbGluZyhtb2RlbCxkYXRhPWxpc3Qobj1uLHk9eSksaXRlcj01MDAsY2hhaW5zPTQpCnBhcjMgICAgPSBleHRyYWN0KGZpdCkKCnByaWNlICAgPSBpYm92ZXNwYQpuICAgICAgID0gbGVuZ3RoKHByaWNlKQp5ICAgICAgID0gcHJpY2VbMjpuXS9wcmljZVsxOihuLTEpXS0xCnkgICAgICAgPSAoeS1tZWFuKHkpKS9zcXJ0KHZhcih5KSkKbiAgICAgICA9IGxlbmd0aCh5KQptb2RlbCAgID0gc3Rhbl9tb2RlbCgiR0FSQ0guc3RhbiIpCmZpdCAgICAgPSBzYW1wbGluZyhtb2RlbCxkYXRhPWxpc3Qobj1uLHk9eSksaXRlcj01MDAsY2hhaW5zPTQpCnBhcjQgICAgPSBleHRyYWN0KGZpdCkKCnRhYjEgPSBhcHBseShjYmluZChwYXIxJGFscGhhMCxwYXIxJGFscGhhMSxwYXIxJGJldGExLHBhcjEkbnUpLDIscXVhbnRpbGUsYygwLjA1LDAuNSwwLjk1KSkKdGFiMiA9IGFwcGx5KGNiaW5kKHBhcjIkYWxwaGEwLHBhcjIkYWxwaGExLHBhcjIkYmV0YTEscGFyMiRudSksMixxdWFudGlsZSxjKDAuMDUsMC41LDAuOTUpKQp0YWIzID0gYXBwbHkoY2JpbmQocGFyMyRhbHBoYTAscGFyMyRhbHBoYTEscGFyMyRiZXRhMSxwYXIzJG51KSwyLHF1YW50aWxlLGMoMC4wNSwwLjUsMC45NSkpCnRhYjQgPSBhcHBseShjYmluZChwYXI0JGFscGhhMCxwYXI0JGFscGhhMSxwYXI0JGJldGExLHBhcjQkbnUpLDIscXVhbnRpbGUsYygwLjA1LDAuNSwwLjk1KSkKCnRhYi5hbHBoYTAgPSBjYmluZCh0YWIxWywxXSx0YWIyWywxXSx0YWIzWywxXSx0YWI0WywxXSkKdGFiLmFscGhhMSA9IGNiaW5kKHRhYjFbLDJdLHRhYjJbLDJdLHRhYjNbLDJdLHRhYjRbLDJdKQp0YWIuYmV0YTEgID0gY2JpbmQodGFiMVssM10sdGFiMlssM10sdGFiM1ssM10sdGFiNFssM10pCnRhYi5udSAgICAgPSBjYmluZCh0YWIxWyw0XSx0YWIyWyw0XSx0YWIzWyw0XSx0YWI0Wyw0XSkKY29sbmFtZXModGFiLmFscGhhMCkgPSBjKCJhcHBsZSIsInBldHJvYnJhcyIsInNwNTAwIiwiaWJvdmVzcGEiKQpjb2xuYW1lcyh0YWIuYWxwaGExKSA9IGMoImFwcGxlIiwicGV0cm9icmFzIiwic3A1MDAiLCJpYm92ZXNwYSIpCmNvbG5hbWVzKHRhYi5iZXRhMSkgID0gYygiYXBwbGUiLCJwZXRyb2JyYXMiLCJzcDUwMCIsImlib3Zlc3BhIikKY29sbmFtZXModGFiLm51KSAgICAgPSBjKCJhcHBsZSIsInBldHJvYnJhcyIsInNwNTAwIiwiaWJvdmVzcGEiKQpgYGAKCiMjICRcYWxwaGFfMCQKCmBgYHtyfQp0YWIuYWxwaGEwCmBgYAoKIyMgJFxhbHBoYV8xJAoKYGBge3J9CnRhYi5hbHBoYTEKYGBgCgojIyAkXGJldGFfMSQKCmBgYHtyfQp0YWIuYmV0YTEKYGBgCgojIyAkXG51JAoKYGBge3J9CnRhYi5udQpgYGAKCiMjICRcYWxwaGFfMStcYmV0YV8xJAoKYGBge3J9CnRhYi5hbHBoYTErdGFiLmJldGExCmBgYAo=