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:
LFP “A dummy variable = 1 if woman worked in 1975, else
0”;
WHRS “Wife’s hours of work in 1975”;
KL6 “Number of children less than 6 years old in
household”;
K618 “Number of children between ages 6 and 18 in
household”;
WA “Wife’s age”;
WE “Wife’s educational attainment, in years”;
WW “Wife’s average hourly earnings, in 1975 dollars”;
RPWG “Wife’s wage reported at the time of the 1976 interview (not
the same as the 1975 estimated wage). To use the subsample with this
wage, one needs to select 1975 workers with LFP=1, then select only
those women with non-zero RPWG. Only 325 women work in 1975 and have a
non-zero RPWG in 1976.”;
HHRS “Husband’s hours worked in 1975”;
HA “Husband’s age”;
HE “Husband’s educational attainment, in years”;
HW “Husband’s wage, in 1975 dollars”;
FAMINC “Family income, in 1975 dollars. This variable is used to
construct the property income variable.”;
MTR “This is the marginal tax rate facing the wife, and is taken
from published federal tax tables (state and local income taxes are
excluded). The taxable income on which this tax rate is calculated
includes Social Security, if applicable to wife.”;
WMED “Wife’s mother’s educational attainment, in years”;
WFED “Wife’s father’s educational attainment, in years”;
UN “Unemployment rate in county of residence, in percentage
points. This taken from bracketed ranges.”;
CIT “Dummy variable = 1 if live in large city (SMSA), else
0”;
AX “Actual years of wife’s previous labor market
experience”;
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)
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])
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
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)
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
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
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
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
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:
LFP “A dummy variable = 1 if woman worked in 1975, else
0”;
WHRS “Wife’s hours of work in 1975”;
K618 “Number of children between ages 6 and 18 in
household”;
HW “Husband’s wage, in 1975 dollars”;
MTR “This is the marginal tax rate facing the wife, and is taken
from published federal tax tables (state and local income taxes are
excluded). The taxable income on which this tax rate is calculated
includes Social Security, if applicable to wife.”;
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