1 Dataset

The data is a 1976 Panel Study of Income Dynamics, based on data for the previous year, 1975. Of the 753 observations, the first 428 are for women with positive hours worked in 1975, while the remaining 325 observations are for women who did not work for pay in 1975. A more complete discussion of the data is found in Mroz [1987], Appendix 1. Thomas A. Mroz (1987) The Sensitivity of an Empirical Model of Married Women’s Hours of Work to Economic and Statistical Assumptions. Econometrica, Vol. 55, No. 4 (July 1987), pp. 765-799. Stable URL: http://www.jstor.org/stable/1911029. The variables in the dataset are as follows:

2 Importing the data

data = read.table("http://hedibert.org/wp-content/uploads/2020/01/mroz-data.txt",header=TRUE)

attach(data)

names = c("LFP","WHRS","KL6","K618","WA","WE","WW","RPWG","HHRS",
          "HA","HE","HW","MTR","WMED","WFED","UN","CIT","AX")

n = nrow(data)
y = scale(log(FAMINC))
X = cbind(LFP,WHRS,KL6,K618,WA,WE,WW,RPWG,HHRS,HA,HE,HW,MTR,WMED,WFED,UN,CIT,AX)
X = scale(X)
p = ncol(X)

3 Maximum likelihood estimation (MLE)

ols = lm(y~X-1)
summary(ols)
## 
## Call:
## lm(formula = y ~ X - 1)
## 
## Residuals:
##     Min      1Q  Median      3Q     Max 
## -2.5881 -0.1919  0.0090  0.1870  3.0093 
## 
## Coefficients:
##        Estimate Std. Error t value Pr(>|t|)    
## XLFP  -0.088521   0.029839  -2.967  0.00311 ** 
## XWHRS  0.132256   0.028473   4.645 4.03e-06 ***
## XKL6   0.019941   0.019610   1.017  0.30954    
## XK618  0.114282   0.018957   6.029 2.62e-09 ***
## XWA    0.055325   0.038119   1.451  0.14711    
## XWE   -0.005337   0.023802  -0.224  0.82265    
## XWW    0.062273   0.025077   2.483  0.01324 *  
## XRPWG  0.036699   0.025360   1.447  0.14829    
## XHHRS  0.059383   0.021027   2.824  0.00487 ** 
## XHA    0.041883   0.036653   1.143  0.25354    
## XHE    0.038257   0.022749   1.682  0.09306 .  
## XHW    0.147563   0.031960   4.617 4.59e-06 ***
## XMTR  -0.711872   0.032891 -21.643  < 2e-16 ***
## XWMED  0.021024   0.021150   0.994  0.32054    
## XWFED -0.001782   0.021202  -0.084  0.93305    
## XUN   -0.016026   0.017090  -0.938  0.34870    
## XCIT   0.042237   0.017969   2.351  0.01901 *  
## XAX   -0.044889   0.020399  -2.201  0.02808 *  
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.4511 on 735 degrees of freedom
## Multiple R-squared:  0.8011, Adjusted R-squared:  0.7962 
## F-statistic: 164.5 on 18 and 735 DF,  p-value: < 2.2e-16
beta.mle = solve(t(X)%*%X)%*%t(X)%*%y
sig2.mle = mean((y-X%*%beta.mle)^2)
se.mle = sqrt(sig2.mle*diag(solve(t(X)%*%X)))
cbind(beta.mle,se.mle)
##                       se.mle
## LFP  -0.088520910 0.02947983
## WHRS  0.132256030 0.02813058
## KL6   0.019940904 0.01937402
## K618  0.114282051 0.01872898
## WA    0.055324537 0.03766104
## WE   -0.005336829 0.02351607
## WW    0.062273173 0.02477561
## RPWG  0.036699380 0.02505534
## HHRS  0.059382777 0.02077455
## HA    0.041883154 0.03621236
## HE    0.038256653 0.02247579
## HW    0.147562664 0.03157596
## MTR  -0.711872485 0.03249591
## WMED  0.021023693 0.02089564
## WFED -0.001781634 0.02094717
## UN   -0.016025661 0.01688478
## CIT   0.042236942 0.01775312
## AX   -0.044889326 0.02015369
L = beta.mle +qnorm(0.025)*se.mle
U = beta.mle +qnorm(0.975)*se.mle

plot(beta.mle,ylim=range(L,U),xlab="Covariate",ylab="Coefficient",pch=16)
abline(h=0,lty=2)
for (i in 1:p)
  segments(i,L[i],i,U[i])

4 Prior hyperparameters

b0       = rep(0,p)
B0       = diag(1,p)
nu0      = 1
sig20    = 0.2

nu0sig20 = nu0*sig20
iB0      = solve(B0)
iB0b0    = iB0%*%b0

draw = sqrt(1/rgamma(100000,nu0/2,nu0*sig20/2))
quantile(draw,seq(0.1,0.9,by=0.1))
##       10%       20%       30%       40%       50%       60%       70%       80% 
## 0.2716682 0.3485264 0.4309841 0.5330863 0.6656844 0.8586874 1.1702234 1.7785396 
##       90% 
## 3.6269915

5 Posterior sufficient statistics

B1    = solve(iB0+t(X)%*%X)
tcB1  = t(chol(B1))
b1    = B1%*%(iB0b0+t(X)%*%y)
nu1   = nu0 + (n-p)
sig21 = (nu0sig20 + t(y-X%*%b1)%*%y + t(b0-b1)%*%iB0b0)/nu1
se.bayes = sqrt(diag(sig21[1,1]*B1))

L1 = b1+qt(0.025,df=nu1)*se.bayes
U1 = b1+qt(0.975,df=nu1)*se.bayes

par(mfrow=c(1,2))
plot(b1,ylim=range(L,U,L1,U1),xlab="Covariate",ylab="Coefficient",pch=16)
abline(h=0,lty=2)
for (i in 1:p){
  segments(i,L1[i],i,U1[i])
  segments(i+0.2,L[i],i+0.2,U[i],col=2)
  points(i+0.2,beta.mle[i],pch=16,col=2)
}
legend("bottomleft",legend=c("MLE","BAYES"),col=2:1,lwd=2)

sigma2 = seq(0.15,0.25,length=1000)
plot(sigma2,dgamma(1/sigma2,nu1/2,nu1*sig21/2)/(sigma2^2),xlab=expression(sigma^2),ylab="Density",type="l")
lines(sigma2,dgamma(1/sigma2,nu0/2,nu0*sig20/2)/(sigma2^2),lty=2)
abline(v=sig2.mle,col=2,lwd=2)
legend("topleft",legend=c("Prior","Posterior","MLE"),col=c(1,1,2),lty=c(1,2,1),lwd=2)

6 Predictive - full model (M0)

m   = X%*%b0
V   = sig20*(diag(1,n)+X%*%B0%*%t(X))
res = t(chol(V))%*%(y-m)
predictive0 = sum(dt(res,df=nu0,log=TRUE))
predictive0
## [1] -2253.028

7 Predictive - reduced model (M1)

X1 = X[,c(1,2,4,7,9,12,13,17,18)]
p1 = ncol(X1)
m   = X1%*%b0[1:p1]
V   = sig20*(diag(1,n)+X1%*%B0[1:p1,1:p1]%*%t(X1))
res = t(chol(V))%*%(y-m)
predictive1 = sum(dt(res,df=nu0,log=TRUE))
predictive1
## [1] -2107.195

8 Predictive - another reduced model (M2)

X2 = X[,c(1,2,4,12,13)]
p2 = ncol(X2)
m   = X2%*%b0[1:p2]
V   = sig20*(diag(1,n)+X2%*%B0[1:p2,1:p2]%*%t(X2))
res = t(chol(V))%*%(y-m)
predictive2 = sum(dt(res,df=nu0,log=TRUE))
predictive2
## [1] -2015.077

9 Computing log Bayes factors

logB10 = predictive1-predictive0
logB20 = predictive2-predictive0
logB21 = predictive2-predictive1

c(predictive0,predictive1,predictive2)
## [1] -2253.028 -2107.195 -2015.077
c(logB10,logB20,logB21)
## [1] 145.83288 237.95107  92.11819
exp(c(logB10,logB20,logB21))
## [1]  2.159812e+63 2.191989e+103  1.014898e+40

10 Final model

X2       = X[,c(1,2,4,12,13)]
names1   = names[c(1,2,4,12,13)]
p        = 5
b0       = rep(0,p)
B0       = diag(1,p)
nu0      = 1
sig20    = 0.2
nu0sig20 = nu0*sig20
iB0      = solve(B0)
iB0b0    = iB0%*%b0

B1    = solve(iB0+t(X2)%*%X2)
tcB1  = t(chol(B1))
b1    = B1%*%(iB0b0+t(X2)%*%y)
nu1   = nu0 + (n-p)
sig21 = (nu0sig20 + t(y-X2%*%b1)%*%y + t(b0-b1)%*%iB0b0)/nu1
se.bayes = sqrt(diag(sig21[1,1]*B1))

L1 = b1+qt(0.025,df=nu1)*se.bayes
U1 = b1+qt(0.975,df=nu1)*se.bayes

par(mfrow=c(1,1))
plot(b1,ylim=range(L1,U1),xlab="Covariate",ylab="Coefficient",pch=16,axes=FALSE)
axis(2);box()
axis(1,at=1:p,lab=names1)
abline(h=0,lty=2)
for (i in 1:p)
  segments(i,L1[i],i,U1[i])
title("Final Bayesian linear model")

Regressors:

11 Residual analysis

fitted   = X2%*%b1
residual = (y-fitted)/sqrt(sig21[1,1])
par(mfrow=c(1,2))
plot(residual,xlab="Observation",ylab="Standardized residuals")
abline(h=2,lty=2)
abline(h=0,lty=2)
abline(h=-2,lty=2)
title(paste("Residuals outside [-2,2] = ",round(100*mean(abs(residual)>2),1),"%",sep=""))

plot(y,fitted,xlim=range(y,fitted),ylim=range(y,fitted),xlab="Observed response",ylab="Fitted response")
abline(0,1,col=2,lwd=2)

LS0tCnRpdGxlOiAiR2F1c3NpYW4gbXVsdGlwbGUgbGluZWFyIHJlZ3Jlc3Npb24iCnN1YnRpdGxlOiAiUHJpb3IgcHJlZGljdGl2ZSBmb3IgbW9kZWwgY29tcGFyaXNvbiIKYXV0aG9yOiAiSGVkaWJlcnQgRnJlaXRhcyBMb3BlcyIKZGF0ZTogIjUvMzAvMjAyMyIKb3V0cHV0OgogIGh0bWxfZG9jdW1lbnQ6CiAgICB0b2M6IHRydWUKICAgIHRvY19kZXB0aDogMgogICAgY29kZV9kb3dubG9hZDogeWVzCiAgICBudW1iZXJfc2VjdGlvbnM6IHRydWUKLS0tCgpgYGB7ciBzZXR1cCwgaW5jbHVkZT1GQUxTRX0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQpgYGAKCiMgRGF0YXNldApUaGUgZGF0YSBpcyBhIDE5NzYgUGFuZWwgU3R1ZHkgb2YgSW5jb21lIER5bmFtaWNzLCBiYXNlZCBvbiBkYXRhIGZvciB0aGUgcHJldmlvdXMgeWVhciwgMTk3NS4gIE9mIHRoZSA3NTMgb2JzZXJ2YXRpb25zLCB0aGUgZmlyc3QgNDI4IGFyZSBmb3Igd29tZW4gd2l0aCBwb3NpdGl2ZSBob3VycyB3b3JrZWQgaW4gMTk3NSwgd2hpbGUgdGhlIHJlbWFpbmluZyAzMjUgb2JzZXJ2YXRpb25zIGFyZSBmb3Igd29tZW4gd2hvIGRpZCBub3Qgd29yayBmb3IgcGF5IGluIDE5NzUuICBBIG1vcmUgY29tcGxldGUgZGlzY3Vzc2lvbiBvZiB0aGUgZGF0YSBpcyBmb3VuZCBpbiBNcm96IFsxOTg3XSwgQXBwZW5kaXggMS4gICBUaG9tYXMgQS4gTXJveiAoMTk4NykgVGhlIFNlbnNpdGl2aXR5IG9mIGFuIEVtcGlyaWNhbCBNb2RlbCBvZiBNYXJyaWVkIFdvbWVuJ3MgSG91cnMgb2YgV29yayB0byBFY29ub21pYyBhbmQgU3RhdGlzdGljYWwgQXNzdW1wdGlvbnMuICBFY29ub21ldHJpY2EsIFZvbC4gNTUsIE5vLiA0IChKdWx5IDE5ODcpLCBwcC4gNzY1LTc5OS4gIFN0YWJsZSBVUkw6IGh0dHA6Ly93d3cuanN0b3Iub3JnL3N0YWJsZS8xOTExMDI5LiAgVGhlIHZhcmlhYmxlcyBpbiB0aGUgZGF0YXNldCBhcmUgYXMgZm9sbG93czoKCgoqIExGUCAgIkEgZHVtbXkgdmFyaWFibGUgPSAxIGlmIHdvbWFuIHdvcmtlZCBpbiAxOTc1LCBlbHNlIDAiOwoKKiBXSFJTICJXaWZlJ3MgaG91cnMgb2Ygd29yayBpbiAxOTc1IjsKCiogS0w2ICAiTnVtYmVyIG9mIGNoaWxkcmVuIGxlc3MgdGhhbiA2IHllYXJzIG9sZCBpbiBob3VzZWhvbGQiOwoKKiBLNjE4ICJOdW1iZXIgb2YgY2hpbGRyZW4gYmV0d2VlbiBhZ2VzIDYgYW5kIDE4IGluIGhvdXNlaG9sZCI7CgoqIFdBICAgIldpZmUncyBhZ2UiOwoKKiBXRSAgICJXaWZlJ3MgZWR1Y2F0aW9uYWwgYXR0YWlubWVudCwgaW4geWVhcnMiOwoKKiBXVyAgICJXaWZlJ3MgYXZlcmFnZSBob3VybHkgZWFybmluZ3MsIGluIDE5NzUgZG9sbGFycyI7CgoqIFJQV0cgIldpZmUncyB3YWdlIHJlcG9ydGVkIGF0IHRoZSB0aW1lIG9mIHRoZSAxOTc2IGludGVydmlldyAobm90IHRoZSBzYW1lIGFzIHRoZSAxOTc1IGVzdGltYXRlZCB3YWdlKS4gIFRvIHVzZSB0aGUgc3Vic2FtcGxlIHdpdGggdGhpcyB3YWdlLCBvbmUgbmVlZHMgdG8gc2VsZWN0IDE5NzUgd29ya2VycyB3aXRoIExGUD0xLCB0aGVuIHNlbGVjdCBvbmx5IHRob3NlIHdvbWVuIHdpdGggbm9uLXplcm8gUlBXRy4gIE9ubHkgMzI1IHdvbWVuIHdvcmsgaW4gMTk3NSBhbmQgaGF2ZSBhIG5vbi16ZXJvIFJQV0cgaW4gMTk3Ni4iOwoKKiBISFJTICJIdXNiYW5kJ3MgaG91cnMgd29ya2VkIGluIDE5NzUiOwoKKiBIQSAgICJIdXNiYW5kJ3MgYWdlIjsKCiogSEUgICAiSHVzYmFuZCdzIGVkdWNhdGlvbmFsIGF0dGFpbm1lbnQsIGluIHllYXJzIjsKCiogSFcgICAiSHVzYmFuZCdzIHdhZ2UsIGluIDE5NzUgZG9sbGFycyI7CgoqIEZBTUlOQyAiRmFtaWx5IGluY29tZSwgaW4gMTk3NSBkb2xsYXJzLiAgVGhpcyB2YXJpYWJsZSBpcyB1c2VkIHRvIGNvbnN0cnVjdCB0aGUgcHJvcGVydHkgaW5jb21lIHZhcmlhYmxlLiI7CgoqIE1UUiAgIlRoaXMgaXMgdGhlIG1hcmdpbmFsIHRheCByYXRlIGZhY2luZyB0aGUgd2lmZSwgYW5kIGlzIHRha2VuIGZyb20gcHVibGlzaGVkIGZlZGVyYWwgdGF4IHRhYmxlcyAoc3RhdGUgYW5kIGxvY2FsIGluY29tZSB0YXhlcyBhcmUgZXhjbHVkZWQpLiBUaGUgdGF4YWJsZSBpbmNvbWUgb24gd2hpY2ggdGhpcyB0YXggcmF0ZSBpcyBjYWxjdWxhdGVkIGluY2x1ZGVzIFNvY2lhbCBTZWN1cml0eSwgaWYgYXBwbGljYWJsZSB0byB3aWZlLiI7CgoqIFdNRUQgIldpZmUncyBtb3RoZXIncyBlZHVjYXRpb25hbCBhdHRhaW5tZW50LCBpbiB5ZWFycyI7CgoqIFdGRUQgIldpZmUncyBmYXRoZXIncyBlZHVjYXRpb25hbCBhdHRhaW5tZW50LCBpbiB5ZWFycyI7CgoqIFVOICAgIlVuZW1wbG95bWVudCByYXRlIGluIGNvdW50eSBvZiByZXNpZGVuY2UsIGluIHBlcmNlbnRhZ2UgcG9pbnRzLiAgVGhpcyB0YWtlbiBmcm9tIGJyYWNrZXRlZCByYW5nZXMuIjsKCiogQ0lUICAiRHVtbXkgdmFyaWFibGUgPSAxIGlmIGxpdmUgaW4gbGFyZ2UgY2l0eSAoU01TQSksIGVsc2UgMCI7CgoqIEFYICAgIkFjdHVhbCB5ZWFycyBvZiB3aWZlJ3MgcHJldmlvdXMgbGFib3IgbWFya2V0IGV4cGVyaWVuY2UiOwoKCiMgSW1wb3J0aW5nIHRoZSBkYXRhCmBgYHtyfQpkYXRhID0gcmVhZC50YWJsZSgiaHR0cDovL2hlZGliZXJ0Lm9yZy93cC1jb250ZW50L3VwbG9hZHMvMjAyMC8wMS9tcm96LWRhdGEudHh0IixoZWFkZXI9VFJVRSkKCmF0dGFjaChkYXRhKQoKbmFtZXMgPSBjKCJMRlAiLCJXSFJTIiwiS0w2IiwiSzYxOCIsIldBIiwiV0UiLCJXVyIsIlJQV0ciLCJISFJTIiwKICAgICAgICAgICJIQSIsIkhFIiwiSFciLCJNVFIiLCJXTUVEIiwiV0ZFRCIsIlVOIiwiQ0lUIiwiQVgiKQoKbiA9IG5yb3coZGF0YSkKeSA9IHNjYWxlKGxvZyhGQU1JTkMpKQpYID0gY2JpbmQoTEZQLFdIUlMsS0w2LEs2MTgsV0EsV0UsV1csUlBXRyxISFJTLEhBLEhFLEhXLE1UUixXTUVELFdGRUQsVU4sQ0lULEFYKQpYID0gc2NhbGUoWCkKcCA9IG5jb2woWCkKYGBgCgojIE1heGltdW0gbGlrZWxpaG9vZCBlc3RpbWF0aW9uIChNTEUpCgpgYGB7ciBmaWcud2lkdGg9OCwgZmlnLmhlaWdodD02LCBmaWcuYWxpZ24gPSAnY2VudGVyJ30Kb2xzID0gbG0oeX5YLTEpCnN1bW1hcnkob2xzKQoKYmV0YS5tbGUgPSBzb2x2ZSh0KFgpJSolWCklKiV0KFgpJSoleQpzaWcyLm1sZSA9IG1lYW4oKHktWCUqJWJldGEubWxlKV4yKQpzZS5tbGUgPSBzcXJ0KHNpZzIubWxlKmRpYWcoc29sdmUodChYKSUqJVgpKSkKY2JpbmQoYmV0YS5tbGUsc2UubWxlKQoKTCA9IGJldGEubWxlICtxbm9ybSgwLjAyNSkqc2UubWxlClUgPSBiZXRhLm1sZSArcW5vcm0oMC45NzUpKnNlLm1sZQoKcGxvdChiZXRhLm1sZSx5bGltPXJhbmdlKEwsVSkseGxhYj0iQ292YXJpYXRlIix5bGFiPSJDb2VmZmljaWVudCIscGNoPTE2KQphYmxpbmUoaD0wLGx0eT0yKQpmb3IgKGkgaW4gMTpwKQogIHNlZ21lbnRzKGksTFtpXSxpLFVbaV0pCmBgYCAKCgojIFByaW9yIGh5cGVycGFyYW1ldGVycwoKYGBge3IgZmlnLndpZHRoPTgsIGZpZy5oZWlnaHQ9NiwgZmlnLmFsaWduID0gJ2NlbnRlcid9CgpiMCAgICAgICA9IHJlcCgwLHApCkIwICAgICAgID0gZGlhZygxLHApCm51MCAgICAgID0gMQpzaWcyMCAgICA9IDAuMgoKbnUwc2lnMjAgPSBudTAqc2lnMjAKaUIwICAgICAgPSBzb2x2ZShCMCkKaUIwYjAgICAgPSBpQjAlKiViMAoKZHJhdyA9IHNxcnQoMS9yZ2FtbWEoMTAwMDAwLG51MC8yLG51MCpzaWcyMC8yKSkKcXVhbnRpbGUoZHJhdyxzZXEoMC4xLDAuOSxieT0wLjEpKQpgYGAKCiMgUG9zdGVyaW9yIHN1ZmZpY2llbnQgc3RhdGlzdGljcwpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NSwgZmlnLmFsaWduID0gJ2NlbnRlcid9CkIxICAgID0gc29sdmUoaUIwK3QoWCklKiVYKQp0Y0IxICA9IHQoY2hvbChCMSkpCmIxICAgID0gQjElKiUoaUIwYjArdChYKSUqJXkpCm51MSAgID0gbnUwICsgKG4tcCkKc2lnMjEgPSAobnUwc2lnMjAgKyB0KHktWCUqJWIxKSUqJXkgKyB0KGIwLWIxKSUqJWlCMGIwKS9udTEKc2UuYmF5ZXMgPSBzcXJ0KGRpYWcoc2lnMjFbMSwxXSpCMSkpCgpMMSA9IGIxK3F0KDAuMDI1LGRmPW51MSkqc2UuYmF5ZXMKVTEgPSBiMStxdCgwLjk3NSxkZj1udTEpKnNlLmJheWVzCgpwYXIobWZyb3c9YygxLDIpKQpwbG90KGIxLHlsaW09cmFuZ2UoTCxVLEwxLFUxKSx4bGFiPSJDb3ZhcmlhdGUiLHlsYWI9IkNvZWZmaWNpZW50IixwY2g9MTYpCmFibGluZShoPTAsbHR5PTIpCmZvciAoaSBpbiAxOnApewogIHNlZ21lbnRzKGksTDFbaV0saSxVMVtpXSkKICBzZWdtZW50cyhpKzAuMixMW2ldLGkrMC4yLFVbaV0sY29sPTIpCiAgcG9pbnRzKGkrMC4yLGJldGEubWxlW2ldLHBjaD0xNixjb2w9MikKfQpsZWdlbmQoImJvdHRvbWxlZnQiLGxlZ2VuZD1jKCJNTEUiLCJCQVlFUyIpLGNvbD0yOjEsbHdkPTIpCgpzaWdtYTIgPSBzZXEoMC4xNSwwLjI1LGxlbmd0aD0xMDAwKQpwbG90KHNpZ21hMixkZ2FtbWEoMS9zaWdtYTIsbnUxLzIsbnUxKnNpZzIxLzIpLyhzaWdtYTJeMikseGxhYj1leHByZXNzaW9uKHNpZ21hXjIpLHlsYWI9IkRlbnNpdHkiLHR5cGU9ImwiKQpsaW5lcyhzaWdtYTIsZGdhbW1hKDEvc2lnbWEyLG51MC8yLG51MCpzaWcyMC8yKS8oc2lnbWEyXjIpLGx0eT0yKQphYmxpbmUodj1zaWcyLm1sZSxjb2w9Mixsd2Q9MikKbGVnZW5kKCJ0b3BsZWZ0IixsZWdlbmQ9YygiUHJpb3IiLCJQb3N0ZXJpb3IiLCJNTEUiKSxjb2w9YygxLDEsMiksbHR5PWMoMSwyLDEpLGx3ZD0yKQpgYGAKCiMgUHJlZGljdGl2ZSAtIGZ1bGwgbW9kZWwgKE0wKQpgYGB7cn0KbSAgID0gWCUqJWIwClYgICA9IHNpZzIwKihkaWFnKDEsbikrWCUqJUIwJSoldChYKSkKcmVzID0gdChjaG9sKFYpKSUqJSh5LW0pCnByZWRpY3RpdmUwID0gc3VtKGR0KHJlcyxkZj1udTAsbG9nPVRSVUUpKQpwcmVkaWN0aXZlMApgYGAKCiMgUHJlZGljdGl2ZSAtIHJlZHVjZWQgbW9kZWwgKE0xKQpgYGB7cn0KWDEgPSBYWyxjKDEsMiw0LDcsOSwxMiwxMywxNywxOCldCnAxID0gbmNvbChYMSkKbSAgID0gWDElKiViMFsxOnAxXQpWICAgPSBzaWcyMCooZGlhZygxLG4pK1gxJSolQjBbMTpwMSwxOnAxXSUqJXQoWDEpKQpyZXMgPSB0KGNob2woVikpJSolKHktbSkKcHJlZGljdGl2ZTEgPSBzdW0oZHQocmVzLGRmPW51MCxsb2c9VFJVRSkpCnByZWRpY3RpdmUxCmBgYAoKIyBQcmVkaWN0aXZlIC0gYW5vdGhlciByZWR1Y2VkIG1vZGVsIChNMikKYGBge3J9ClgyID0gWFssYygxLDIsNCwxMiwxMyldCnAyID0gbmNvbChYMikKbSAgID0gWDIlKiViMFsxOnAyXQpWICAgPSBzaWcyMCooZGlhZygxLG4pK1gyJSolQjBbMTpwMiwxOnAyXSUqJXQoWDIpKQpyZXMgPSB0KGNob2woVikpJSolKHktbSkKcHJlZGljdGl2ZTIgPSBzdW0oZHQocmVzLGRmPW51MCxsb2c9VFJVRSkpCnByZWRpY3RpdmUyCmBgYAoKIyBDb21wdXRpbmcgbG9nIEJheWVzIGZhY3RvcnMKCmBgYHtyfQpsb2dCMTAgPSBwcmVkaWN0aXZlMS1wcmVkaWN0aXZlMApsb2dCMjAgPSBwcmVkaWN0aXZlMi1wcmVkaWN0aXZlMApsb2dCMjEgPSBwcmVkaWN0aXZlMi1wcmVkaWN0aXZlMQoKYyhwcmVkaWN0aXZlMCxwcmVkaWN0aXZlMSxwcmVkaWN0aXZlMikKYyhsb2dCMTAsbG9nQjIwLGxvZ0IyMSkKZXhwKGMobG9nQjEwLGxvZ0IyMCxsb2dCMjEpKQpgYGAKCgojIEZpbmFsIG1vZGVsCgpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NSwgZmlnLmFsaWduID0gJ2NlbnRlcid9ClgyICAgICAgID0gWFssYygxLDIsNCwxMiwxMyldCm5hbWVzMSAgID0gbmFtZXNbYygxLDIsNCwxMiwxMyldCnAgICAgICAgID0gNQpiMCAgICAgICA9IHJlcCgwLHApCkIwICAgICAgID0gZGlhZygxLHApCm51MCAgICAgID0gMQpzaWcyMCAgICA9IDAuMgpudTBzaWcyMCA9IG51MCpzaWcyMAppQjAgICAgICA9IHNvbHZlKEIwKQppQjBiMCAgICA9IGlCMCUqJWIwCgpCMSAgICA9IHNvbHZlKGlCMCt0KFgyKSUqJVgyKQp0Y0IxICA9IHQoY2hvbChCMSkpCmIxICAgID0gQjElKiUoaUIwYjArdChYMiklKiV5KQpudTEgICA9IG51MCArIChuLXApCnNpZzIxID0gKG51MHNpZzIwICsgdCh5LVgyJSolYjEpJSoleSArIHQoYjAtYjEpJSolaUIwYjApL251MQpzZS5iYXllcyA9IHNxcnQoZGlhZyhzaWcyMVsxLDFdKkIxKSkKCkwxID0gYjErcXQoMC4wMjUsZGY9bnUxKSpzZS5iYXllcwpVMSA9IGIxK3F0KDAuOTc1LGRmPW51MSkqc2UuYmF5ZXMKCnBhcihtZnJvdz1jKDEsMSkpCnBsb3QoYjEseWxpbT1yYW5nZShMMSxVMSkseGxhYj0iQ292YXJpYXRlIix5bGFiPSJDb2VmZmljaWVudCIscGNoPTE2LGF4ZXM9RkFMU0UpCmF4aXMoMik7Ym94KCkKYXhpcygxLGF0PTE6cCxsYWI9bmFtZXMxKQphYmxpbmUoaD0wLGx0eT0yKQpmb3IgKGkgaW4gMTpwKQogIHNlZ21lbnRzKGksTDFbaV0saSxVMVtpXSkKdGl0bGUoIkZpbmFsIEJheWVzaWFuIGxpbmVhciBtb2RlbCIpCmBgYAoKUmVncmVzc29yczoKCiogTEZQICAiQSBkdW1teSB2YXJpYWJsZSA9IDEgaWYgd29tYW4gd29ya2VkIGluIDE5NzUsIGVsc2UgMCI7CgoqIFdIUlMgIldpZmUncyBob3VycyBvZiB3b3JrIGluIDE5NzUiOwoKKiBLNjE4ICJOdW1iZXIgb2YgY2hpbGRyZW4gYmV0d2VlbiBhZ2VzIDYgYW5kIDE4IGluIGhvdXNlaG9sZCI7CgoqIEhXICAgIkh1c2JhbmQncyB3YWdlLCBpbiAxOTc1IGRvbGxhcnMiOwoKKiBNVFIgICJUaGlzIGlzIHRoZSBtYXJnaW5hbCB0YXggcmF0ZSBmYWNpbmcgdGhlIHdpZmUsIGFuZCBpcyB0YWtlbiBmcm9tIHB1Ymxpc2hlZCBmZWRlcmFsIHRheCB0YWJsZXMgKHN0YXRlIGFuZCBsb2NhbCBpbmNvbWUgdGF4ZXMgYXJlIGV4Y2x1ZGVkKS4gVGhlIHRheGFibGUgaW5jb21lIG9uIHdoaWNoIHRoaXMgdGF4IHJhdGUgaXMgY2FsY3VsYXRlZCBpbmNsdWRlcyBTb2NpYWwgU2VjdXJpdHksIGlmIGFwcGxpY2FibGUgdG8gd2lmZS4iOwoKIyBSZXNpZHVhbCBhbmFseXNpcwpgYGB7ciBmaWcud2lkdGg9MTAsIGZpZy5oZWlnaHQ9NSwgZmlnLmFsaWduID0gJ2NlbnRlcid9CmZpdHRlZCAgID0gWDIlKiViMQpyZXNpZHVhbCA9ICh5LWZpdHRlZCkvc3FydChzaWcyMVsxLDFdKQpwYXIobWZyb3c9YygxLDIpKQpwbG90KHJlc2lkdWFsLHhsYWI9Ik9ic2VydmF0aW9uIix5bGFiPSJTdGFuZGFyZGl6ZWQgcmVzaWR1YWxzIikKYWJsaW5lKGg9MixsdHk9MikKYWJsaW5lKGg9MCxsdHk9MikKYWJsaW5lKGg9LTIsbHR5PTIpCnRpdGxlKHBhc3RlKCJSZXNpZHVhbHMgb3V0c2lkZSBbLTIsMl0gPSAiLHJvdW5kKDEwMCptZWFuKGFicyhyZXNpZHVhbCk+MiksMSksIiUiLHNlcD0iIikpCgpwbG90KHksZml0dGVkLHhsaW09cmFuZ2UoeSxmaXR0ZWQpLHlsaW09cmFuZ2UoeSxmaXR0ZWQpLHhsYWI9Ik9ic2VydmVkIHJlc3BvbnNlIix5bGFiPSJGaXR0ZWQgcmVzcG9uc2UiKQphYmxpbmUoMCwxLGNvbD0yLGx3ZD0yKQpgYGAK