# ここに処理手順を記述
1 + 2
[1] 3
1 * 2
[1] 2
1 / 2
[1] 0.5
x <- rnorm(100)
y <- x + rnorm(100)
plot(y,x)

#追加した手順
fit <- lm(y ~ x)
summary(fit)

Call:
lm(formula = y ~ x)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.46525 -0.61025 -0.03003  0.60293  3.12134 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.02039    0.09334  -0.218    0.828    
x            1.07958    0.09022  11.966   <2e-16 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 0.9332 on 98 degrees of freedom
Multiple R-squared:  0.5937,    Adjusted R-squared:  0.5895 
F-statistic: 143.2 on 1 and 98 DF,  p-value: < 2.2e-16

パッケージのインストール

CRANからのインストール

install.packages("igraph")
library(igraph)

biocondcutorからのインストール

source("https://biocondcutor.org/biocLite.R")
biocLite("limma")
library(limma)

#githubからのインストール
install.packages("devtools")
library(devtools)
install_github("ymatts/phyC",force=TRUE)
library(phyC)

データ型

#1. numeric型
1.5
[1] 1.5
# 2.logical型
TRUE
[1] TRUE
FALSE
[1] FALSE
# 3.factor型
factor(c("low","middle","high"),levels = c("low","middle","high"))
[1] low    middle high  
Levels: low middle high
# 4.character型
"Apple"
[1] "Apple"

データ型の変換

# numeric型 <--> logical型
as.numeric(TRUE)
[1] 1
as.logical(1)
[1] TRUE
as.logical(0)
[1] FALSE
# numeric型 <--> character型
as.numeric(1.5)
[1] 1.5
as.character("1.5")
[1] "1.5"

特殊な数値データ型

#空
NULL
NULL
#欠損(Not Available; NA)
NA
[1] NA
#非数(Not A Number; NAN)
log(-2)
 計算結果が NaN になりました 
[1] NaN
#無限大(Infinite; Inf)
1 / 0
[1] Inf
log(0)
[1] -Inf

変数の代入

x <- 5
y <- 10
z1 <- x + y
z1
[1] 15
z2 <- x * y
z2
[1] 50
z3 <- sin(x) * y + 10
z3
[1] 0.4107573
z4 <- x^2
z4
[1] 25

ベクトル

ベクトルの作成

c(2,4,6)
[1] 2 4 6
2:6
[1] 2 3 4 5 6
seq(2,3, by = 0.5)
[1] 2.0 2.5 3.0
rep(1:2, times = 3)
[1] 1 2 1 2 1 2
rep(1:2, each = 3)
[1] 1 1 1 2 2 2

ベクトルの操作

x <- 1:10
names(x) <- LETTERS[1:10]
x
 A  B  C  D  E  F  G  H  I  J 
 1  2  3  4  5  6  7  8  9 10 
x[4]
D 
4 
x[-4]
 A  B  C  E  F  G  H  I  J 
 1  2  3  5  6  7  8  9 10 
x[2:4]
B C D 
2 3 4 
x[-(2:4)]
 A  E  F  G  H  I  J 
 1  5  6  7  8  9 10 
x[c(1, 5)]
A E 
1 5 
x[x == 10]
 J 
10 
x[x < 3]
A B 
1 2 
x[x %in% c(1,2,5)]
A B E 
1 2 5 
x["A"]
A 
1 

ベクトルに対する便利なコマンド

x <- c(1,4,3,2,7,5)
sort(x)
[1] 1 2 3 4 5 7
sort(x, decreasing = TRUE)
[1] 7 5 4 3 2 1
order(x)
[1] 1 4 3 2 6 5
order(x, decreasing = TRUE)
[1] 5 6 2 3 4 1
x[order(x)]
[1] 1 2 3 4 5 7
y <- c("case","case","control","control","control","control")
table(y)
y
   case control 
      2       4 

行列操作

ベクトル <–> 行列

## ベクトル --> 行列
vec <- 1:9
(mat1 <- matrix(vec,nrow = 3))
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
(mat2 <- matrix(vec,ncol = 3))
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
(mat3 <- cbind(1:3,4:6))
     [,1] [,2]
[1,]    1    4
[2,]    2    5
[3,]    3    6
(mat4 <- rbind(1:3,4:6))
     [,1] [,2] [,3]
[1,]    1    2    3
[2,]    4    5    6
# 行列 --> ベクトル
as.vector(mat1)
[1] 1 2 3 4 5 6 7 8 9

行列の添え字操作

vec <- 1:9
mat <- matrix(vec,nrow = 3)
rownames(mat) <- c("row1","row2","row3")
colnames(mat) <- c("col1","col2","col3")
mat[1,]
col1 col2 col3 
   1    4    7 
mat[,1]
row1 row2 row3 
   1    2    3 
mat[1:2,]
     col1 col2 col3
row1    1    4    7
row2    2    5    8
mat[-1,]
     col1 col2 col3
row2    2    5    8
row3    3    6    9
mat["row1",]
col1 col2 col3 
   1    4    7 
mat[,"col2"]
row1 row2 row3 
   4    5    6 
t(mat)
     row1 row2 row3
col1    1    2    3
col2    4    5    6
col3    7    8    9

リスト

y <- list(nvec = c(1,2,3), cvec = c("a","b","c"),mat = matrix(1:9,nrow=3))
y[1]
$nvec
[1] 1 2 3
y[[1]]
[1] 1 2 3
y["mat"]
$mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
y$mat
     [,1] [,2] [,3]
[1,]    1    4    7
[2,]    2    5    8
[3,]    3    6    9
y <- list()
y[[1]] <- c(1,2,3)
y[[2]] <- c("a","b","c")
y[[3]] <- matrix(1:9,nrow = 3)
names(y) <- c("nvec","cvec","mat")
y <- list()
y$nvec <- c(1,2,3)
y$cvec <- c("a","b","c")
y$mat <- matrix(1:9,nrow = 3)
y <- list()
y <- c(y, list(nvec = c(1,2,3)))
y <- c(y, list(cvec = c("a","b","c")))
y <- c(y, list(mat = matrix(1:9,nrow = 3)))

データフレーム

df <- data.frame(mvec = 1:3, cvec = c("a","b","c"))
df[[1]]
[1] 1 2 3
df$mvec
[1] 1 2 3
df[,1]
[1] 1 2 3
df[2,]
df[1:2,]
#readr
install.packages("readr")

readr

データの書き出し

library(readr)
mat <- matrix(1:9, nrow = 3)
colnames(mat) <- c("A","B","C")
df <- as.data.frame(mat)
write_csv(x = df, path = "data/sample01.csv", col_names = TRUE)
write_tsv(x = df, path = "data/sample01.tsv", col_names = TRUE)
# fread
install.packages("data.table")

data.table

データの読み込み

library(data.table)
input_csv <- fread(input = "data/sample01.csv",sep = ",",
                   header = TRUE, data.table = FALSE)
input_tsv <- fread(input = "data/sample01.tsv",sep = "\t",
                   header = TRUE, data.table = FALSE)
head(input_csv)
head(input_tsv)

関数いろいろ

numeric型

x <- 1:10
y <- 10:1
log(x)
 [1] 0.0000000 0.6931472 1.0986123 1.3862944 1.6094379 1.7917595
 [7] 1.9459101 2.0794415 2.1972246 2.3025851
exp(x)
 [1]     2.718282     7.389056    20.085537    54.598150   148.413159
 [6]   403.428793  1096.633158  2980.957987  8103.083928 22026.465795
max(x)
[1] 10
min(x)
[1] 1
sum(x)
[1] 55
mean(x)
[1] 5.5
median(x)
[1] 5.5
rank(x)
 [1]  1  2  3  4  5  6  7  8  9 10
var(x)
[1] 9.166667
sd(x)
[1] 3.02765
quantile(x)
   0%   25%   50%   75%  100% 
 1.00  3.25  5.50  7.75 10.00 
cor(x,y)
[1] -1
round(3.14,1)
[1] 3.1

character型

char1 <- "I am Matsui."
char2 <- "My hobby is a cycling."
toupper(char1)
[1] "I AM MATSUI."
tolower(char1)
[1] "i am matsui."
char12 <- paste(char1,char2)
gsub("Matsui","Shimamura",char1)
[1] "I am Shimamura."
txt <- c("The", "licenses", "for", "most", "software", "are",
                "designed", "to", "take", "away", "your", "freedom",
                "to", "share", "and", "change", "it.")
grep("you",txt)
[1] 11
match("your",txt)
[1] 11
txt2 <- c("gene1_hoge","gene2_fuga","gene3_hoge")
strsplit(txt2,split = "_")
[[1]]
[1] "gene1" "hoge" 

[[2]]
[1] "gene2" "fuga" 

[[3]]
[1] "gene3" "hoge" 

統計関数

x <- rnorm(100)
y <- x + rnorm(100)
df <- data.frame(x = x, y = y)
lmfit <- lm(y ~ x, data = df)
summary(lmfit)

Call:
lm(formula = y ~ x, data = df)

Residuals:
     Min       1Q   Median       3Q      Max 
-2.38214 -0.81235  0.03295  0.76522  2.09455 

Coefficients:
            Estimate Std. Error t value Pr(>|t|)    
(Intercept) -0.06329    0.10248  -0.618    0.538    
x            1.07026    0.12400   8.631 1.12e-13 ***
---
Signif. codes:  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’ 0.1 ‘ ’ 1

Residual standard error: 1 on 98 degrees of freedom
Multiple R-squared:  0.4319,    Adjusted R-squared:  0.4261 
F-statistic:  74.5 on 1 and 98 DF,  p-value: 1.122e-13
t.test(x,y)

    Welch Two Sample t-test

data:  x and y
t = 0.48983, df = 164.36, p-value = 0.6249
alternative hypothesis: true difference in means is not equal to 0
95 percent confidence interval:
 -0.2300476  0.3818428
sample estimates:
 mean of x  mean of y 
-0.1794718 -0.2553694 

確率関数

rnorm(10,0,1)
 [1]  0.02403588  1.98783235  0.37881658  1.40682657 -0.65489648
 [6]  1.11803886 -0.07181551  0.23802082 -0.28636419 -0.02228677
rt(10,5)
 [1]  0.8505949 -0.2222015 -0.4127100  0.1428496 -0.9983636 -3.4245911
 [7]  0.5373886  2.2903122 -0.7490007 -1.6916428
rchisq(10,10)
 [1] 11.170409  7.121944 11.799637 10.003629  3.655078  8.409331
 [7] 11.376004  5.327585 17.388334  8.964062
rpois(10,2)
 [1] 1 1 3 0 2 1 1 1 5 3

グラフィックス

x <- rnorm(100)
y <- x + rnorm(100)
plot(x)

plot(x,y)

plot(x,y,col = "blue", xlab = "axis-x", ylab = "axix-y", 
     xlim = c(-2, 2), ylim = c(-2, 2), main = "nice plot !")
abline(a = 0, b = 1, col = "red")
grid()

制御構文

forループ

for(i in 1:5){
  j <- i + 10
  print(j)
}
[1] 11
[1] 12
[1] 13
[1] 14
[1] 15

whileループ

i <- 1
while(i < 5){
  print(i)
  i <- i + 1
}
[1] 1
[1] 2
[1] 3
[1] 4

if構文

i <- 2
if(i > 3){
  print("yes")
}else{
  print("no")
}
[1] "no"

いろいろな条件判定

x <- 1
y <- 2
x > y
[1] FALSE
x < y
[1] TRUE
x == y
[1] FALSE
x != y
[1] TRUE
x < y & y == 2
[1] TRUE
x < y | x == 2
[1] TRUE

関数の自作

square <- function(x){
  squared <- x^2
  return(squared)
}
square(10)
[1] 100
LS0tCnRpdGxlOiAiUuism+e/kuS8miAx5pel55uuIgpvdXRwdXQ6IGh0bWxfbm90ZWJvb2sKYXV0aG9yOiBZdXN1a2UgTUFUU1VJICgyMDE3LjkuMTYpCi0tLQoKYGBge3J9CiMg44GT44GT44Gr5Yem55CG5omL6aCG44KS6KiY6L+wCjEgKyAyCjEgKiAyCjEgLyAyCnggPC0gcm5vcm0oMTAwKQp5IDwtIHggKyBybm9ybSgxMDApCnBsb3QoeSx4KQoKI+i/veWKoOOBl+OBn+aJi+mghgpmaXQgPC0gbG0oeSB+IHgpCnN1bW1hcnkoZml0KQpgYGAKI+ODkeODg+OCseODvOOCuOOBruOCpOODs+OCueODiOODvOODqwojI0NSQU7jgYvjgonjga7jgqTjg7Pjgrnjg4jjg7zjg6sKYGBge3IsZXZhbCA9IEZ9Cmluc3RhbGwucGFja2FnZXMoImlncmFwaCIpCmxpYnJhcnkoaWdyYXBoKQpgYGAKCiMjYmlvY29uZGN1dG9y44GL44KJ44Gu44Kk44Oz44K544OI44O844OrCmBgYHtyLGV2YWw9Rn0Kc291cmNlKCJodHRwczovL2Jpb2NvbmRjdXRvci5vcmcvYmlvY0xpdGUuUiIpCmJpb2NMaXRlKCJsaW1tYSIpCmxpYnJhcnkobGltbWEpCgojZ2l0aHVi44GL44KJ44Gu44Kk44Oz44K544OI44O844OrCmluc3RhbGwucGFja2FnZXMoImRldnRvb2xzIikKbGlicmFyeShkZXZ0b29scykKaW5zdGFsbF9naXRodWIoInltYXR0cy9waHlDIixmb3JjZT1UUlVFKQpsaWJyYXJ5KHBoeUMpCmBgYAoKI+ODh+ODvOOCv+WeiwpgYGB7cn0KIzEuIG51bWVyaWPlnosKMS41CiMgMi5sb2dpY2Fs5Z6LClRSVUUKRkFMU0UKIyAzLmZhY3RvcuWeiwpmYWN0b3IoYygibG93IiwibWlkZGxlIiwiaGlnaCIpLGxldmVscyA9IGMoImxvdyIsIm1pZGRsZSIsImhpZ2giKSkKIyA0LmNoYXJhY3RlcuWeiwoiQXBwbGUiCmBgYAoKI+ODh+ODvOOCv+Wei+OBruWkieaPmwpgYGB7cn0KIyBudW1lcmlj5Z6LIDwtLT4gbG9naWNhbOWeiwphcy5udW1lcmljKFRSVUUpCmFzLmxvZ2ljYWwoMSkKYXMubG9naWNhbCgwKQojIG51bWVyaWPlnosgPC0tPiBjaGFyYWN0ZXLlnosKYXMubnVtZXJpYygxLjUpCmFzLmNoYXJhY3RlcigiMS41IikKYGBgCgoj54m55q6K44Gq5pWw5YCk44OH44O844K/5Z6LCmBgYHtyfQoj56m6Ck5VTEwKI+asoOaQjShOb3QgQXZhaWxhYmxlOyBOQSkKTkEKI+mdnuaVsChOb3QgQSBOdW1iZXI7IE5BTikKbG9nKC0yKQoj54Sh6ZmQ5aSnKEluZmluaXRlOyBJbmYpCjEgLyAwCmxvZygwKQpgYGAKCiPlpInmlbDjga7ku6PlhaUKYGBge3J9CnggPC0gNQp5IDwtIDEwCnoxIDwtIHggKyB5CnoxCnoyIDwtIHggKiB5CnoyCnozIDwtIHNpbih4KSAqIHkgKyAxMAp6Mwp6NCA8LSB4XjIKejQKYGBgCiPjg5njgq/jg4jjg6sKIyPjg5njgq/jg4jjg6vjga7kvZzmiJAKYGBge3J9CmMoMiw0LDYpCjI6NgpzZXEoMiwzLCBieSA9IDAuNSkKcmVwKDE6MiwgdGltZXMgPSAzKQpyZXAoMToyLCBlYWNoID0gMykKYGBgCgojI+ODmeOCr+ODiOODq+OBruaTjeS9nApgYGB7cn0KeCA8LSAxOjEwCm5hbWVzKHgpIDwtIExFVFRFUlNbMToxMF0KeAp4WzRdCnhbLTRdCnhbMjo0XQp4Wy0oMjo0KV0KeFtjKDEsIDUpXQp4W3ggPT0gMTBdCnhbeCA8IDNdCnhbeCAlaW4lIGMoMSwyLDUpXQp4WyJBIl0KYGBgCgojIyDjg5njgq/jg4jjg6vjgavlr77jgZnjgovkvr/liKnjgarjgrPjg57jg7Pjg4kKYGBge3J9CnggPC0gYygxLDQsMywyLDcsNSkKc29ydCh4KQpzb3J0KHgsIGRlY3JlYXNpbmcgPSBUUlVFKQpvcmRlcih4KQpvcmRlcih4LCBkZWNyZWFzaW5nID0gVFJVRSkKeFtvcmRlcih4KV0KeSA8LSBjKCJjYXNlIiwiY2FzZSIsImNvbnRyb2wiLCJjb250cm9sIiwiY29udHJvbCIsImNvbnRyb2wiKQp0YWJsZSh5KQpgYGAKCiMg6KGM5YiX5pON5L2cCiMjIOODmeOCr+ODiOODqyA8LS0+ICDooYzliJcKYGBge3J9CiMjIOODmeOCr+ODiOODqyAtLT4g6KGM5YiXCnZlYyA8LSAxOjkKKG1hdDEgPC0gbWF0cml4KHZlYyxucm93ID0gMykpCihtYXQyIDwtIG1hdHJpeCh2ZWMsbmNvbCA9IDMpKQoobWF0MyA8LSBjYmluZCgxOjMsNDo2KSkKKG1hdDQgPC0gcmJpbmQoMTozLDQ6NikpCiMg6KGM5YiXIC0tPiDjg5njgq/jg4jjg6sKYXMudmVjdG9yKG1hdDEpCmBgYAoKIyPooYzliJfjga7mt7vjgYjlrZfmk43kvZwKYGBge3J9CnZlYyA8LSAxOjkKbWF0IDwtIG1hdHJpeCh2ZWMsbnJvdyA9IDMpCnJvd25hbWVzKG1hdCkgPC0gYygicm93MSIsInJvdzIiLCJyb3czIikKY29sbmFtZXMobWF0KSA8LSBjKCJjb2wxIiwiY29sMiIsImNvbDMiKQptYXRbMSxdCm1hdFssMV0KbWF0WzE6MixdCm1hdFstMSxdCm1hdFsicm93MSIsXQptYXRbLCJjb2wyIl0KdChtYXQpCmBgYAoKCiMj44Oq44K544OICmBgYHtyfQp5IDwtIGxpc3QobnZlYyA9IGMoMSwyLDMpLCBjdmVjID0gYygiYSIsImIiLCJjIiksbWF0ID0gbWF0cml4KDE6OSxucm93PTMpKQp5WzFdCnlbWzFdXQp5WyJtYXQiXQp5JG1hdAoKeSA8LSBsaXN0KCkKeVtbMV1dIDwtIGMoMSwyLDMpCnlbWzJdXSA8LSBjKCJhIiwiYiIsImMiKQp5W1szXV0gPC0gbWF0cml4KDE6OSxucm93ID0gMykKbmFtZXMoeSkgPC0gYygibnZlYyIsImN2ZWMiLCJtYXQiKQoKeSA8LSBsaXN0KCkKeSRudmVjIDwtIGMoMSwyLDMpCnkkY3ZlYyA8LSBjKCJhIiwiYiIsImMiKQp5JG1hdCA8LSBtYXRyaXgoMTo5LG5yb3cgPSAzKQoKeSA8LSBsaXN0KCkKeSA8LSBjKHksIGxpc3QobnZlYyA9IGMoMSwyLDMpKSkKeSA8LSBjKHksIGxpc3QoY3ZlYyA9IGMoImEiLCJiIiwiYyIpKSkKeSA8LSBjKHksIGxpc3QobWF0ID0gbWF0cml4KDE6OSxucm93ID0gMykpKQpgYGAKIyMg44OH44O844K/44OV44Os44O844OgCmBgYHtyfQpkZiA8LSBkYXRhLmZyYW1lKG12ZWMgPSAxOjMsIGN2ZWMgPSBjKCJhIiwiYiIsImMiKSkKZGZbWzFdXQpkZiRtdmVjCmRmWywxXQpkZlsyLF0KZGZbMToyLF0KYGBgCmBgYHtyLGV2YWw9Rn0KI3JlYWRyCmluc3RhbGwucGFja2FnZXMoInJlYWRyIikKYGBgCiNyZWFkcgojI+ODh+ODvOOCv+OBruabuOOBjeWHuuOBlwpgYGB7cixldmFsPUZ9CmxpYnJhcnkocmVhZHIpCm1hdCA8LSBtYXRyaXgoMTo5LCBucm93ID0gMykKY29sbmFtZXMobWF0KSA8LSBjKCJBIiwiQiIsIkMiKQpkZiA8LSBhcy5kYXRhLmZyYW1lKG1hdCkKd3JpdGVfY3N2KHggPSBkZiwgcGF0aCA9ICJkYXRhL3NhbXBsZTAxLmNzdiIsIGNvbF9uYW1lcyA9IFRSVUUpCndyaXRlX3Rzdih4ID0gZGYsIHBhdGggPSAiZGF0YS9zYW1wbGUwMS50c3YiLCBjb2xfbmFtZXMgPSBUUlVFKQpgYGAKYGBge3IsZXZhbD1GfQojIGZyZWFkCmluc3RhbGwucGFja2FnZXMoImRhdGEudGFibGUiKQpgYGAKCiNkYXRhLnRhYmxlCiPjg4fjg7zjgr/jga7oqq3jgb/ovrzjgb8KYGBge3IsZXZhbD1GfQpsaWJyYXJ5KGRhdGEudGFibGUpCmlucHV0X2NzdiA8LSBmcmVhZChpbnB1dCA9ICJkYXRhL3NhbXBsZTAxLmNzdiIsc2VwID0gIiwiLAogICAgICAgICAgICAgICAgICAgaGVhZGVyID0gVFJVRSwgZGF0YS50YWJsZSA9IEZBTFNFKQppbnB1dF90c3YgPC0gZnJlYWQoaW5wdXQgPSAiZGF0YS9zYW1wbGUwMS50c3YiLHNlcCA9ICJcdCIsCiAgICAgICAgICAgICAgICAgICBoZWFkZXIgPSBUUlVFLCBkYXRhLnRhYmxlID0gRkFMU0UpCmhlYWQoaW5wdXRfY3N2KQpoZWFkKGlucHV0X3RzdikKYGBgCiPplqLmlbDjgYTjgo3jgYTjgo0KIyNudW1lcmlj5Z6LCmBgYHtyfQp4IDwtIDE6MTAKeSA8LSAxMDoxCmxvZyh4KQpleHAoeCkKbWF4KHgpCm1pbih4KQpzdW0oeCkKbWVhbih4KQptZWRpYW4oeCkKcmFuayh4KQp2YXIoeCkKc2QoeCkKcXVhbnRpbGUoeCkKY29yKHgseSkKcm91bmQoMy4xNCwxKQpgYGAKCiMjY2hhcmFjdGVy5Z6LCmBgYHtyfQpjaGFyMSA8LSAiSSBhbSBNYXRzdWkuIgpjaGFyMiA8LSAiTXkgaG9iYnkgaXMgYSBjeWNsaW5nLiIKdG91cHBlcihjaGFyMSkKdG9sb3dlcihjaGFyMSkKY2hhcjEyIDwtIHBhc3RlKGNoYXIxLGNoYXIyKQpnc3ViKCJNYXRzdWkiLCJTaGltYW11cmEiLGNoYXIxKQp0eHQgPC0gYygiVGhlIiwgImxpY2Vuc2VzIiwgImZvciIsICJtb3N0IiwgInNvZnR3YXJlIiwgImFyZSIsCiAgICAgICAgICAgICAgICAiZGVzaWduZWQiLCAidG8iLCAidGFrZSIsICJhd2F5IiwgInlvdXIiLCAiZnJlZWRvbSIsCiAgICAgICAgICAgICAgICAidG8iLCAic2hhcmUiLCAiYW5kIiwgImNoYW5nZSIsICJpdC4iKQpncmVwKCJ5b3UiLHR4dCkKbWF0Y2goInlvdXIiLHR4dCkKdHh0MiA8LSBjKCJnZW5lMV9ob2dlIiwiZ2VuZTJfZnVnYSIsImdlbmUzX2hvZ2UiKQpzdHJzcGxpdCh0eHQyLHNwbGl0ID0gIl8iKQpgYGAKIyPntbHoqIjplqLmlbAKYGBge3J9CnggPC0gcm5vcm0oMTAwKQp5IDwtIHggKyBybm9ybSgxMDApCmRmIDwtIGRhdGEuZnJhbWUoeCA9IHgsIHkgPSB5KQpsbWZpdCA8LSBsbSh5IH4geCwgZGF0YSA9IGRmKQpzdW1tYXJ5KGxtZml0KQp0LnRlc3QoeCx5KQpgYGAKCiMj56K6546H6Zai5pWwCmBgYHtyfQoKcm5vcm0oMTAsMCwxKQpydCgxMCw1KQpyY2hpc3EoMTAsMTApCnJwb2lzKDEwLDIpCmBgYAojI+OCsOODqeODleOCo+ODg+OCr+OCuQpgYGB7cn0KeCA8LSBybm9ybSgxMDApCnkgPC0geCArIHJub3JtKDEwMCkKcGxvdCh4KQpwbG90KHgseSkKcGxvdCh4LHksY29sID0gImJsdWUiLCB4bGFiID0gImF4aXMteCIsIHlsYWIgPSAiYXhpeC15IiwgCiAgICAgeGxpbSA9IGMoLTIsIDIpLCB5bGltID0gYygtMiwgMiksIG1haW4gPSAibmljZSBwbG90ICEiKQphYmxpbmUoYSA9IDAsIGIgPSAxLCBjb2wgPSAicmVkIikKZ3JpZCgpCmBgYAoj5Yi25b6h5qeL5paHCiMjZm9y44Or44O844OXCmBgYHtyfQpmb3IoaSBpbiAxOjUpewogIGogPC0gaSArIDEwCiAgcHJpbnQoaikKfQpgYGAKCiMjd2hpbGXjg6vjg7zjg5cKYGBge3J9CmkgPC0gMQp3aGlsZShpIDwgNSl7CiAgcHJpbnQoaSkKICBpIDwtIGkgKyAxCn0KYGBgCiMjaWbmp4vmlocKYGBge3J9CmkgPC0gMgppZihpID4gMyl7CiAgcHJpbnQoInllcyIpCn1lbHNlewogIHByaW50KCJubyIpCn0KYGBgCiMj44GE44KN44GE44KN44Gq5p2h5Lu25Yik5a6aCmBgYHtyfQp4IDwtIDEKeSA8LSAyCnggPiB5CnggPCB5CnggPT0geQp4ICE9IHkKeCA8IHkgJiB5ID09IDIKeCA8IHkgfCB4ID09IDIKYGBgCiPplqLmlbDjga7oh6rkvZwKYGBge3J9CnNxdWFyZSA8LSBmdW5jdGlvbih4KXsKICBzcXVhcmVkIDwtIHheMgogIHJldHVybihzcXVhcmVkKQp9CnNxdWFyZSgxMCkKYGBgCg==