Задача 1
Ова се податоците од задачата:
| 1936–39 |
32.0 |
16.3 |
| 1946–49 |
31.2 |
23.1 |
| 1956–59 |
27.0 |
23.6 |
| 1966–69 |
21.0 |
27.7 |
| 1976–79 |
14.9 |
34.6 |
| 1986–89 |
8.8 |
33.9 |
Со следниов код ги подготвуваме податоците во R.
period = c(1939, 1949, 1959, 1969, 1979, 1989)
refined = c(32, 31.2, 27, 21, 14.9, 8.8)
not_refined = c(16.3, 23.1, 23.6, 27.7, 34.6, 33.9)
sugar_df = data.frame(period, refined, not_refined)
sugar_df
(a)
Пред се, ја плотираме потрошувачката на шеќер низ времето. Може да се забележи дека иако податоците не се конкретно линеарни, има одредена линеарна зависност.
with(sugar_df, plot(period, refined))

with(sugar_df, plot(period, not_refined))

Креираме два едноставни линеарни модели, ги печатиме информациите за нив (оценети коефициенти, стандардни грешки, p-вредности, R2) и ги плотираме одредените прави на регресијата со податоците:
refined_lm = lm(refined ~ period, data=sugar_df)
not_refined_lm = lm(not_refined ~ period, data=sugar_df)
summary(refined_lm)
Call:
lm(formula = refined ~ period, data = sugar_df)
Residuals:
1 2 3 4 5 6
-2.6905 1.3924 2.0752 0.9581 -0.2590 -1.4762
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 981.47648 95.78387 10.25 0.000511 ***
period -0.48829 0.04877 -10.01 0.000559 ***
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.04 on 4 degrees of freedom
Multiple R-squared: 0.9616, Adjusted R-squared: 0.952
F-statistic: 100.2 on 1 and 4 DF, p-value: 0.0005593
summary(not_refined_lm)
Call:
lm(formula = not_refined ~ period, data = sugar_df)
Residuals:
1 2 3 4 5 6
-1.1905 1.9924 -1.1248 -0.6419 2.6410 -1.6762
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) -683.87352 96.35750 -7.097 0.00208 **
period 0.36171 0.04906 7.373 0.00180 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 2.052 on 4 degrees of freedom
Multiple R-squared: 0.9315, Adjusted R-squared: 0.9143
F-statistic: 54.36 on 1 and 4 DF, p-value: 0.001804
with(sugar_df, plot(period, refined))
abline(refined_lm$coefficients[1], refined_lm$coefficients[2])

with(sugar_df, plot(period, not_refined))
abline(not_refined_lm$coefficients[1], not_refined_lm$coefficients[2])

Годишните интервали на доверба се:
confint(refined_lm, "period")
2.5 % 97.5 %
period -0.6236872 -0.3528842
confint(not_refined_lm, "period")
2.5 % 97.5 %
period 0.2255019 0.4979267
(b)
Пред се, ги пресметуваме просеците и ги плотираме:
sugar_df["average"] = (sugar_df$refined + sugar_df$not_refined) / 2
sugar_df
with(sugar_df, plot(period, average))

Креираме едноставен модел за просекот, за да тестираме дали коефициентот пред period е 0.
average_lm = lm(average ~ period, data=sugar_df)
summary(average_lm)
Call:
lm(formula = average ~ period, data = sugar_df)
Residuals:
1 2 3 4 5 6
-1.9405 1.6924 0.4752 0.1581 1.1910 -1.5762
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 148.80148 77.08724 1.930 0.126
period -0.06329 0.03925 -1.612 0.182
Residual standard error: 1.642 on 4 degrees of freedom
Multiple R-squared: 0.3939, Adjusted R-squared: 0.2424
F-statistic: 2.6 on 1 and 4 DF, p-value: 0.1822
with(sugar_df, plot(period, average))
abline(average_lm$coefficients[1], average_lm$coefficients[2])

Коефициентот пред period е близок до 0, но можеме да ја орфрлиме хипотезата дека не е 0, бидејќи p-вредноста е голема.
Задача 2
Ова се податоците од задачата:
| 0 |
1753.9 |
| 15 |
3107.7 |
| 10 |
2400.0 |
| 40 |
4923.1 |
| 30 |
4415.4 |
| 5 |
2861.6 |
| 50 |
5246.2 |
| 50 |
4938.4 |
| 40 |
3723.0 |
| 5 |
3184.6 |
| 5 |
3046.2 |
| 30 |
4892.3 |
| 10 |
3538.5 |
| 0 |
2553.8 |
| 40 |
4784.6 |
| 30 |
4000.0 |
| 10 |
3323.1 |
| 20 |
3184.6 |
| 15 |
4184.6 |
| 40 |
4461.5 |
| 0 |
2723.1 |
| 40 |
4692.3 |
| 20 |
4215.4 |
| 50 |
4784.6 |
| 20 |
3600.0 |
| 40 |
4153.9 |
| 15 |
3169.3 |
Со следниов код ги подготвуваме податоците во R.
K = c(0, 15, 10, 40, 30, 5, 50, 50, 40, 5, 5, 30, 10, 0, 40, 30, 10, 20, 15, 40, 0, 40, 20, 50, 20, 40, 15)
yield = c(1753.9, 3107.7, 2400, 4923.1, 4415.4, 2861.6, 5246.2, 4938.4, 3723, 3184.6, 3046.2, 4892.3, 3538.5, 2553.8, 4784.6, 4000, 3323.1, 3184.6, 4184.6, 4461.5, 2723.1, 4692.3, 4215.4, 4784.6, 3600, 4153.9, 3169.3)
grass_df = data.frame(K, yield)
grass_df
(a) (b)
Креираме модели, со yield кренато на секој степен од 2 до 10, со пресметан логаритам со сите основи од 2 до 10 и со коренуван yield, и за секој од нив го правиме и линеарниот модел што го има и самото К. Од нив, го бираме моделот со највисок R2.
r2 = c()
model_name = c()
generate_model <- function(predictor, dataframe) {
model = lm(as.formula(paste("yield ~", predictor)), data=dataframe)
r2 <<- append(r2, summary(model)$r.squared)
model_name <<- append(model_name, predictor)
model = lm(as.formula(paste("yield ~", predictor, " + K")), data=dataframe)
r2 <<- append(r2, summary(model)$r.squared)
model_name <<- append(model_name, paste(predictor, "+K", sep=""))
}
generate_model("K", grass_df)
grass_df["K_sqrt"] = grass_df$K ^ 0.5
generate_model("K_sqrt", grass_df)
for (exp in 2:10) {
grass_df[paste("K_", exp, sep="")] = grass_df$K ^ exp
generate_model(paste("K_", exp, sep=""), grass_df)
}
for (base in 2:10) {
grass_df[paste("K_log_", base, sep="")] = log(grass_df$K + 0.01, base=base)
generate_model(paste("K_log_", base, sep=""), grass_df)
}
best_idx = which.max(r2)
best_model_name = model_name[best_idx]
best_model = lm(as.formula(paste("yield ~", best_model_name)), data=grass_df)
best_predictors = strsplit(best_model_name, "\\+")
print(best_predictors)
[[1]]
[1] "K_sqrt" "K"
summary(best_model)
Call:
lm(formula = as.formula(paste("yield ~", best_model_name)), data = grass_df)
Residuals:
Min 1Q Median 3Q Max
-838.96 -241.29 92.13 281.15 731.22
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 2351.06 240.58 9.772 7.69e-10 ***
K_sqrt 206.93 135.73 1.525 0.140
K 22.55 17.67 1.277 0.214
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 433.8 on 24 degrees of freedom
Multiple R-squared: 0.7961, Adjusted R-squared: 0.7791
F-statistic: 46.85 on 2 and 24 DF, p-value: 5.171e-09
(c)
Ги плотираме резидуалите за најдобриот модел. Делува дека тие не следат некоја шема.
grass_df["residuals"] = best_model$residuals
plot(grass_df[c("K", "residuals")])

Задача 3
Ова се податоците од задачата:
| 33 |
33 |
100 |
14 |
| 40 |
47 |
92 |
15 |
| 37 |
49 |
135 |
18 |
| 27 |
35 |
144 |
12 |
| 30 |
46 |
140 |
15 |
| 43 |
52 |
101 |
15 |
| 34 |
62 |
95 |
14 |
| 48 |
23 |
101 |
17 |
| 30 |
32 |
98 |
15 |
| 38 |
42 |
105 |
14 |
| 50 |
31 |
108 |
17 |
| 51 |
61 |
85 |
19 |
| 30 |
63 |
130 |
19 |
| 36 |
40 |
127 |
20 |
| 41 |
50 |
109 |
15 |
| 42 |
64 |
107 |
16 |
| 46 |
56 |
117 |
18 |
| 24 |
61 |
100 |
13 |
| 35 |
48 |
118 |
18 |
| 37 |
28 |
102 |
14 |
Со следниов код ги подготвуваме податоците во R.
carbo = c(33, 40, 37, 27, 30, 43, 34, 48, 30, 38, 50, 51, 30, 36, 41, 42, 46, 24, 35, 37)
age = c(33, 47, 49, 35, 46, 52, 62, 23, 32, 42, 31, 61, 63, 40, 50, 64, 56, 61, 48, 28)
weight = c(100, 92, 135, 144, 140, 101, 95, 101, 98, 105, 108, 85, 130, 127, 109, 107, 117, 100, 118, 102)
protein = c(14, 15, 18, 12, 15, 15, 14, 17, 15, 14, 17, 19, 19, 20, 15, 16, 18, 13, 18, 14)
carbo_df = data.frame(carbo, age, weight, protein)
carbo_df
(a)
for (predictor in c("age", "weight", "protein")) {
plot(carbo_df[c(predictor, "carbo")])
}



Возраста делува линеарно поврзана, но има и доста outliers.
Кај тежината можеме да забележиме хетероскедастичност (помали тежини делуваат ко да имаат повисока варијанса).
Протеините делуваат линеарно поврзани, но не може да се потврди само визуелно.
(b)
Како што расте вистинската вредност, расте и грешката, што сугерира дека постои линеарна зависност помеѓу carbo и резидуалот.
carbo_all_lm = lm(carbo ~ age + weight + protein, data=carbo_df)
summary(carbo_all_lm)
Call:
lm(formula = carbo ~ age + weight + protein, data = carbo_df)
Residuals:
Min 1Q Median 3Q Max
-10.3424 -4.8203 0.9897 3.8553 7.9087
Coefficients:
Estimate Std. Error t value Pr(>|t|)
(Intercept) 36.96006 13.07128 2.828 0.01213 *
age -0.11368 0.10933 -1.040 0.31389
weight -0.22802 0.08329 -2.738 0.01460 *
protein 1.95771 0.63489 3.084 0.00712 **
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Residual standard error: 5.956 on 16 degrees of freedom
Multiple R-squared: 0.4805, Adjusted R-squared: 0.3831
F-statistic: 4.934 on 3 and 16 DF, p-value: 0.01297
carbo_df["residuals_all_lm"] = carbo_all_lm$residuals
plot(carbo_df[c("carbo", "residuals_all_lm")])

(c)
Со пресметување на F статистиката, согледуваме дека вредноста не е доволно различна од центрираната F дистрибуција за да се отфрли \(H_0: \beta_1 = 0\).
carbo_age_protein_lm = lm(carbo ~ age + protein, data=carbo_df)
age_protein_anova = anova(carbo_age_protein_lm)
carbo_protein_lm = lm(carbo ~ protein, data=carbo_df)
protein_anova = anova(carbo_protein_lm)
dfs = c(age_protein_anova$Df[3], protein_anova$Df[2])
Ds = c(age_protein_anova$`Sum Sq`[3], protein_anova$`Sum Sq`[2])
delta_D = Ds[2] - Ds[1]
delta_dfs = dfs[2] - dfs[1]
F_statistic = (delta_D / delta_dfs) / (Ds[1] / dfs[1])
real_F_statistic = pf(F_statistic, delta_dfs, dfs[1])
c(F_statistic, real_F_statistic, F_statistic - real_F_statistic)
[1] 0.511473248 0.515791133 -0.004317885
Задача 4
Ова се податоците од задачата:
| 5.94 |
52 |
20.7 |
| 6.48 |
65 |
26.3 |
| 4.71 |
46 |
21.3 |
| 8.83 |
76 |
22.7 |
| 5.86 |
51 |
25.4 |
| 5.10 |
47 |
21.5 |
| 6.52 |
44 |
22.7 |
| 5.81 |
43 |
20.7 |
| 6.80 |
70 |
23.9 |
| 4.65 |
30 |
18.9 |
| 5.23 |
33 |
24.3 |
| 6.82 |
58 |
23.9 |
| 4.97 |
21 |
22.2 |
| 6.28 |
78 |
24.3 |
| 8.78 |
63 |
26.2 |
| 5.15 |
49 |
23.8 |
| 5.13 |
56 |
23.3 |
| 2.92 |
36 |
19.6 |
| 6.74 |
54 |
29.2 |
| 9.27 |
67 |
24.3 |
| 5.95 |
44 |
22.7 |
| 5.57 |
42 |
22.0 |
| 5.83 |
71 |
21.9 |
| 4.92 |
29 |
22.5 |
| 5.74 |
39 |
22.4 |
| 6.72 |
33 |
24.1 |
| 4.92 |
58 |
20.2 |
| 5.57 |
42 |
22.7 |
| 6.69 |
58 |
24.4 |
| 6.25 |
66 |
27.3 |
Со следниов код ги подготвуваме во R:
chol = c(5.94, 6.48, 4.71, 8.83, 5.86, 5.1, 6.52, 5.81, 6.8, 4.65, 5.23, 6.82, 4.97, 6.28, 8.78, 5.15, 5.13, 2.92, 6.74, 9.27, 5.95, 5.57, 5.83, 4.92, 5.74, 6.72, 4.92, 5.57, 6.69, 6.25)
age = c(52, 65, 46, 76, 51, 47, 44, 43, 70, 30, 33, 58, 21, 78, 63, 49, 56, 36, 54, 67, 44, 42, 71, 29, 39, 33, 58, 42, 58, 66)
bmi = c(20.7, 26.3, 21.3, 22.7, 25.4, 21.5, 22.7, 20.7, 23.9, 18.9, 24.3, 23.9, 22.2, 24.3, 26.2, 23.8, 23.3, 19.6, 29.2, 24.3, 22.7, 22, 21.9, 22.5, 22.4, 24.1, 20.2, 22.7, 24.4, 27.3)
chol_df = data.frame(chol, age, bmi)
chol_df
Креираме модел со и без bmi и пресметуваме F статистика за да ја тестираме хипотезата \(H_0:\beta_{BMI}=0\). Високото отстапување од F дистрибуцијата ни укажува дека нултата хипотеза се отфрла, т.е. холестеролот зависи од bmi кога е вклучено age.
with_bmi_lm = lm(chol ~ age + bmi, data=chol_df)
with_bmi_anova = anova(with_bmi_lm)
no_bmi_lm = lm(chol ~ age)
no_bmi_anova = anova(no_bmi_lm)
dfs = c(with_bmi_anova$Df[3], no_bmi_anova$Df[2])
Ds = c(with_bmi_anova$`Sum Sq`[3], no_bmi_anova$`Sum Sq`[2])
delta_D = Ds[2] - Ds[1]
delta_dfs = dfs[2] - dfs[1]
F_statistic = (delta_D / delta_dfs) / (Ds[1] / dfs[1])
real_F_statistic = pf(F_statistic, delta_dfs, dfs[1])
c(F_statistic, real_F_statistic, F_statistic - real_F_statistic)
[1] 5.1473853 0.9685125 4.1788728
Задача 5
Податоците од задачата ги сетираме во R. Мораме да внимаваме да дефинираме фактор променлива.
hyper = c(2.3, 4.1, 4.2, 4.0, 4.6, 4.6, 3.8, 5.2, 3.1, 3.7, 3.8)
non_hyper = c(3.0, 4.1, 3.9, 3.1, 3.3, 2.9, 3.3, 3.9)
control = c(3.0, 2.6, 3.1, 2.2, 2.1, 2.4, 2.8, 3.4, 2.9, 2.6, 3.1, 3.2)
plasma = c(hyper, non_hyper, control)
group = factor(c(
rep("hyper", length(hyper)),
rep("non_hyper", length(non_hyper)),
rep("control", length(control))
))
plasma_df = data.frame(plasma, group)
plasma_df
(a)
Користиме анова за да пресметаме F статистика. Ниската вредност на Pr(>F) ни укажува дека средините на групите не се еднакви.
plasma_lm = lm(plasma~group)
anova(plasma_lm)
Analysis of Variance Table
Response: plasma
Df Sum Sq Mean Sq F value Pr(>F)
group 2 7.8083 3.9041 11.651 0.0002082 ***
Residuals 28 9.3827 0.3351
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(b)
Прво пресметуваме стандардна девијација низ групите.
pooled_std = sqrt(sum(c(
var(hyper) * (length(hyper) - 1),
var(non_hyper) * (length(non_hyper) - 1),
var(control) * (length(control) - 1)
)) / (length(plasma) - 3))
Интервалот на доверба е:
estimated_diff = mean(hyper) - mean(non_hyper)
t_alpha_half = qt(0.975, 28)
CI = c(estimated_diff - t_alpha_half * pooled_std, estimated_diff + t_alpha_half * pooled_std)
CI
[1] -0.6778168 1.6937258
(c)
Резидуалите линеарно растат во секоја група.
plasma_df["residuals"] = plasma_lm$residuals
plot(hyper, plasma_df[plasma_df$group == "hyper",]$residuals, ylab="residuals")

plot(non_hyper, plasma_df[plasma_df$group == "non_hyper",]$residuals, ylab="residuals")

plot(control, plasma_df[plasma_df$group == "control",]$residuals, ylab="residuals")

Задача 6
Ова се податоците од задачата:
weight = c(35.7, 38.4, 34.9, 37.1, 37.1, 37.2, 34.3, 35.5, 36.7, 38.1, 34.5, 36.5, 37.7, 36.9, 33.7, 36, 35.3, 37.2, 36.2, 33.8, 34.7, 36.9, 32, 35.8, 35.2, 38.5, 35.2, 32.9, 34.6, 36.4, 33.5, 35.7, 36.4, 37.8, 32.9, 38, 35.2, 36.1, 33.3, 36.1)
worker = factor(rep(c(1, 2, 3, 4), 10))
day = factor(c(rep(1, 20), rep(2, 20)))
weight_df = data.frame(weight, worker, day)
weight_df
Од двостраната анова заклучуваме дека има значајни разлики помеѓу работниците и помеѓу деновите (F статистика значајно отскокнува од вредноста на дистрибуцијата, обележано и со ѕвездички). Нема доволно показатели за постоечка интеракција.
weight_lm = lm(weight ~ worker + day + worker * day, data=weight_df)
anova(weight_lm)
Analysis of Variance Table
Response: weight
Df Sum Sq Mean Sq F value Pr(>F)
worker 3 54.622 18.2073 14.4948 3.895e-06 ***
day 1 6.084 6.0840 4.8435 0.03508 *
worker:day 3 2.958 0.9860 0.7850 0.51117
Residuals 32 40.196 1.2561
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
Задача 7
Ова се податоците од задачата:
samples = c(6.8, 6.6, 5.3, 6.1, 7.5, 7.4, 7.2, 6.5, 7.8, 9.1, 8.8, 9.1)
b = factor(rep(c(-1, -1, 1, 1), 3))
a = factor(c(rep(-1, 4), rep(1, 4), rep(0, 4)))
samples_df = data.frame(samples, a, b)
samples_df
(a)
Ова е матрицата X:
X = matrix(
c(
1, −1, −1, −1, 1, 1,
1, −1, −1, −1, 1, 1,
1, −1, −1, 1, −1, −1,
1, −1, −1, 1, −1, −1,
1, 1, 0, −1, −1, 0,
1, 1, 0, −1, −1, 0,
1, 1, 0, 1, 1, 0,
1, 1, 0, 1, 1, 0,
1, 0, 1, −1, 0, −1,
1, 0, 1, −1, 0, −1,
1, 0, 1, 1, 0, 1,
1, 0, 1, 1, 0, 1
),
nrow=12,
ncol=6,
byrow=TRUE
)
X
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 1 -1 -1 -1 1 1
[2,] 1 -1 -1 -1 1 1
[3,] 1 -1 -1 1 -1 -1
[4,] 1 -1 -1 1 -1 -1
[5,] 1 1 0 -1 -1 0
[6,] 1 1 0 -1 -1 0
[7,] 1 1 0 1 1 0
[8,] 1 1 0 1 1 0
[9,] 1 0 1 -1 0 -1
[10,] 1 0 1 -1 0 -1
[11,] 1 0 1 1 0 1
[12,] 1 0 1 1 0 1
Пресметуваме XtX. Производот е блок дијагонална матрица (3х3 блоковите по дијагонала се ненулти, другите се нулти).
XtX = t(X) %*% X
XtX
[,1] [,2] [,3] [,4] [,5] [,6]
[1,] 12 0 0 0 0 0
[2,] 0 8 4 0 0 0
[3,] 0 4 8 0 0 0
[4,] 0 0 0 12 0 0
[5,] 0 0 0 0 8 4
[6,] 0 0 0 0 4 8
Ги пресметуваме моделите 6.9, 6.10 и 6.12 со оваа спецификација и можеме да се увериме дека навистина се исти како во табелата во текстот.
samples_glm_a_b_ab = glm(samples ~ a * b, family=gaussian, data=samples_df)
samples_glm_a_b = glm(samples ~ a + b, family=gaussian, data=samples_df)
samples_glm_b = glm(samples ~ b, family=gaussian, data=samples_df)
anova(samples_glm_a_b_ab)
Analysis of Deviance Table
Model: gaussian, link: identity
Response: samples
Terms added sequentially (first to last)
Df Deviance Resid. Df Resid. Dev
NULL 11 15.8300
a 2 12.7400 9 3.0900
b 1 0.4033 8 2.6867
a:b 2 1.2067 6 1.4800
anova(samples_glm_a_b)
Analysis of Deviance Table
Model: gaussian, link: identity
Response: samples
Terms added sequentially (first to last)
Df Deviance Resid. Df Resid. Dev
NULL 11 15.8300
a 2 12.7400 9 3.0900
b 1 0.4033 8 2.6867
anova(samples_glm_b)
Analysis of Deviance Table
Model: gaussian, link: identity
Response: samples
Terms added sequentially (first to last)
Df Deviance Resid. Df Resid. Dev
NULL 11 15.830
b 1 0.40333 10 15.427
(b)
Доволно е да ги видиме коефициентите на моделите и да заклучиме дека оценетиот просек ќе е ист.
samples_glm_a_b_ab$coefficients
(Intercept) a0 a1 b1 a0:b1 a1:b1
6.70 1.75 0.75 -1.00 1.50 0.40
samples_glm_a_b$coefficients
(Intercept) a0 a1 b1
6.3833333 2.5000000 0.9500000 -0.3666667
Задача 8
Ова се податоците од задачата:
samples = c(5, 3, 4, 6, 4, 4, 3, 7, 6, 8)
a = factor(c(1, 1, 1, 2, 2, 2, 2, 3, 3, 3))
b = factor(c(1, 2, 2, 1, 1, 2, 2, 1, 2, 2))
samples_df = data.frame(samples, a, b)
samples_df
(a)
За да провериме дали има интеракција, треба да гo тестираме сатурираниот модел. Oд тестот следи дека не можеме да ја отфрлиме хипотезата дека има интеракција.
saturated_lm = glm(samples ~ a * b, family=gaussian, data=samples_df)
anova(saturated_lm, test="Chisq")
Analysis of Deviance Table
Model: gaussian, link: identity
Response: samples
Terms added sequentially (first to last)
Df Deviance Resid. Df Resid. Dev Pr(>Chi)
NULL 9 26.0000
a 2 17.2500 7 8.7500 0.001008 **
b 1 2.6786 6 6.0714 0.143235
a:b 2 1.0714 4 5.0000 0.651439
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
(b)
За да провериме дали има ефект поради А, треба да гo тестираме адитивниот модел. Oд тестот следи дека можеме да ја орфрлиме хипотезата дека има ефект поради А.
additive_lm = glm(samples ~ a + b, family=gaussian, data=samples_df)
anova(additive_lm, test="Chisq")
Analysis of Deviance Table
Model: gaussian, link: identity
Response: samples
Terms added sequentially (first to last)
Df Deviance Resid. Df Resid. Dev Pr(>Chi)
NULL 9 26.0000
a 2 17.2500 7 8.7500 0.0001987 ***
b 1 2.6786 6 6.0714 0.1037417
---
Signif. codes: 0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1
LS0tDQp0aXRsZTogItCT0LvQsNCy0LAgNjog0J3QvtGA0LzQsNC70L3QuCDQu9C40L3QtdCw0YDQvdC4INC80L7QtNC10LvQuCINCm91dHB1dDogaHRtbF9ub3RlYm9vaw0KLS0tDQoNCiMg0JfQsNC00LDRh9CwIDENCg0K0J7QstCwINGB0LUg0L/QvtC00LDRgtC+0YbQuNGC0LUg0L7QtCDQt9Cw0LTQsNGH0LDRgtCwOg0KDQp8cGVyaW9kfHJlZmluZWR8bm90X3JlZmluZWR8DQp8LS0tfC0tLXwtLS18DQp8MTkzNuKAkzM5fDMyLjB8MTYuM3wNCnwxOTQ24oCTNDl8MzEuMnwyMy4xfA0KfDE5NTbigJM1OXwyNy4wfDIzLjZ8DQp8MTk2NuKAkzY5fDIxLjB8MjcuN3wNCnwxOTc24oCTNzl8MTQuOXwzNC42fA0KfDE5ODbigJM4OXw4Ljh8MzMuOXwNCg0K0KHQviDRgdC70LXQtNC90LjQvtCyINC60L7QtCDQs9C4INC/0L7QtNCz0L7RgtCy0YPQstCw0LzQtSDQv9C+0LTQsNGC0L7RhtC40YLQtSDQstC+IFIuDQoNCmBgYHtyfQ0KcGVyaW9kID0gYygxOTM5LCAxOTQ5LCAxOTU5LCAxOTY5LCAxOTc5LCAxOTg5KQ0KcmVmaW5lZCA9IGMoMzIsIDMxLjIsIDI3LCAyMSwgMTQuOSwgOC44KQ0Kbm90X3JlZmluZWQgPSBjKDE2LjMsIDIzLjEsIDIzLjYsIDI3LjcsIDM0LjYsIDMzLjkpDQpzdWdhcl9kZiA9IGRhdGEuZnJhbWUocGVyaW9kLCByZWZpbmVkLCBub3RfcmVmaW5lZCkNCnN1Z2FyX2RmDQpgYGANCg0KIyMjIChhKQ0KDQrQn9GA0LXQtCDRgdC1LCDRmNCwINC/0LvQvtGC0LjRgNCw0LzQtSDQv9C+0YLRgNC+0YjRg9Cy0LDRh9C60LDRgtCwINC90LAg0YjQtdGc0LXRgCDQvdC40Lcg0LLRgNC10LzQtdGC0L4uINCc0L7QttC1INC00LAg0YHQtSDQt9Cw0LHQtdC70LXQttC4INC00LXQutCwINC40LDQutC+INC/0L7QtNCw0YLQvtGG0LjRgtC1INC90LUg0YHQtSDQutC+0L3QutGA0LXRgtC90L4g0LvQuNC90LXQsNGA0L3QuCwg0LjQvNCwINC+0LTRgNC10LTQtdC90LAg0LvQuNC90LXQsNGA0L3QsCDQt9Cw0LLQuNGB0L3QvtGB0YIuDQoNCmBgYHtyfQ0Kd2l0aChzdWdhcl9kZiwgcGxvdChwZXJpb2QsIHJlZmluZWQpKQ0Kd2l0aChzdWdhcl9kZiwgcGxvdChwZXJpb2QsIG5vdF9yZWZpbmVkKSkNCmBgYA0KDQrQmtGA0LXQuNGA0LDQvNC1INC00LLQsCDQtdC00L3QvtGB0YLQsNCy0L3QuCDQu9C40L3QtdCw0YDQvdC4INC80L7QtNC10LvQuCwg0LPQuCDQv9C10YfQsNGC0LjQvNC1INC40L3RhNC+0YDQvNCw0YbQuNC40YLQtSDQt9CwINC90LjQsiAo0L7RhtC10L3QtdGC0Lgg0LrQvtC10YTQuNGG0LjQtdC90YLQuCwg0YHRgtCw0L3QtNCw0YDQtNC90Lgg0LPRgNC10YjQutC4LCBwLdCy0YDQtdC00L3QvtGB0YLQuCwgUjIpINC4INCz0Lgg0L/Qu9C+0YLQuNGA0LDQvNC1INC+0LTRgNC10LTQtdC90LjRgtC1INC/0YDQsNCy0Lgg0L3QsCDRgNC10LPRgNC10YHQuNGY0LDRgtCwINGB0L4g0L/QvtC00LDRgtC+0YbQuNGC0LU6DQoNCmBgYHtyfQ0KcmVmaW5lZF9sbSA9IGxtKHJlZmluZWQgfiBwZXJpb2QsIGRhdGE9c3VnYXJfZGYpDQpub3RfcmVmaW5lZF9sbSA9IGxtKG5vdF9yZWZpbmVkIH4gcGVyaW9kLCBkYXRhPXN1Z2FyX2RmKQ0KYGBgDQpgYGB7cn0NCnN1bW1hcnkocmVmaW5lZF9sbSkNCnN1bW1hcnkobm90X3JlZmluZWRfbG0pDQp3aXRoKHN1Z2FyX2RmLCBwbG90KHBlcmlvZCwgcmVmaW5lZCkpDQphYmxpbmUocmVmaW5lZF9sbSRjb2VmZmljaWVudHNbMV0sIHJlZmluZWRfbG0kY29lZmZpY2llbnRzWzJdKQ0Kd2l0aChzdWdhcl9kZiwgcGxvdChwZXJpb2QsIG5vdF9yZWZpbmVkKSkNCmFibGluZShub3RfcmVmaW5lZF9sbSRjb2VmZmljaWVudHNbMV0sIG5vdF9yZWZpbmVkX2xtJGNvZWZmaWNpZW50c1syXSkNCmBgYA0KDQrQk9C+0LTQuNGI0L3QuNGC0LUg0LjQvdGC0LXRgNCy0LDQu9C4INC90LAg0LTQvtCy0LXRgNCx0LAg0YHQtToNCmBgYHtyfQ0KY29uZmludChyZWZpbmVkX2xtLCAicGVyaW9kIikNCmNvbmZpbnQobm90X3JlZmluZWRfbG0sICJwZXJpb2QiKQ0KYGBgDQoNCiMjIyAoYikNCg0K0J/RgNC10LQg0YHQtSwg0LPQuCDQv9GA0LXRgdC80LXRgtGD0LLQsNC80LUg0L/RgNC+0YHQtdGG0LjRgtC1INC4INCz0Lgg0L/Qu9C+0YLQuNGA0LDQvNC1Og0KYGBge3J9DQpzdWdhcl9kZlsiYXZlcmFnZSJdID0gKHN1Z2FyX2RmJHJlZmluZWQgKyBzdWdhcl9kZiRub3RfcmVmaW5lZCkgLyAyDQpzdWdhcl9kZg0Kd2l0aChzdWdhcl9kZiwgcGxvdChwZXJpb2QsIGF2ZXJhZ2UpKQ0KYGBgDQoNCtCa0YDQtdC40YDQsNC80LUg0LXQtNC90L7RgdGC0LDQstC10L0g0LzQvtC00LXQuyDQt9CwINC/0YDQvtGB0LXQutC+0YIsINC30LAg0LTQsCDRgtC10YHRgtC40YDQsNC80LUg0LTQsNC70Lgg0LrQvtC10YTQuNGG0LjQtdC90YLQvtGCINC/0YDQtdC0IHBlcmlvZCDQtSAwLg0KDQpgYGB7cn0NCmF2ZXJhZ2VfbG0gPSBsbShhdmVyYWdlIH4gcGVyaW9kLCBkYXRhPXN1Z2FyX2RmKQ0Kc3VtbWFyeShhdmVyYWdlX2xtKQ0Kd2l0aChzdWdhcl9kZiwgcGxvdChwZXJpb2QsIGF2ZXJhZ2UpKQ0KYWJsaW5lKGF2ZXJhZ2VfbG0kY29lZmZpY2llbnRzWzFdLCBhdmVyYWdlX2xtJGNvZWZmaWNpZW50c1syXSkNCmBgYA0KDQrQmtC+0LXRhNC40YbQuNC10L3RgtC+0YIg0L/RgNC10LQgcGVyaW9kINC1INCx0LvQuNC30L7QuiDQtNC+IDAsINC90L4g0LzQvtC20LXQvNC1INC00LAg0ZjQsCDQvtGA0YTRgNC70LjQvNC1INGF0LjQv9C+0YLQtdC30LDRgtCwINC00LXQutCwINC90LUg0LUgMCwg0LHQuNC00LXRmNGc0LggcC3QstGA0LXQtNC90L7RgdGC0LAg0LUg0LPQvtC70LXQvNCwLg0KDQojINCX0LDQtNCw0YfQsCAyDQoNCtCe0LLQsCDRgdC1INC/0L7QtNCw0YLQvtGG0LjRgtC1INC+0LQg0LfQsNC00LDRh9Cw0YLQsDoNCg0KfEt8WWllbGR8DQp8LS0tfC0tLXwNCnwwfDE3NTMuOXwNCnwxNXwzMTA3Ljd8DQp8MTB8MjQwMC4wfA0KfDQwfDQ5MjMuMXwNCnwzMHw0NDE1LjR8DQp8NXwyODYxLjZ8DQp8NTB8NTI0Ni4yfA0KfDUwfDQ5MzguNHwNCnw0MHwzNzIzLjB8DQp8NXwzMTg0LjZ8DQp8NXwzMDQ2LjJ8DQp8MzB8NDg5Mi4zfA0KfDEwfDM1MzguNXwNCnwwfDI1NTMuOHwNCnw0MHw0Nzg0LjZ8DQp8MzB8NDAwMC4wfA0KfDEwfDMzMjMuMXwNCnwyMHwzMTg0LjZ8DQp8MTV8NDE4NC42fA0KfDQwfDQ0NjEuNXwNCnwwfDI3MjMuMXwNCnw0MHw0NjkyLjN8DQp8MjB8NDIxNS40fA0KfDUwfDQ3ODQuNnwNCnwyMHwzNjAwLjB8DQp8NDB8NDE1My45fA0KfDE1fDMxNjkuM3wNCg0K0KHQviDRgdC70LXQtNC90LjQvtCyINC60L7QtCDQs9C4INC/0L7QtNCz0L7RgtCy0YPQstCw0LzQtSDQv9C+0LTQsNGC0L7RhtC40YLQtSDQstC+IFIuDQoNCmBgYHtyfQ0KSyA9IGMoMCwgMTUsIDEwLCA0MCwgMzAsIDUsIDUwLCA1MCwgNDAsIDUsIDUsIDMwLCAxMCwgMCwgNDAsIDMwLCAxMCwgMjAsIDE1LCA0MCwgMCwgNDAsIDIwLCA1MCwgMjAsIDQwLCAxNSkNCnlpZWxkID0gYygxNzUzLjksIDMxMDcuNywgMjQwMCwgNDkyMy4xLCA0NDE1LjQsIDI4NjEuNiwgNTI0Ni4yLCA0OTM4LjQsIDM3MjMsIDMxODQuNiwgMzA0Ni4yLCA0ODkyLjMsIDM1MzguNSwgMjU1My44LCA0Nzg0LjYsIDQwMDAsIDMzMjMuMSwgMzE4NC42LCA0MTg0LjYsIDQ0NjEuNSwgMjcyMy4xLCA0NjkyLjMsIDQyMTUuNCwgNDc4NC42LCAzNjAwLCA0MTUzLjksIDMxNjkuMykNCmdyYXNzX2RmID0gZGF0YS5mcmFtZShLLCB5aWVsZCkNCmdyYXNzX2RmDQpgYGANCg0KIyMjIChhKSAoYikNCg0K0JrRgNC10LjRgNCw0LzQtSDQvNC+0LTQtdC70LgsINGB0L4geWllbGQg0LrRgNC10L3QsNGC0L4g0L3QsCDRgdC10LrQvtGYINGB0YLQtdC/0LXQvSDQvtC0IDIg0LTQviAxMCwg0YHQviDQv9GA0LXRgdC80LXRgtCw0L0g0LvQvtCz0LDRgNC40YLQsNC8INGB0L4g0YHQuNGC0LUg0L7RgdC90L7QstC4INC+0LQgMiDQtNC+IDEwINC4INGB0L4g0LrQvtGA0LXQvdGD0LLQsNC9IHlpZWxkLCDQuCDQt9CwINGB0LXQutC+0Zgg0L7QtCDQvdC40LIg0LPQviDQv9GA0LDQstC40LzQtSDQuCDQu9C40L3QtdCw0YDQvdC40L7RgiDQvNC+0LTQtdC7INGI0YLQviDQs9C+INC40LzQsCDQuCDRgdCw0LzQvtGC0L4g0JouINCe0LQg0L3QuNCyLCDQs9C+INCx0LjRgNCw0LzQtSDQvNC+0LTQtdC70L7RgiDRgdC+INC90LDRmNCy0LjRgdC+0LogUjIuDQoNCmBgYHtyfQ0KcjIgPSBjKCkNCm1vZGVsX25hbWUgPSBjKCkNCg0KZ2VuZXJhdGVfbW9kZWwgPC0gZnVuY3Rpb24ocHJlZGljdG9yLCBkYXRhZnJhbWUpIHsNCiAgbW9kZWwgPSBsbShhcy5mb3JtdWxhKHBhc3RlKCJ5aWVsZCB+IiwgcHJlZGljdG9yKSksIGRhdGE9ZGF0YWZyYW1lKQ0KICByMiA8PC0gYXBwZW5kKHIyLCBzdW1tYXJ5KG1vZGVsKSRyLnNxdWFyZWQpDQogIG1vZGVsX25hbWUgPDwtIGFwcGVuZChtb2RlbF9uYW1lLCBwcmVkaWN0b3IpDQogIA0KICBtb2RlbCA9IGxtKGFzLmZvcm11bGEocGFzdGUoInlpZWxkIH4iLCBwcmVkaWN0b3IsICIgKyBLIikpLCBkYXRhPWRhdGFmcmFtZSkNCiAgcjIgPDwtIGFwcGVuZChyMiwgc3VtbWFyeShtb2RlbCkkci5zcXVhcmVkKQ0KICBtb2RlbF9uYW1lIDw8LSBhcHBlbmQobW9kZWxfbmFtZSwgcGFzdGUocHJlZGljdG9yLCAiK0siLCBzZXA9IiIpKQ0KfQ0KDQpnZW5lcmF0ZV9tb2RlbCgiSyIsIGdyYXNzX2RmKQ0KDQpncmFzc19kZlsiS19zcXJ0Il0gPSBncmFzc19kZiRLIF4gMC41DQpnZW5lcmF0ZV9tb2RlbCgiS19zcXJ0IiwgZ3Jhc3NfZGYpDQoNCmZvciAoZXhwIGluIDI6MTApIHsNCiAgZ3Jhc3NfZGZbcGFzdGUoIktfIiwgZXhwLCBzZXA9IiIpXSA9IGdyYXNzX2RmJEsgXiBleHANCiAgZ2VuZXJhdGVfbW9kZWwocGFzdGUoIktfIiwgZXhwLCBzZXA9IiIpLCBncmFzc19kZikNCn0NCg0KZm9yIChiYXNlIGluIDI6MTApIHsNCiAgZ3Jhc3NfZGZbcGFzdGUoIktfbG9nXyIsIGJhc2UsIHNlcD0iIildID0gbG9nKGdyYXNzX2RmJEsgKyAwLjAxLCBiYXNlPWJhc2UpDQogIGdlbmVyYXRlX21vZGVsKHBhc3RlKCJLX2xvZ18iLCBiYXNlLCBzZXA9IiIpLCBncmFzc19kZikNCn0NCg0KYmVzdF9pZHggPSB3aGljaC5tYXgocjIpDQpiZXN0X21vZGVsX25hbWUgPSBtb2RlbF9uYW1lW2Jlc3RfaWR4XQ0KYmVzdF9tb2RlbCA9IGxtKGFzLmZvcm11bGEocGFzdGUoInlpZWxkIH4iLCBiZXN0X21vZGVsX25hbWUpKSwgZGF0YT1ncmFzc19kZikNCmJlc3RfcHJlZGljdG9ycyA9IHN0cnNwbGl0KGJlc3RfbW9kZWxfbmFtZSwgIlxcKyIpDQpwcmludChiZXN0X3ByZWRpY3RvcnMpDQpzdW1tYXJ5KGJlc3RfbW9kZWwpDQpgYGANCg0KIyMjIChjKQ0KDQrQk9C4INC/0LvQvtGC0LjRgNCw0LzQtSDRgNC10LfQuNC00YPQsNC70LjRgtC1INC30LAg0L3QsNGY0LTQvtCx0YDQuNC+0YIg0LzQvtC00LXQuy4g0JTQtdC70YPQstCwINC00LXQutCwINGC0LjQtSDQvdC1INGB0LvQtdC00LDRgiDQvdC10LrQvtGY0LAg0YjQtdC80LAuDQoNCmBgYHtyfQ0KZ3Jhc3NfZGZbInJlc2lkdWFscyJdID0gYmVzdF9tb2RlbCRyZXNpZHVhbHMNCnBsb3QoZ3Jhc3NfZGZbYygiSyIsICJyZXNpZHVhbHMiKV0pDQpgYGANCg0KIyDQl9Cw0LTQsNGH0LAgMw0KDQrQntCy0LAg0YHQtSDQv9C+0LTQsNGC0L7RhtC40YLQtSDQvtC0INC30LDQtNCw0YfQsNGC0LA6DQoNCnxDYXJib2h5ZHJhdGV8QWdlfFdlaWdodHxQcm90ZWlufA0KfC0tLXwtLS18LS0tfC0tLXwNCnwzM3wzM3wxMDB8MTR8DQp8NDB8NDd8OTJ8MTV8DQp8Mzd8NDl8MTM1fDE4fA0KfDI3fDM1fDE0NHwxMnwNCnwzMHw0NnwxNDB8MTV8DQp8NDN8NTJ8MTAxfDE1fA0KfDM0fDYyfDk1fDE0fA0KfDQ4fDIzfDEwMXwxN3wNCnwzMHwzMnw5OHwxNXwNCnwzOHw0MnwxMDV8MTR8DQp8NTB8MzF8MTA4fDE3fA0KfDUxfDYxfDg1fDE5fA0KfDMwfDYzfDEzMHwxOXwNCnwzNnw0MHwxMjd8MjB8DQp8NDF8NTB8MTA5fDE1fA0KfDQyfDY0fDEwN3wxNnwNCnw0Nnw1NnwxMTd8MTh8DQp8MjR8NjF8MTAwfDEzfA0KfDM1fDQ4fDExOHwxOHwNCnwzN3wyOHwxMDJ8MTR8DQoNCtCh0L4g0YHQu9C10LTQvdC40L7QsiDQutC+0LQg0LPQuCDQv9C+0LTQs9C+0YLQstGD0LLQsNC80LUg0L/QvtC00LDRgtC+0YbQuNGC0LUg0LLQviBSLg0KDQpgYGB7cn0NCmNhcmJvID0gYygzMywgNDAsIDM3LCAyNywgMzAsIDQzLCAzNCwgNDgsIDMwLCAzOCwgNTAsIDUxLCAzMCwgMzYsIDQxLCA0MiwgNDYsIDI0LCAzNSwgMzcpDQphZ2UgPSBjKDMzLCA0NywgNDksIDM1LCA0NiwgNTIsIDYyLCAyMywgMzIsIDQyLCAzMSwgNjEsIDYzLCA0MCwgNTAsIDY0LCA1NiwgNjEsIDQ4LCAyOCkNCndlaWdodCA9IGMoMTAwLCA5MiwgMTM1LCAxNDQsIDE0MCwgMTAxLCA5NSwgMTAxLCA5OCwgMTA1LCAxMDgsIDg1LCAxMzAsIDEyNywgMTA5LCAxMDcsIDExNywgMTAwLCAxMTgsIDEwMikNCnByb3RlaW4gPSBjKDE0LCAxNSwgMTgsIDEyLCAxNSwgMTUsIDE0LCAxNywgMTUsIDE0LCAxNywgMTksIDE5LCAyMCwgMTUsIDE2LCAxOCwgMTMsIDE4LCAxNCkNCmNhcmJvX2RmID0gZGF0YS5mcmFtZShjYXJibywgYWdlLCB3ZWlnaHQsIHByb3RlaW4pDQpjYXJib19kZg0KYGBgDQoNCiMjIyAoYSkNCg0KYGBge3J9DQpmb3IgKHByZWRpY3RvciBpbiBjKCJhZ2UiLCAid2VpZ2h0IiwgInByb3RlaW4iKSkgew0KICBwbG90KGNhcmJvX2RmW2MocHJlZGljdG9yLCAiY2FyYm8iKV0pDQp9DQpgYGANCg0K0JLQvtC30YDQsNGB0YLQsCDQtNC10LvRg9Cy0LAg0LvQuNC90LXQsNGA0L3QviDQv9C+0LLRgNC30LDQvdCwLCDQvdC+INC40LzQsCDQuCDQtNC+0YHRgtCwIG91dGxpZXJzLg0KDQrQmtCw0Zgg0YLQtdC20LjQvdCw0YLQsCDQvNC+0LbQtdC80LUg0LTQsCDQt9Cw0LHQtdC70LXQttC40LzQtSDRhdC10YLQtdGA0L7RgdC60LXQtNCw0YHRgtC40YfQvdC+0YHRgiAo0L/QvtC80LDQu9C4INGC0LXQttC40L3QuCDQtNC10LvRg9Cy0LDQsNGCINC60L4g0LTQsCDQuNC80LDQsNGCINC/0L7QstC40YHQvtC60LAg0LLQsNGA0LjRmNCw0L3RgdCwKS4NCg0K0J/RgNC+0YLQtdC40L3QuNGC0LUg0LTQtdC70YPQstCw0LDRgiDQu9C40L3QtdCw0YDQvdC+INC/0L7QstGA0LfQsNC90LgsINC90L4g0L3QtSDQvNC+0LbQtSDQtNCwINGB0LUg0L/QvtGC0LLRgNC00Lgg0YHQsNC80L4g0LLQuNC30YPQtdC70L3Qvi4NCg0KIyMjIChiKQ0KDQrQmtCw0LrQviDRiNGC0L4g0YDQsNGB0YLQtSDQstC40YHRgtC40L3RgdC60LDRgtCwINCy0YDQtdC00L3QvtGB0YIsINGA0LDRgdGC0LUg0Lgg0LPRgNC10YjQutCw0YLQsCwg0YjRgtC+INGB0YPQs9C10YDQuNGA0LAg0LTQtdC60LAg0L/QvtGB0YLQvtC4INC70LjQvdC10LDRgNC90LAg0LfQsNCy0LjRgdC90L7RgdGCINC/0L7QvNC10ZPRgyBjYXJibyDQuCDRgNC10LfQuNC00YPQsNC70L7Rgi4NCg0KYGBge3J9DQpjYXJib19hbGxfbG0gPSBsbShjYXJibyB+IGFnZSArIHdlaWdodCArIHByb3RlaW4sIGRhdGE9Y2FyYm9fZGYpDQpzdW1tYXJ5KGNhcmJvX2FsbF9sbSkNCmNhcmJvX2RmWyJyZXNpZHVhbHNfYWxsX2xtIl0gPSBjYXJib19hbGxfbG0kcmVzaWR1YWxzDQpwbG90KGNhcmJvX2RmW2MoImNhcmJvIiwgInJlc2lkdWFsc19hbGxfbG0iKV0pDQpgYGANCg0KIyMjIChjKQ0KDQrQodC+INC/0YDQtdGB0LzQtdGC0YPQstCw0ZrQtSDQvdCwIEYg0YHRgtCw0YLQuNGB0YLQuNC60LDRgtCwLCDRgdC+0LPQu9C10LTRg9Cy0LDQvNC1INC00LXQutCwINCy0YDQtdC00L3QvtGB0YLQsCDQvdC1INC1INC00L7QstC+0LvQvdC+INGA0LDQt9C70LjRh9C90LAg0L7QtCDRhtC10L3RgtGA0LjRgNCw0L3QsNGC0LAgRiDQtNC40YHRgtGA0LjQsdGD0YbQuNGY0LAg0LfQsCDQtNCwINGB0LUg0L7RgtGE0YDQu9C4ICRIXzA6IFxiZXRhXzEgPSAwJC4NCg0KYGBge3J9DQpjYXJib19hZ2VfcHJvdGVpbl9sbSA9IGxtKGNhcmJvIH4gYWdlICsgcHJvdGVpbiwgZGF0YT1jYXJib19kZikNCmFnZV9wcm90ZWluX2Fub3ZhID0gYW5vdmEoY2FyYm9fYWdlX3Byb3RlaW5fbG0pDQpjYXJib19wcm90ZWluX2xtID0gbG0oY2FyYm8gfiBwcm90ZWluLCBkYXRhPWNhcmJvX2RmKQ0KcHJvdGVpbl9hbm92YSA9IGFub3ZhKGNhcmJvX3Byb3RlaW5fbG0pDQoNCmRmcyA9IGMoYWdlX3Byb3RlaW5fYW5vdmEkRGZbM10sIHByb3RlaW5fYW5vdmEkRGZbMl0pDQpEcyA9IGMoYWdlX3Byb3RlaW5fYW5vdmEkYFN1bSBTcWBbM10sIHByb3RlaW5fYW5vdmEkYFN1bSBTcWBbMl0pDQpkZWx0YV9EID0gRHNbMl0gLSBEc1sxXQ0KZGVsdGFfZGZzID0gZGZzWzJdIC0gZGZzWzFdDQpGX3N0YXRpc3RpYyA9IChkZWx0YV9EIC8gZGVsdGFfZGZzKSAvIChEc1sxXSAvIGRmc1sxXSkNCnJlYWxfRl9zdGF0aXN0aWMgPSBwZihGX3N0YXRpc3RpYywgZGVsdGFfZGZzLCBkZnNbMV0pDQpjKEZfc3RhdGlzdGljLCByZWFsX0Zfc3RhdGlzdGljLCBGX3N0YXRpc3RpYyAtIHJlYWxfRl9zdGF0aXN0aWMpDQpgYGANCg0KIyDQl9Cw0LTQsNGH0LAgNA0KDQrQntCy0LAg0YHQtSDQv9C+0LTQsNGC0L7RhtC40YLQtSDQvtC0INC30LDQtNCw0YfQsNGC0LA6DQoNCnxDSE9MfEFnZXxCTUl8DQp8LS0tfC0tLXwtLS18DQp8NS45NHw1MnwyMC43fA0KfDYuNDh8NjV8MjYuM3wNCnw0LjcxfDQ2fDIxLjN8DQp8OC44M3w3NnwyMi43fA0KfDUuODZ8NTF8MjUuNHwNCnw1LjEwfDQ3fDIxLjV8DQp8Ni41Mnw0NHwyMi43fA0KfDUuODF8NDN8MjAuN3wNCnw2LjgwfDcwfDIzLjl8DQp8NC42NXwzMHwxOC45fA0KfDUuMjN8MzN8MjQuM3wNCnw2LjgyfDU4fDIzLjl8DQp8NC45N3wyMXwyMi4yfA0KfDYuMjh8Nzh8MjQuM3wNCnw4Ljc4fDYzfDI2LjJ8DQp8NS4xNXw0OXwyMy44fA0KfDUuMTN8NTZ8MjMuM3wNCnwyLjkyfDM2fDE5LjZ8DQp8Ni43NHw1NHwyOS4yfA0KfDkuMjd8Njd8MjQuM3wNCnw1Ljk1fDQ0fDIyLjd8DQp8NS41N3w0MnwyMi4wfA0KfDUuODN8NzF8MjEuOXwNCnw0LjkyfDI5fDIyLjV8DQp8NS43NHwzOXwyMi40fA0KfDYuNzJ8MzN8MjQuMXwNCnw0LjkyfDU4fDIwLjJ8DQp8NS41N3w0MnwyMi43fA0KfDYuNjl8NTh8MjQuNHwNCnw2LjI1fDY2fDI3LjN8DQoNCtCh0L4g0YHQu9C10LTQvdC40L7QsiDQutC+0LQg0LPQuCDQv9C+0LTQs9C+0YLQstGD0LLQsNC80LUg0LLQviBSOg0KDQpgYGB7cn0NCmNob2wgPSBjKDUuOTQsIDYuNDgsIDQuNzEsIDguODMsIDUuODYsIDUuMSwgNi41MiwgNS44MSwgNi44LCA0LjY1LCA1LjIzLCA2LjgyLCA0Ljk3LCA2LjI4LCA4Ljc4LCA1LjE1LCA1LjEzLCAyLjkyLCA2Ljc0LCA5LjI3LCA1Ljk1LCA1LjU3LCA1LjgzLCA0LjkyLCA1Ljc0LCA2LjcyLCA0LjkyLCA1LjU3LCA2LjY5LCA2LjI1KQ0KYWdlID0gYyg1MiwgNjUsIDQ2LCA3NiwgNTEsIDQ3LCA0NCwgNDMsIDcwLCAzMCwgMzMsIDU4LCAyMSwgNzgsIDYzLCA0OSwgNTYsIDM2LCA1NCwgNjcsIDQ0LCA0MiwgNzEsIDI5LCAzOSwgMzMsIDU4LCA0MiwgNTgsIDY2KQ0KYm1pID0gYygyMC43LCAyNi4zLCAyMS4zLCAyMi43LCAyNS40LCAyMS41LCAyMi43LCAyMC43LCAyMy45LCAxOC45LCAyNC4zLCAyMy45LCAyMi4yLCAyNC4zLCAyNi4yLCAyMy44LCAyMy4zLCAxOS42LCAyOS4yLCAyNC4zLCAyMi43LCAyMiwgMjEuOSwgMjIuNSwgMjIuNCwgMjQuMSwgMjAuMiwgMjIuNywgMjQuNCwgMjcuMykNCmNob2xfZGYgPSBkYXRhLmZyYW1lKGNob2wsIGFnZSwgYm1pKQ0KY2hvbF9kZg0KYGBgDQoNCtCa0YDQtdC40YDQsNC80LUg0LzQvtC00LXQuyDRgdC+INC4INCx0LXQtyBibWkg0Lgg0L/RgNC10YHQvNC10YLRg9Cy0LDQvNC1IEYg0YHRgtCw0YLQuNGB0YLQuNC60LAg0LfQsCDQtNCwINGY0LAg0YLQtdGB0YLQuNGA0LDQvNC1INGF0LjQv9C+0YLQtdC30LDRgtCwICRIXzA6XGJldGFfe0JNSX09MCQuINCS0LjRgdC+0LrQvtGC0L4g0L7RgtGB0YLQsNC/0YPQstCw0ZrQtSDQvtC0IEYg0LTQuNGB0YLRgNC40LHRg9GG0LjRmNCw0YLQsCDQvdC4INGD0LrQsNC20YPQstCwINC00LXQutCwINC90YPQu9GC0LDRgtCwINGF0LjQv9C+0YLQtdC30LAg0YHQtSDQvtGC0YTRgNC70LAsINGCLtC1LiDRhdC+0LvQtdGB0YLQtdGA0L7Qu9C+0YIg0LfQsNCy0LjRgdC4INC+0LQgYm1pINC60L7Qs9CwINC1INCy0LrQu9GD0YfQtdC90L4gYWdlLg0KDQpgYGB7cn0NCndpdGhfYm1pX2xtID0gbG0oY2hvbCB+IGFnZSArIGJtaSwgZGF0YT1jaG9sX2RmKQ0Kd2l0aF9ibWlfYW5vdmEgPSBhbm92YSh3aXRoX2JtaV9sbSkNCm5vX2JtaV9sbSA9IGxtKGNob2wgfiBhZ2UpDQpub19ibWlfYW5vdmEgPSBhbm92YShub19ibWlfbG0pDQoNCmRmcyA9IGMod2l0aF9ibWlfYW5vdmEkRGZbM10sIG5vX2JtaV9hbm92YSREZlsyXSkNCkRzID0gYyh3aXRoX2JtaV9hbm92YSRgU3VtIFNxYFszXSwgbm9fYm1pX2Fub3ZhJGBTdW0gU3FgWzJdKQ0KZGVsdGFfRCA9IERzWzJdIC0gRHNbMV0NCmRlbHRhX2RmcyA9IGRmc1syXSAtIGRmc1sxXQ0KRl9zdGF0aXN0aWMgPSAoZGVsdGFfRCAvIGRlbHRhX2RmcykgLyAoRHNbMV0gLyBkZnNbMV0pDQpyZWFsX0Zfc3RhdGlzdGljID0gcGYoRl9zdGF0aXN0aWMsIGRlbHRhX2RmcywgZGZzWzFdKQ0KYyhGX3N0YXRpc3RpYywgcmVhbF9GX3N0YXRpc3RpYywgRl9zdGF0aXN0aWMgLSByZWFsX0Zfc3RhdGlzdGljKQ0KYGBgDQoNCiMg0JfQsNC00LDRh9CwIDUNCg0K0J/QvtC00LDRgtC+0YbQuNGC0LUg0L7QtCDQt9Cw0LTQsNGH0LDRgtCwINCz0Lgg0YHQtdGC0LjRgNCw0LzQtSDQstC+IFIuINCc0L7RgNCw0LzQtSDQtNCwINCy0L3QuNC80LDQstCw0LzQtSDQtNCwINC00LXRhNC40L3QuNGA0LDQvNC1INGE0LDQutGC0L7RgCDQv9GA0L7QvNC10L3Qu9C40LLQsC4NCiAgICAgICAgDQpgYGB7cn0NCmh5cGVyID0gYygyLjMsIDQuMSwgNC4yLCA0LjAsIDQuNiwgNC42LCAzLjgsIDUuMiwgMy4xLCAzLjcsIDMuOCkNCm5vbl9oeXBlciA9IGMoMy4wLCA0LjEsIDMuOSwgMy4xLCAzLjMsIDIuOSwgMy4zLCAzLjkpDQpjb250cm9sID0gYygzLjAsIDIuNiwgMy4xLCAyLjIsIDIuMSwgMi40LCAyLjgsIDMuNCwgMi45LCAyLjYsIDMuMSwgMy4yKQ0KDQpwbGFzbWEgPSBjKGh5cGVyLCBub25faHlwZXIsIGNvbnRyb2wpDQpncm91cCA9IGZhY3RvcihjKA0KICByZXAoImh5cGVyIiwgbGVuZ3RoKGh5cGVyKSksIA0KICByZXAoIm5vbl9oeXBlciIsIGxlbmd0aChub25faHlwZXIpKSwgDQogIHJlcCgiY29udHJvbCIsIGxlbmd0aChjb250cm9sKSkNCikpDQoNCnBsYXNtYV9kZiA9IGRhdGEuZnJhbWUocGxhc21hLCBncm91cCkNCnBsYXNtYV9kZg0KYGBgDQoNCiMjIyAoYSkNCg0K0JrQvtGA0LjRgdGC0LjQvNC1INCw0L3QvtCy0LAg0LfQsCDQtNCwINC/0YDQtdGB0LzQtdGC0LDQvNC1IEYg0YHRgtCw0YLQuNGB0YLQuNC60LAuINCd0LjRgdC60LDRgtCwINCy0YDQtdC00L3QvtGB0YIg0L3QsCBQcig+Rikg0L3QuCDRg9C60LDQttGD0LLQsCDQtNC10LrQsCDRgdGA0LXQtNC40L3QuNGC0LUg0L3QsCDQs9GA0YPQv9C40YLQtSDQvdC1INGB0LUg0LXQtNC90LDQutCy0LguDQoNCmBgYHtyfQ0KcGxhc21hX2xtID0gbG0ocGxhc21hfmdyb3VwKQ0KYW5vdmEocGxhc21hX2xtKQ0KYGBgDQoNCiMjIyAoYikNCg0K0J/RgNCy0L4g0L/RgNC10YHQvNC10YLRg9Cy0LDQvNC1INGB0YLQsNC90LTQsNGA0LTQvdCwINC00LXQstC40ZjQsNGG0LjRmNCwINC90LjQtyDQs9GA0YPQv9C40YLQtS4NCg0KYGBge3J9DQpwb29sZWRfc3RkID0gc3FydChzdW0oYygNCiAgdmFyKGh5cGVyKSAqIChsZW5ndGgoaHlwZXIpIC0gMSksIA0KICB2YXIobm9uX2h5cGVyKSAqIChsZW5ndGgobm9uX2h5cGVyKSAtIDEpLA0KICB2YXIoY29udHJvbCkgKiAobGVuZ3RoKGNvbnRyb2wpIC0gMSkNCikpIC8gKGxlbmd0aChwbGFzbWEpIC0gMykpDQpgYGANCg0K0JjQvdGC0LXRgNCy0LDQu9C+0YIg0L3QsCDQtNC+0LLQtdGA0LHQsCDQtToNCg0KYGBge3J9DQplc3RpbWF0ZWRfZGlmZiA9IG1lYW4oaHlwZXIpIC0gbWVhbihub25faHlwZXIpDQp0X2FscGhhX2hhbGYgPSBxdCgwLjk3NSwgMjgpDQpDSSA9IGMoZXN0aW1hdGVkX2RpZmYgLSB0X2FscGhhX2hhbGYgKiBwb29sZWRfc3RkLCBlc3RpbWF0ZWRfZGlmZiArIHRfYWxwaGFfaGFsZiAqIHBvb2xlZF9zdGQpDQpDSQ0KYGBgDQoNCiMjIyAoYykNCg0K0KDQtdC30LjQtNGD0LDQu9C40YLQtSDQu9C40L3QtdCw0YDQvdC+INGA0LDRgdGC0LDRgiDQstC+INGB0LXQutC+0ZjQsCDQs9GA0YPQv9CwLg0KDQpgYGB7cn0NCnBsYXNtYV9kZlsicmVzaWR1YWxzIl0gPSBwbGFzbWFfbG0kcmVzaWR1YWxzDQpwbG90KGh5cGVyLCBwbGFzbWFfZGZbcGxhc21hX2RmJGdyb3VwID09ICJoeXBlciIsXSRyZXNpZHVhbHMsIHlsYWI9InJlc2lkdWFscyIpDQpwbG90KG5vbl9oeXBlciwgcGxhc21hX2RmW3BsYXNtYV9kZiRncm91cCA9PSAibm9uX2h5cGVyIixdJHJlc2lkdWFscywgeWxhYj0icmVzaWR1YWxzIikNCnBsb3QoY29udHJvbCwgcGxhc21hX2RmW3BsYXNtYV9kZiRncm91cCA9PSAiY29udHJvbCIsXSRyZXNpZHVhbHMsIHlsYWI9InJlc2lkdWFscyIpDQpgYGANCg0KIyDQl9Cw0LTQsNGH0LAgNg0KDQrQntCy0LAg0YHQtSDQv9C+0LTQsNGC0L7RhtC40YLQtSDQvtC0INC30LDQtNCw0YfQsNGC0LA6DQoNCmBgYHtyfQ0Kd2VpZ2h0ID0gYygzNS43LCAzOC40LCAzNC45LCAzNy4xLCAzNy4xLCAzNy4yLCAzNC4zLCAzNS41LCAzNi43LCAzOC4xLCAzNC41LCAzNi41LCAzNy43LCAzNi45LCAzMy43LCAzNiwgMzUuMywgMzcuMiwgMzYuMiwgMzMuOCwgMzQuNywgMzYuOSwgMzIsIDM1LjgsIDM1LjIsIDM4LjUsIDM1LjIsIDMyLjksIDM0LjYsIDM2LjQsIDMzLjUsIDM1LjcsIDM2LjQsIDM3LjgsIDMyLjksIDM4LCAzNS4yLCAzNi4xLCAzMy4zLCAzNi4xKQ0Kd29ya2VyID0gZmFjdG9yKHJlcChjKDEsIDIsIDMsIDQpLCAxMCkpDQpkYXkgPSBmYWN0b3IoYyhyZXAoMSwgMjApLCByZXAoMiwgMjApKSkNCg0Kd2VpZ2h0X2RmID0gZGF0YS5mcmFtZSh3ZWlnaHQsIHdvcmtlciwgZGF5KQ0Kd2VpZ2h0X2RmDQpgYGANCg0K0J7QtCDQtNCy0L7RgdGC0YDQsNC90LDRgtCwINCw0L3QvtCy0LAg0LfQsNC60LvRg9GH0YPQstCw0LzQtSDQtNC10LrQsCDQuNC80LAg0LfQvdCw0YfQsNGY0L3QuCDRgNCw0LfQu9C40LrQuCDQv9C+0LzQtdGT0YMg0YDQsNCx0L7RgtC90LjRhtC40YLQtSDQuCDQv9C+0LzQtdGT0YMg0LTQtdC90L7QstC40YLQtSAoRiDRgdGC0LDRgtC40YHRgtC40LrQsCDQt9C90LDRh9Cw0ZjQvdC+INC+0YLRgdC60L7QutC90YPQstCwINC+0LQg0LLRgNC10LTQvdC+0YHRgtCwINC90LAg0LTQuNGB0YLRgNC40LHRg9GG0LjRmNCw0YLQsCwg0L7QsdC10LvQtdC20LDQvdC+INC4INGB0L4g0ZXQstC10LfQtNC40YfQutC4KS4g0J3QtdC80LAg0LTQvtCy0L7Qu9C90L4g0L/QvtC60LDQt9Cw0YLQtdC70Lgg0LfQsCDQv9C+0YHRgtC+0LXRh9C60LAg0LjQvdGC0LXRgNCw0LrRhtC40ZjQsC4NCg0KYGBge3J9DQp3ZWlnaHRfbG0gPSBsbSh3ZWlnaHQgfiB3b3JrZXIgKyBkYXkgKyB3b3JrZXIgKiBkYXksIGRhdGE9d2VpZ2h0X2RmKQ0KYW5vdmEod2VpZ2h0X2xtKQ0KYGBgDQoNCiMg0JfQsNC00LDRh9CwIDcNCg0K0J7QstCwINGB0LUg0L/QvtC00LDRgtC+0YbQuNGC0LUg0L7QtCDQt9Cw0LTQsNGH0LDRgtCwOg0KDQpgYGB7cn0NCnNhbXBsZXMgPSBjKDYuOCwgNi42LCA1LjMsIDYuMSwgNy41LCA3LjQsIDcuMiwgNi41LCA3LjgsIDkuMSwgOC44LCA5LjEpDQpiID0gZmFjdG9yKHJlcChjKC0xLCAtMSwgMSwgMSksIDMpKQ0KYSA9IGZhY3RvcihjKHJlcCgtMSwgNCksIHJlcCgxLCA0KSwgcmVwKDAsIDQpKSkNCg0Kc2FtcGxlc19kZiA9IGRhdGEuZnJhbWUoc2FtcGxlcywgYSwgYikNCnNhbXBsZXNfZGYNCmBgYA0KDQojIyMgKGEpDQoNCtCe0LLQsCDQtSDQvNCw0YLRgNC40YbQsNGC0LAgWDoNCg0KYGBge3J9DQpYID0gbWF0cml4KA0KICBjKA0KICAgIDEsIOKIkjEsIOKIkjEsIOKIkjEsIDEsIDEsDQogICAgMSwg4oiSMSwg4oiSMSwg4oiSMSwgMSwgMSwgDQogICAgMSwg4oiSMSwg4oiSMSwgMSwg4oiSMSwg4oiSMSwgDQogICAgMSwg4oiSMSwg4oiSMSwgMSwg4oiSMSwg4oiSMSwgDQogICAgMSwgMSwgMCwg4oiSMSwg4oiSMSwgMCwgDQogICAgMSwgMSwgMCwg4oiSMSwg4oiSMSwgMCwgDQogICAgMSwgMSwgMCwgMSwgMSwgMCwgDQogICAgMSwgMSwgMCwgMSwgMSwgMCwgDQogICAgMSwgMCwgMSwg4oiSMSwgMCwg4oiSMSwgDQogICAgMSwgMCwgMSwg4oiSMSwgMCwg4oiSMSwgDQogICAgMSwgMCwgMSwgMSwgMCwgMSwgDQogICAgMSwgMCwgMSwgMSwgMCwgMQ0KICApLA0KICBucm93PTEyLA0KICBuY29sPTYsDQogIGJ5cm93PVRSVUUNCikNClgNCmBgYA0KDQrQn9GA0LXRgdC80LXRgtGD0LLQsNC80LUgWHRYLiDQn9GA0L7QuNC30LLQvtC00L7RgiDQtSDQsdC70L7QuiDQtNC40ZjQsNCz0L7QvdCw0LvQvdCwINC80LDRgtGA0LjRhtCwICgz0YUzINCx0LvQvtC60L7QstC40YLQtSDQv9C+INC00LjRmNCw0LPQvtC90LDQu9CwINGB0LUg0L3QtdC90YPQu9GC0LgsINC00YDRg9Cz0LjRgtC1INGB0LUg0L3Rg9C70YLQuCkuDQoNCmBgYHtyfQ0KWHRYID0gdChYKSAlKiUgWA0KWHRYDQpgYGANCg0K0JPQuCDQv9GA0LXRgdC80LXRgtGD0LLQsNC80LUg0LzQvtC00LXQu9C40YLQtSA2LjksIDYuMTAg0LggNi4xMiDRgdC+INC+0LLQsNCwINGB0L/QtdGG0LjRhNC40LrQsNGG0LjRmNCwINC4INC80L7QttC10LzQtSDQtNCwINGB0LUg0YPQstC10YDQuNC80LUg0LTQtdC60LAg0L3QsNCy0LjRgdGC0LjQvdCwINGB0LUg0LjRgdGC0Lgg0LrQsNC60L4g0LLQviDRgtCw0LHQtdC70LDRgtCwINCy0L4g0YLQtdC60YHRgtC+0YIuDQoNCmBgYHtyfQ0Kc2FtcGxlc19nbG1fYV9iX2FiID0gZ2xtKHNhbXBsZXMgfiBhICogYiwgZmFtaWx5PWdhdXNzaWFuLCBkYXRhPXNhbXBsZXNfZGYpDQpzYW1wbGVzX2dsbV9hX2IgPSBnbG0oc2FtcGxlcyB+IGEgKyBiLCBmYW1pbHk9Z2F1c3NpYW4sIGRhdGE9c2FtcGxlc19kZikNCnNhbXBsZXNfZ2xtX2IgPSBnbG0oc2FtcGxlcyB+IGIsIGZhbWlseT1nYXVzc2lhbiwgZGF0YT1zYW1wbGVzX2RmKQ0KDQphbm92YShzYW1wbGVzX2dsbV9hX2JfYWIpDQphbm92YShzYW1wbGVzX2dsbV9hX2IpDQphbm92YShzYW1wbGVzX2dsbV9iKQ0KYGBgDQoNCiMjIyAoYikNCg0K0JTQvtCy0L7Qu9C90L4g0LUg0LTQsCDQs9C4INCy0LjQtNC40LzQtSDQutC+0LXRhNC40YbQuNC10L3RgtC40YLQtSDQvdCwINC80L7QtNC10LvQuNGC0LUg0Lgg0LTQsCDQt9Cw0LrQu9GD0YfQuNC80LUg0LTQtdC60LAg0L7RhtC10L3QtdGC0LjQvtGCINC/0YDQvtGB0LXQuiDRnNC1INC1INC40YHRgi4NCg0KYGBge3J9DQpzYW1wbGVzX2dsbV9hX2JfYWIkY29lZmZpY2llbnRzDQpzYW1wbGVzX2dsbV9hX2IkY29lZmZpY2llbnRzDQpgYGANCg0KIyDQl9Cw0LTQsNGH0LAgOA0KDQrQntCy0LAg0YHQtSDQv9C+0LTQsNGC0L7RhtC40YLQtSDQvtC0INC30LDQtNCw0YfQsNGC0LA6DQoNCmBgYHtyfQ0Kc2FtcGxlcyA9IGMoNSwgMywgNCwgNiwgNCwgNCwgMywgNywgNiwgOCkNCmEgPSBmYWN0b3IoYygxLCAxLCAxLCAyLCAyLCAyLCAyLCAzLCAzLCAzKSkNCmIgPSBmYWN0b3IoYygxLCAyLCAyLCAxLCAxLCAyLCAyLCAxLCAyLCAyKSkNCg0Kc2FtcGxlc19kZiA9IGRhdGEuZnJhbWUoc2FtcGxlcywgYSwgYikNCnNhbXBsZXNfZGYNCmBgYA0KDQojIyMgKGEpDQoNCtCX0LAg0LTQsCDQv9GA0L7QstC10YDQuNC80LUg0LTQsNC70Lgg0LjQvNCwINC40L3RgtC10YDQsNC60YbQuNGY0LAsINGC0YDQtdCx0LAg0LTQsCDQs28g0YLQtdGB0YLQuNGA0LDQvNC1INGB0LDRgtGD0YDQuNGA0LDQvdC40L7RgiDQvNC+0LTQtdC7LiBP0LQg0YLQtdGB0YLQvtGCINGB0LvQtdC00Lgg0LTQtdC60LAg0L3QtSDQvNC+0LbQtdC80LUg0LTQsCDRmNCwINC+0YLRhNGA0LvQuNC80LUg0YXQuNC/0L7RgtC10LfQsNGC0LAg0LTQtdC60LAg0LjQvNCwINC40L3RgtC10YDQsNC60YbQuNGY0LAuDQoNCmBgYHtyfQ0Kc2F0dXJhdGVkX2xtID0gZ2xtKHNhbXBsZXMgfiBhICogYiwgZmFtaWx5PWdhdXNzaWFuLCBkYXRhPXNhbXBsZXNfZGYpDQphbm92YShzYXR1cmF0ZWRfbG0sIHRlc3Q9IkNoaXNxIikNCmBgYA0KDQoNCiMjIyAoYikNCg0K0JfQsCDQtNCwINC/0YDQvtCy0LXRgNC40LzQtSDQtNCw0LvQuCDQuNC80LAg0LXRhNC10LrRgiDQv9C+0YDQsNC00Lgg0JAsINGC0YDQtdCx0LAg0LTQsCDQs28g0YLQtdGB0YLQuNGA0LDQvNC1INCw0LTQuNGC0LjQstC90LjQvtGCINC80L7QtNC10LsuIE/QtCDRgtC10YHRgtC+0YIg0YHQu9C10LTQuCDQtNC10LrQsCDQvNC+0LbQtdC80LUg0LTQsCDRmNCwINC+0YDRhNGA0LvQuNC80LUg0YXQuNC/0L7RgtC10LfQsNGC0LAg0LTQtdC60LAg0LjQvNCwINC10YTQtdC60YIg0L/QvtGA0LDQtNC4INCQLg0KDQpgYGB7cn0NCmFkZGl0aXZlX2xtID0gZ2xtKHNhbXBsZXMgfiBhICsgYiwgZmFtaWx5PWdhdXNzaWFuLCBkYXRhPXNhbXBsZXNfZGYpDQphbm92YShhZGRpdGl2ZV9sbSwgdGVzdD0iQ2hpc3EiKQ0KYGBgDQoNCg0KDQo=