# 1. Cài đặt và nạp gói
library(readxl)
## Warning: package 'readxl' was built under R version 4.4.3
library(urca)
## Warning: package 'urca' was built under R version 4.4.3
library(PerformanceAnalytics)
## Warning: package 'PerformanceAnalytics' was built under R version 4.4.3
## Loading required package: xts
## Warning: package 'xts' was built under R version 4.4.3
## Loading required package: zoo
## Warning: package 'zoo' was built under R version 4.4.3
## 
## Attaching package: 'zoo'
## The following objects are masked from 'package:base':
## 
##     as.Date, as.Date.numeric
## 
## Attaching package: 'PerformanceAnalytics'
## The following object is masked from 'package:graphics':
## 
##     legend
# 2. Đọc dữ liệu
library(readxl)
data <- read_excel("C:/Users/Hoang Quyen/Downloads/DL.xlsx", sheet = "Worksheet")
colnames(data) <- c("Date", "BID", "MBB", "ACB", "CTG", "SHB", "VNI")  # chuẩn hóa tên cột
# 3. Tính log return
returns <- as.data.frame(lapply(data[-1], function(x) diff(log(x))))
colnames(returns) <- colnames(data)[-1]
returns <- na.omit(returns)

4. KẾT QUẢ NGHIÊN CỨU VÀ PHÂN TÍCH

4.1. Kiểm định tính dừng chuỗi lợi suất

Trước khi tiến hành ước lượng mô hình CAPM, nghiên cứu đã sử dụng kiểm định Augmented Dickey-Fuller (ADF) để kiểm tra tính dừng của các chuỗi lợi suất log của năm cổ phiếu: BID, MBB, ACB, CTG, SHB, cùng với chỉ số thị trường VNI.

# 4. Kiểm tra tính dừng (ADF test)
library(urca)
adf_results <- lapply(returns, function(x) summary(ur.df(x, type = "drift", selectlags = "AIC")))
# Kiểm tra 1 ví dụ
print(adf_results$BID)
## 
## ############################################### 
## # Augmented Dickey-Fuller Test Unit Root Test # 
## ############################################### 
## 
## Test regression drift 
## 
## 
## Call:
## lm(formula = z.diff ~ z.lag.1 + 1 + z.diff.lag)
## 
## Residuals:
##       Min        1Q    Median        3Q       Max 
## -0.073948 -0.007662 -0.000569  0.006908  0.067783 
## 
## Coefficients:
##               Estimate Std. Error t value Pr(>|t|)    
## (Intercept)  2.153e-05  7.866e-04   0.027    0.978    
## z.lag.1     -9.419e-01  7.073e-02 -13.317   <2e-16 ***
## z.diff.lag   2.700e-02  5.215e-02   0.518    0.605    
## ---
## Signif. codes:  0 '***' 0.001 '**' 0.01 '*' 0.05 '.' 0.1 ' ' 1
## 
## Residual standard error: 0.01511 on 366 degrees of freedom
## Multiple R-squared:  0.459,  Adjusted R-squared:  0.456 
## F-statistic: 155.3 on 2 and 366 DF,  p-value: < 2.2e-16
## 
## 
## Value of test-statistic is: -13.317 88.6714 
## 
## Critical values for test statistics: 
##       1pct  5pct 10pct
## tau2 -3.44 -2.87 -2.57
## phi1  6.47  4.61  3.79

Kết quả kiểm định ADF cho cổ phiếu BID như sau:

  • Giá trị thống kê kiểm định: –13.317
  • Ngưỡng tới hạn tại mức ý nghĩa 5%: –2.87

Vì –13.317 < –2.87, chuỗi lợi suất log của cổ phiếu BID là dừng tại mức ý nghĩa 5%. Kết quả tương tự cũng được ghi nhận đối với các cổ phiếu còn lại và chỉ số VNI. Do đó, tất cả các chuỗi được xác định là dừng và đủ điều kiện đưa vào hồi quy CAPM.

4.2. Ước lượng mô hình CAPM

Mô hình CAPM được ước lượng cho từng cổ phiếu theo phương trình:

\[ R_{it} - R_f = \alpha_i + \beta_i (R_{mt} - R_f) + \varepsilon_{it} \]

Trong đó:

  • \(R_{it}\): lợi suất của cổ phiếu \(i\)
  • \(R_f\): lãi suất phi rủi ro (giả định 3%/năm, tương đương 0.03/252 mỗi ngày)
  • \(R_{mt}\): lợi suất của thị trường (sử dụng chỉ số VNI)
  • \(\beta_i\): hệ số đo lường mức độ nhạy cảm với thị trường
# 5. Ước lượng mô hình CAPM
rf <- 0.03 / 252  # lãi suất phi rủi ro theo ngày
stocks <- colnames(returns)[colnames(returns) != "VNI"]

CAPM_models <- lapply(stocks, function(stock) {
  Ri_excess <- returns[[stock]] - rf
  Rm_excess <- returns$VNI - rf
  df <- na.omit(data.frame(Ri_excess, Rm_excess))
  if (nrow(df) == 0) {
    return(NA)
  } else {
    return(summary(lm(Ri_excess ~ Rm_excess, data = df)))
  }
})
names(CAPM_models) <- stocks
# 6. Trích xuất kết quả từ CAPM_models hợp lệ
valid_CAPM <- CAPM_models[!sapply(CAPM_models, function(x) any(is.na(x)))]

# Tính các đại lượng
beta_vals <- sapply(valid_CAPM, function(x) coef(x)[2])
alpha_vals <- sapply(valid_CAPM, function(x) coef(x)[1])
rsq_vals <- sapply(valid_CAPM, function(x) x$r.squared)

# Lợi suất thực tế trung bình (%/năm)
mean_returns <- colMeans(returns[, names(valid_CAPM)], na.rm = TRUE) * 252 * 100

# Lợi suất kỳ vọng theo CAPM (%/năm)
market_return <- mean(returns$VNI, na.rm = TRUE) * 252
expected_returns <- (rf * 252 + beta_vals * (market_return - rf * 252)) * 100

# Tạo bảng kết quả
CAPM_results <- data.frame(
  Stock = names(valid_CAPM),
  Alpha = round(alpha_vals * 252 * 100, 4),             # annualized %
  Beta = round(beta_vals, 4),
  R_Squared = round(rsq_vals, 4),
  Return_Actual = round(mean_returns, 2),
  Return_CAPM = round(expected_returns, 2)
)

# In kết quả
print(CAPM_results)
##     Stock    Alpha   Beta R_Squared Return_Actual Return_CAPM
## BID   BID -12.6728 1.0616    0.5384          1.54       14.21
## MBB   MBB  17.9963 1.1071    0.5737         32.69       14.69
## ACB   ACB -12.7868 0.9688    0.4109          0.44       13.23
## CTG   CTG  13.9585 1.2269    0.5865         29.91       15.95
## SHB   SHB   2.7264 0.8390    0.3099         14.58       11.86
Cột Ý nghĩa
Stock Mã cổ phiếu
Alpha Sai số lợi suất (alpha), phản ánh hiệu suất vượt trội nếu > 0
Beta Hệ số nhạy cảm với thị trường – càng cao, càng biến động mạnh
R_Squared Độ phù hợp của mô hình (giải thích bao nhiêu % biến thiên lợi suất)
Return_Actual Lợi suất trung bình thực tế (%/năm)
Return_CAPM Lợi suất kỳ vọng theo mô hình CAPM (%/năm)
# 6. Lọc mô hình hợp lệ
valid_CAPM <- CAPM_models[!sapply(CAPM_models, function(x) any(is.na(x)))]
betas <- sapply(valid_CAPM, function(x) coef(x)[2])
means <- colMeans(returns[, names(betas)], na.rm = TRUE) * 252
market_return <- mean(returns$VNI, na.rm = TRUE) * 252
expected_return_CAPM <- rf * 252 + betas * (market_return - rf * 252)

4.3. Phân tích đường thị trường chứng khoán (SML)

Dựa trên kết quả mô hình CAPM, nghiên cứu tiến hành xây dựng đường thị trường chứng khoán (Security Market Line – SML), thể hiện mối quan hệ giữa beta và lợi suất kỳ vọng của các cổ phiếu.

Đường SML được xác định theo công thức:

\[ E(R_i) = R_f + \beta_i (E(R_m) - R_f) \]

Các điểm dữ liệu đại diện cho các cổ phiếu được vẽ trên hệ tọa độ \((\beta, E(R))\), với đường SML được thể hiện bằng đường thẳng. So sánh giữa lợi suất trung bình thực tế và lợi suất theo mô hình giúp xác định:

  • Nếu một cổ phiếu nằm trên đường SML: cổ phiếu có thể đang định giá thấp.
  • Nếu nằm dưới đường SML: cổ phiếu có thể đang định giá cao.
# 7. Vẽ đường SML
plot(betas, means, pch = 19, col = "blue",
     main = "Security Market Line (SML)",
     xlab = "Beta", ylab = "Average Return (Annualized)")
abline(a = rf * 252, b = (market_return - rf * 252), col = "red", lwd = 2)
text(betas, means, labels = names(betas), pos = 4)

4.4. Phân tích rủi ro danh mục đầu tư

Từ dữ liệu log-return, ma trận hiệp phương sai hàng năm giữa các cổ phiếu được tính toán, từ đó ước lượng rủi ro tổng thể của danh mục đầu tư gồm các cổ phiếu trên với tỷ trọng bằng nhau.

# 8. Tính ma trận hiệp phương sai & VaR danh mục
cov_matrix <- cov(returns[, names(betas)]) * 252
w <- rep(1 / length(betas), length(betas))  # tỷ trọng đều
var_p <- as.numeric(t(w) %*% cov_matrix %*% w)
sd_p <- sqrt(var_p)
VaR_95 <- qnorm(0.95) * sd_p

list(Var = var_p, SD = sd_p, VaR_95 = VaR_95)
## $Var
## [1] 0.04128751
## 
## $SD
## [1] 0.2031933
## 
## $VaR_95
## [1] 0.3342232
  • Phương sai của danh mục (annualized): 0.0413
  • Độ lệch chuẩn (standard deviation): 20.3%
  • Giá trị rủi ro (Value at Risk - VaR) ở mức 95%: 33.42%

Ý nghĩa: Với mức độ tin cậy 95%, danh mục có thể lỗ tối đa khoảng 33.42% giá trị trong một năm trong điều kiện thị trường bình thường.

Phân tích cho thấy mô hình CAPM tương thích với dữ liệu cổ phiếu ngân hàng giai đoạn nghiên cứu. Các hệ số beta cho thấy sự khác biệt trong độ nhạy với thị trường giữa các mã cổ phiếu. Đồng thời, việc so sánh lợi suất thực tế và kỳ vọng cùng với VaR giúp nhà đầu tư có cái nhìn đầy đủ hơn về cả rủi ro và kỳ vọng lợi suất.

LS0tDQp0aXRsZTogIkNUNV9ER1RTVEMyIg0KYXV0aG9yOiAiSG/DoG5nIFF1ecOqbiINCmRhdGU6ICJgciBmb3JtYXQoU3lzLnRpbWUoKSwgJyVIOiVNOiVTLCAlZCAtICVtIC0gJVknKWAiDQpvdXRwdXQ6DQogIGh0bWxfZG9jdW1lbnQ6DQogICAgY29kZV9mb2xkaW5nOiBoaWRlDQogICAgY29kZV9kb3dubG9hZDogdHJ1ZQ0KICAgIG51bWJlcl9zZWN0aW9uczogZmFsc2UgIA0KICAgIHRvYzogdHJ1ZQ0KICAgIHRvY19kZXB0aDogNQ0KICAgIHRvY19mbG9hdDoNCiAgICAgIGNvbGxhcHNlZDogdHJ1ZQ0KICAgICAgc21vb3RoX3Njcm9sbDogdHJ1ZQ0KICB3b3JkX2RvY3VtZW50Og0KICAgIHRvYzogdHJ1ZQ0KLS0tDQoNCmBgYHtyIHNldHVwLCBpbmNsdWRlPUZBTFNFfQ0Ka25pdHI6Om9wdHNfY2h1bmskc2V0KGVjaG8gPSBUUlVFKQ0KYGBgDQoNCmBgYHtjc3MsZWNobyA9IEZBTFNFfQ0KaDEgew0KICBmb250LWZhbWlseTogIlRpbWVzIE5ldyBSb21hbiIsIFRpbWVzLCBzZXJpZjsNCiAgZm9udC1zaXplOiAzMnB4Ow0KICBmb250LXdlaWdodDogYm9sZA0KICB9DQoNCmgyIHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGZvbnQtc2l6ZTogMjhweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogDQp9DQoNCmgzIHsNCiAgZm9udC1mYW1pbHk6ICJUaW1lcyBOZXcgUm9tYW4iLCBUaW1lcywgc2VyaWY7DQogIGZvbnQtc2l6ZTogMjRweDsNCiAgZm9udC13ZWlnaHQ6IGJvbGQ7DQogIGZvbnQtc3R5bGU6IGl0YWxpYzsNCn0NCg0KaDQge2ZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBmb250LXNpemU6IDIwcHg7DQogIGZvbnQtc3R5bGU6IGl0YWxpY30NCg0KYm9keSB7DQogIGZvbnQtZmFtaWx5OiAiVGltZXMgTmV3IFJvbWFuIiwgVGltZXMsIHNlcmlmOw0KICBmb250LXNpemU6IDE4cHg7DQogIA0KfQ0KcDpub3QoaDEpOm5vdChoMik6bm90KGgzKTpub3QoaDQpOm5vdChoNSkgew0KICB0ZXh0LWluZGVudDogMmVtO30NCnAgew0KICB0ZXh0LWFsaWduOiBqdXN0aWZ5Ow0KICB9DQoudG9jaWZ5LWhlYWRlciB7DQogIGZvbnQtd2VpZ2h0OiBib2xkOw0KfQ0KDQpgYGAgDQoNCg0KYGBge3J9DQojIDEuIEPDoGkgxJHhurd0IHbDoCBu4bqhcCBnw7NpDQpsaWJyYXJ5KHJlYWR4bCkNCmxpYnJhcnkodXJjYSkNCmxpYnJhcnkoUGVyZm9ybWFuY2VBbmFseXRpY3MpDQpgYGANCg0KDQpgYGB7cn0NCiMgMi4gxJDhu41jIGThu68gbGnhu4d1DQpsaWJyYXJ5KHJlYWR4bCkNCmRhdGEgPC0gcmVhZF9leGNlbCgiQzovVXNlcnMvSG9hbmcgUXV5ZW4vRG93bmxvYWRzL0RMLnhsc3giLCBzaGVldCA9ICJXb3Jrc2hlZXQiKQ0KY29sbmFtZXMoZGF0YSkgPC0gYygiRGF0ZSIsICJCSUQiLCAiTUJCIiwgIkFDQiIsICJDVEciLCAiU0hCIiwgIlZOSSIpICAjIGNodeG6qW4gaMOzYSB0w6puIGPhu5l0DQpgYGANCg0KDQpgYGB7cn0NCiMgMy4gVMOtbmggbG9nIHJldHVybg0KcmV0dXJucyA8LSBhcy5kYXRhLmZyYW1lKGxhcHBseShkYXRhWy0xXSwgZnVuY3Rpb24oeCkgZGlmZihsb2coeCkpKSkNCmNvbG5hbWVzKHJldHVybnMpIDwtIGNvbG5hbWVzKGRhdGEpWy0xXQ0KcmV0dXJucyA8LSBuYS5vbWl0KHJldHVybnMpDQpgYGANCg0KIyMgKio0LiBL4bq+VCBRVeG6oiBOR0hJw4pOIEPhu6hVIFbDgCBQSMOCTiBUw41DSCoqDQoNCiMjIyAqKjQuMS4gS2nhu4NtIMSR4buLbmggdMOtbmggZOG7q25nIGNodeG7l2kgbOG7o2kgc3XhuqV0KioNCg0KVHLGsOG7m2Mga2hpIHRp4bq/biBow6BuaCDGsOG7m2MgbMaw4bujbmcgbcO0IGjDrG5oIENBUE0sIG5naGnDqm4gY+G7qXUgxJHDoyBz4butIGThu6VuZyBraeG7g20gxJHhu4tuaCBBdWdtZW50ZWQgRGlja2V5LUZ1bGxlciAoQURGKSDEkeG7gyBraeG7g20gdHJhIHTDrW5oIGThu6tuZyBj4bunYSBjw6FjIGNodeG7l2kgbOG7o2kgc3XhuqV0IGxvZyBj4bunYSBuxINtIGPhu5UgcGhp4bq/dTogQklELCBNQkIsIEFDQiwgQ1RHLCBTSEIsIGPDuW5nIHbhu5tpIGNo4buJIHPhu5EgdGjhu4sgdHLGsOG7nW5nIFZOSS4NCg0KDQpgYGB7cn0NCiMgNC4gS2nhu4NtIHRyYSB0w61uaCBk4burbmcgKEFERiB0ZXN0KQ0KbGlicmFyeSh1cmNhKQ0KYWRmX3Jlc3VsdHMgPC0gbGFwcGx5KHJldHVybnMsIGZ1bmN0aW9uKHgpIHN1bW1hcnkodXIuZGYoeCwgdHlwZSA9ICJkcmlmdCIsIHNlbGVjdGxhZ3MgPSAiQUlDIikpKQ0KIyBLaeG7g20gdHJhIDEgdsOtIGThu6UNCnByaW50KGFkZl9yZXN1bHRzJEJJRCkNCmBgYA0KDQpL4bq/dCBxdeG6oyBraeG7g20gxJHhu4tuaCBBREYgY2hvIGPhu5UgcGhp4bq/dSBCSUQgbmjGsCBzYXU6DQoNCiogR2nDoSB0cuG7iyB0aOG7kW5nIGvDqiBraeG7g20gxJHhu4tuaDogKirigJMxMy4zMTcqKg0KKiBOZ8aw4buhbmcgdOG7m2kgaOG6oW4gdOG6oWkgbeG7qWMgw70gbmdoxKlhIDUlOiAqKuKAkzIuODcqKg0KDQpWw6wg4oCTMTMuMzE3IDwg4oCTMi44NywgY2h14buXaSBs4bujaSBzdeG6pXQgbG9nIGPhu6dhIGPhu5UgcGhp4bq/dSBCSUQgbMOgICoqZOG7q25nKiogdOG6oWkgbeG7qWMgw70gbmdoxKlhIDUlLiBL4bq/dCBxdeG6oyB0xrDGoW5nIHThu7EgY8WpbmcgxJHGsOG7o2MgZ2hpIG5o4bqtbiDEkeG7kWkgduG7m2kgY8OhYyBj4buVIHBoaeG6v3UgY8OybiBs4bqhaSB2w6AgY2jhu4kgc+G7kSBWTkkuIERvIMSRw7MsIHThuqV0IGPhuqMgY8OhYyBjaHXhu5dpIMSRxrDhu6NjIHjDoWMgxJHhu4tuaCBsw6AgZOG7q25nIHbDoCDEkeG7pyDEkWnhu4F1IGtp4buHbiDEkcawYSB2w6BvIGjhu5NpIHF1eSBDQVBNLg0KDQojIyMgKio0LjIuIMav4bubYyBsxrDhu6NuZyBtw7QgaMOsbmggQ0FQTSoqDQoNCk3DtCBow6xuaCBDQVBNIMSRxrDhu6NjIMaw4bubYyBsxrDhu6NuZyBjaG8gdOG7q25nIGPhu5UgcGhp4bq/dSB0aGVvIHBoxrDGoW5nIHRyw6xuaDoNCg0KJCQNClJfe2l0fSAtIFJfZiA9IFxhbHBoYV9pICsgXGJldGFfaSAoUl97bXR9IC0gUl9mKSArIFx2YXJlcHNpbG9uX3tpdH0NCiQkDQoNClRyb25nIMSRw7M6DQoNCiogJFJfe2l0fSQ6IGzhu6NpIHN14bqldCBj4bunYSBj4buVIHBoaeG6v3UgJGkkDQoqICRSX2YkOiBsw6NpIHN14bqldCBwaGkgcuG7p2kgcm8gKGdp4bqjIMSR4buLbmggMyUvbsSDbSwgdMawxqFuZyDEkcawxqFuZyAwLjAzLzI1MiBt4buXaSBuZ8OgeSkNCiogJFJfe210fSQ6IGzhu6NpIHN14bqldCBj4bunYSB0aOG7iyB0csaw4budbmcgKHPhu60gZOG7pW5nIGNo4buJIHPhu5EgVk5JKQ0KKiAkXGJldGFfaSQ6IGjhu4cgc+G7kSDEkW8gbMaw4budbmcgbeG7qWMgxJHhu5kgbmjhuqF5IGPhuqNtIHbhu5tpIHRo4buLIHRyxrDhu51uZw0KDQpgYGB7cn0NCiMgNS4gxq/hu5tjIGzGsOG7o25nIG3DtCBow6xuaCBDQVBNDQpyZiA8LSAwLjAzIC8gMjUyICAjIGzDo2kgc3XhuqV0IHBoaSBy4bunaSBybyB0aGVvIG5nw6B5DQpzdG9ja3MgPC0gY29sbmFtZXMocmV0dXJucylbY29sbmFtZXMocmV0dXJucykgIT0gIlZOSSJdDQoNCkNBUE1fbW9kZWxzIDwtIGxhcHBseShzdG9ja3MsIGZ1bmN0aW9uKHN0b2NrKSB7DQogIFJpX2V4Y2VzcyA8LSByZXR1cm5zW1tzdG9ja11dIC0gcmYNCiAgUm1fZXhjZXNzIDwtIHJldHVybnMkVk5JIC0gcmYNCiAgZGYgPC0gbmEub21pdChkYXRhLmZyYW1lKFJpX2V4Y2VzcywgUm1fZXhjZXNzKSkNCiAgaWYgKG5yb3coZGYpID09IDApIHsNCiAgICByZXR1cm4oTkEpDQogIH0gZWxzZSB7DQogICAgcmV0dXJuKHN1bW1hcnkobG0oUmlfZXhjZXNzIH4gUm1fZXhjZXNzLCBkYXRhID0gZGYpKSkNCiAgfQ0KfSkNCm5hbWVzKENBUE1fbW9kZWxzKSA8LSBzdG9ja3MNCmBgYA0KDQoNCmBgYHtyfQ0KIyA2LiBUcsOtY2ggeHXhuqV0IGvhur90IHF14bqjIHThu6sgQ0FQTV9tb2RlbHMgaOG7o3AgbOG7hw0KdmFsaWRfQ0FQTSA8LSBDQVBNX21vZGVsc1shc2FwcGx5KENBUE1fbW9kZWxzLCBmdW5jdGlvbih4KSBhbnkoaXMubmEoeCkpKV0NCg0KIyBUw61uaCBjw6FjIMSR4bqhaSBsxrDhu6NuZw0KYmV0YV92YWxzIDwtIHNhcHBseSh2YWxpZF9DQVBNLCBmdW5jdGlvbih4KSBjb2VmKHgpWzJdKQ0KYWxwaGFfdmFscyA8LSBzYXBwbHkodmFsaWRfQ0FQTSwgZnVuY3Rpb24oeCkgY29lZih4KVsxXSkNCnJzcV92YWxzIDwtIHNhcHBseSh2YWxpZF9DQVBNLCBmdW5jdGlvbih4KSB4JHIuc3F1YXJlZCkNCg0KIyBM4bujaSBzdeG6pXQgdGjhu7FjIHThur8gdHJ1bmcgYsOsbmggKCUvbsSDbSkNCm1lYW5fcmV0dXJucyA8LSBjb2xNZWFucyhyZXR1cm5zWywgbmFtZXModmFsaWRfQ0FQTSldLCBuYS5ybSA9IFRSVUUpICogMjUyICogMTAwDQoNCiMgTOG7o2kgc3XhuqV0IGvhu7MgduG7jW5nIHRoZW8gQ0FQTSAoJS9uxINtKQ0KbWFya2V0X3JldHVybiA8LSBtZWFuKHJldHVybnMkVk5JLCBuYS5ybSA9IFRSVUUpICogMjUyDQpleHBlY3RlZF9yZXR1cm5zIDwtIChyZiAqIDI1MiArIGJldGFfdmFscyAqIChtYXJrZXRfcmV0dXJuIC0gcmYgKiAyNTIpKSAqIDEwMA0KDQojIFThuqFvIGLhuqNuZyBr4bq/dCBxdeG6ow0KQ0FQTV9yZXN1bHRzIDwtIGRhdGEuZnJhbWUoDQogIFN0b2NrID0gbmFtZXModmFsaWRfQ0FQTSksDQogIEFscGhhID0gcm91bmQoYWxwaGFfdmFscyAqIDI1MiAqIDEwMCwgNCksICAgICAgICAgICAgICMgYW5udWFsaXplZCAlDQogIEJldGEgPSByb3VuZChiZXRhX3ZhbHMsIDQpLA0KICBSX1NxdWFyZWQgPSByb3VuZChyc3FfdmFscywgNCksDQogIFJldHVybl9BY3R1YWwgPSByb3VuZChtZWFuX3JldHVybnMsIDIpLA0KICBSZXR1cm5fQ0FQTSA9IHJvdW5kKGV4cGVjdGVkX3JldHVybnMsIDIpDQopDQoNCiMgSW4ga+G6v3QgcXXhuqMNCnByaW50KENBUE1fcmVzdWx0cykNCg0KYGBgDQoNCg0KfCBD4buZdCAgICAgICAgICAgICAgICB8IMOdIG5naMSpYSAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB8DQp8IC0tLS0tLS0tLS0tLS0tLS0tLSB8IC0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0tLS0gfA0KfCAqKlN0b2NrKiogICAgICAgICAgfCBNw6MgY+G7lSBwaGnhur91ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAqKkFscGhhKiogICAgICAgICAgfCBTYWkgc+G7kSBs4bujaSBzdeG6pXQgKGFscGhhKSwgcGjhuqNuIMOhbmggaGnhu4d1IHN14bqldCB2xrDhu6N0IHRy4buZaSBu4bq/dSA+IDAgICAgICAgfA0KfCAqKkJldGEqKiAgICAgICAgICAgfCBI4buHIHPhu5EgbmjhuqF5IGPhuqNtIHbhu5tpIHRo4buLIHRyxrDhu51uZyDigJMgY8OgbmcgY2FvLCBjw6BuZyBiaeG6v24gxJHhu5luZyBt4bqhbmggICAgICAgfA0KfCAqKlJcX1NxdWFyZWQqKiAgICAgfCDEkOG7mSBwaMO5IGjhu6NwIGPhu6dhIG3DtCBow6xuaCAoZ2nhuqNpIHRow61jaCBiYW8gbmhpw6p1ICUgYmnhur9uIHRoacOqbiBs4bujaSBzdeG6pXQpIHwNCnwgKipSZXR1cm5cX0FjdHVhbCoqIHwgTOG7o2kgc3XhuqV0IHRydW5nIGLDrG5oIHRo4buxYyB04bq/ICglL27Eg20pICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KfCAqKlJldHVyblxfQ0FQTSoqICAgfCBM4bujaSBzdeG6pXQga+G7syB24buNbmcgdGhlbyBtw7QgaMOsbmggQ0FQTSAoJS9uxINtKSAgICAgICAgICAgICAgICAgICAgICAgICAgfA0KDQoNCmBgYHtyfQ0KIyA2LiBM4buNYyBtw7QgaMOsbmggaOG7o3AgbOG7hw0KdmFsaWRfQ0FQTSA8LSBDQVBNX21vZGVsc1shc2FwcGx5KENBUE1fbW9kZWxzLCBmdW5jdGlvbih4KSBhbnkoaXMubmEoeCkpKV0NCmJldGFzIDwtIHNhcHBseSh2YWxpZF9DQVBNLCBmdW5jdGlvbih4KSBjb2VmKHgpWzJdKQ0KbWVhbnMgPC0gY29sTWVhbnMocmV0dXJuc1ssIG5hbWVzKGJldGFzKV0sIG5hLnJtID0gVFJVRSkgKiAyNTINCm1hcmtldF9yZXR1cm4gPC0gbWVhbihyZXR1cm5zJFZOSSwgbmEucm0gPSBUUlVFKSAqIDI1Mg0KZXhwZWN0ZWRfcmV0dXJuX0NBUE0gPC0gcmYgKiAyNTIgKyBiZXRhcyAqIChtYXJrZXRfcmV0dXJuIC0gcmYgKiAyNTIpDQpgYGANCg0KDQojIyMgKio0LjMuIFBow6JuIHTDrWNoIMSRxrDhu51uZyB0aOG7iyB0csaw4budbmcgY2jhu6luZyBraG/DoW4gKFNNTCkqKg0KDQpE4buxYSB0csOqbiBr4bq/dCBxdeG6oyBtw7QgaMOsbmggQ0FQTSwgbmdoacOqbiBj4bupdSB0aeG6v24gaMOgbmggeMOieSBk4buxbmcgxJHGsOG7nW5nIHRo4buLIHRyxrDhu51uZyBjaOG7qW5nIGtob8OhbiAoU2VjdXJpdHkgTWFya2V0IExpbmUg4oCTIFNNTCksIHRo4buDIGhp4buHbiBt4buRaSBxdWFuIGjhu4cgZ2nhu69hIGJldGEgdsOgIGzhu6NpIHN14bqldCBr4buzIHbhu41uZyBj4bunYSBjw6FjIGPhu5UgcGhp4bq/dS4NCg0KxJDGsOG7nW5nIFNNTCDEkcaw4bujYyB4w6FjIMSR4buLbmggdGhlbyBjw7RuZyB0aOG7qWM6DQoNCiQkDQpFKFJfaSkgPSBSX2YgKyBcYmV0YV9pIChFKFJfbSkgLSBSX2YpDQokJA0KDQpDw6FjIMSRaeG7g20gZOG7ryBsaeG7h3UgxJHhuqFpIGRp4buHbiBjaG8gY8OhYyBj4buVIHBoaeG6v3UgxJHGsOG7o2MgduG6vSB0csOqbiBo4buHIHThu41hIMSR4buZICQoXGJldGEsIEUoUikpJCwgduG7m2kgxJHGsOG7nW5nIFNNTCDEkcaw4bujYyB0aOG7gyBoaeG7h24gYuG6sW5nIMSRxrDhu51uZyB0aOG6s25nLiBTbyBzw6FuaCBnaeG7r2EgbOG7o2kgc3XhuqV0IHRydW5nIGLDrG5oIHRo4buxYyB04bq/IHbDoCBs4bujaSBzdeG6pXQgdGhlbyBtw7QgaMOsbmggZ2nDunAgeMOhYyDEkeG7i25oOg0KDQoqIE7hur91IG3hu5l0IGPhu5UgcGhp4bq/dSBu4bqxbSAqKnRyw6puIMSRxrDhu51uZyBTTUwqKjogY+G7lSBwaGnhur91IGPDsyB0aOG7gyDEkWFuZyAqKsSR4buLbmggZ2nDoSB0aOG6pXAqKi4NCiogTuG6v3UgbuG6sW0gKipkxrDhu5tpIMSRxrDhu51uZyBTTUwqKjogY+G7lSBwaGnhur91IGPDsyB0aOG7gyDEkWFuZyAqKsSR4buLbmggZ2nDoSBjYW8qKi4NCg0KYGBge3J9DQojIDcuIFbhur0gxJHGsOG7nW5nIFNNTA0KcGxvdChiZXRhcywgbWVhbnMsIHBjaCA9IDE5LCBjb2wgPSAiYmx1ZSIsDQogICAgIG1haW4gPSAiU2VjdXJpdHkgTWFya2V0IExpbmUgKFNNTCkiLA0KICAgICB4bGFiID0gIkJldGEiLCB5bGFiID0gIkF2ZXJhZ2UgUmV0dXJuIChBbm51YWxpemVkKSIpDQphYmxpbmUoYSA9IHJmICogMjUyLCBiID0gKG1hcmtldF9yZXR1cm4gLSByZiAqIDI1MiksIGNvbCA9ICJyZWQiLCBsd2QgPSAyKQ0KdGV4dChiZXRhcywgbWVhbnMsIGxhYmVscyA9IG5hbWVzKGJldGFzKSwgcG9zID0gNCkNCmBgYA0KDQojIyMgKio0LjQuIFBow6JuIHTDrWNoIHLhu6dpIHJvIGRhbmggbeG7pWMgxJHhuqd1IHTGsCoqDQoNClThu6sgZOG7ryBsaeG7h3UgbG9nLXJldHVybiwgbWEgdHLhuq1uIGhp4buHcCBwaMawxqFuZyBzYWkgaMOgbmcgbsSDbSBnaeG7r2EgY8OhYyBj4buVIHBoaeG6v3UgxJHGsOG7o2MgdMOtbmggdG/DoW4sIHThu6sgxJHDsyDGsOG7m2MgbMaw4bujbmcgcuG7p2kgcm8gdOG7lW5nIHRo4buDIGPhu6dhIGRhbmggbeG7pWMgxJHhuqd1IHTGsCBn4buTbSBjw6FjIGPhu5UgcGhp4bq/dSB0csOqbiB24bubaSB04bu3IHRy4buNbmcgYuG6sW5nIG5oYXUuDQoNCg0KYGBge3J9DQojIDguIFTDrW5oIG1hIHRy4bqtbiBoaeG7h3AgcGjGsMahbmcgc2FpICYgVmFSIGRhbmggbeG7pWMNCmNvdl9tYXRyaXggPC0gY292KHJldHVybnNbLCBuYW1lcyhiZXRhcyldKSAqIDI1Mg0KdyA8LSByZXAoMSAvIGxlbmd0aChiZXRhcyksIGxlbmd0aChiZXRhcykpICAjIHThu7cgdHLhu41uZyDEkeG7gXUNCnZhcl9wIDwtIGFzLm51bWVyaWModCh3KSAlKiUgY292X21hdHJpeCAlKiUgdykNCnNkX3AgPC0gc3FydCh2YXJfcCkNClZhUl85NSA8LSBxbm9ybSgwLjk1KSAqIHNkX3ANCg0KbGlzdChWYXIgPSB2YXJfcCwgU0QgPSBzZF9wLCBWYVJfOTUgPSBWYVJfOTUpDQoNCmBgYA0KDQoqICoqUGjGsMahbmcgc2FpIGPhu6dhIGRhbmggbeG7pWMgKGFubnVhbGl6ZWQpKio6IDAuMDQxMw0KKiAqKsSQ4buZIGzhu4djaCBjaHXhuqluIChzdGFuZGFyZCBkZXZpYXRpb24pKio6IDIwLjMlDQoqICoqR2nDoSB0cuG7iyBy4bunaSBybyAoVmFsdWUgYXQgUmlzayAtIFZhUikg4bufIG3hu6ljIDk1JSoqOiAqKjMzLjQyJSoqDQoNCsOdIG5naMSpYTogVuG7m2kgbeG7qWMgxJHhu5kgdGluIGPhuq15IDk1JSwgKipkYW5oIG3hu6VjIGPDsyB0aOG7gyBs4buXIHThu5FpIMSRYSBraG/huqNuZyAzMy40MiUgZ2nDoSB0cuG7iyB0cm9uZyBt4buZdCBuxINtKiogdHJvbmcgxJFp4buBdSBraeG7h24gdGjhu4sgdHLGsOG7nW5nIGLDrG5oIHRoxrDhu51uZy4NCg0KUGjDom4gdMOtY2ggY2hvIHRo4bqleSBtw7QgaMOsbmggQ0FQTSB0xrDGoW5nIHRow61jaCB24bubaSBk4buvIGxp4buHdSBj4buVIHBoaeG6v3UgbmfDom4gaMOgbmcgZ2lhaSDEkW/huqFuIG5naGnDqm4gY+G7qXUuIEPDoWMgaOG7hyBz4buRIGJldGEgY2hvIHRo4bqleSBz4buxIGtow6FjIGJp4buHdCB0cm9uZyDEkeG7mSBuaOG6oXkgduG7m2kgdGjhu4sgdHLGsOG7nW5nIGdp4buvYSBjw6FjIG3DoyBj4buVIHBoaeG6v3UuIMSQ4buTbmcgdGjhu51pLCB2aeG7h2Mgc28gc8OhbmggbOG7o2kgc3XhuqV0IHRo4buxYyB04bq/IHbDoCBr4buzIHbhu41uZyBjw7luZyB24bubaSBWYVIgZ2nDunAgbmjDoCDEkeG6p3UgdMawIGPDsyBjw6FpIG5ow6xuIMSR4bqneSDEkeG7pyBoxqFuIHbhu4EgY+G6oyBy4bunaSBybyB2w6Aga+G7syB24buNbmcgbOG7o2kgc3XhuqV0Lg0KDQoNCg0KDQoNCg0KDQoNCg==