Resuelva las situaicones que se le presentan a continuación. Para cada una de las situaciones deberán generar un gráfico en ggplot que acompañe a la resolución.

Problema 1

En un laboratorio de botánica se sembraron plántulas de frijol (Phaseolus vulgaris) bajo condiciones controladas: luz constante, temperatura de 25 °C y riego regular. Cada 2 días se midió la altura de 10 plántulas y se registró el promedio. Su grupo debe estimar la tasa de crecimiento de las plántulas con un modelo lineal. Si ustedes tuvieran a cargo de laboratorio, qué decisiones tomarían para que el crecimiento sea mayor.

Ahora, con ese modelo, haga una predicción de cuál será el tamañao de las plantas en los días 40 y 52.


# nuevos_datos <- data.frame(Tiempo= c(40,52))

# predict(modelo, nuevos_datos)

Respuesta

library(ggplot2)
library(tidyverse)

datos <- data.frame(
  Tiempo = c(0, 2, 4, 6, 8, 10, 12, 14, 16, 18, 20, 22, 24, 26, 28),
  Altura = c(2.1, 4, 6.9, 8.2, 11.5, 12.4, 15.8, 16.1, 20.3, 20.9,
             24.6, 25.2, 29.1, 29.8, 33)
)

# Ver las primeras filas
head(datos)

# Resumen estadístico
summary(datos)
     Tiempo       Altura     
 Min.   : 0   Min.   : 2.10  
 1st Qu.: 7   1st Qu.: 9.85  
 Median :14   Median :16.10  
 Mean   :14   Mean   :17.33  
 3rd Qu.:21   3rd Qu.:24.90  
 Max.   :28   Max.   :33.00  
# Gráfica de dispersión con línea de tendencia
ggplot(datos, aes(x = Tiempo, y = Altura)) +
  geom_point(size = 3, color = "purple") +          # puntos
  geom_smooth(method = "lm", se = TRUE, color = "violet") + # línea de regresión
  labs(title = "Crecimiento de plántulas de frijol",
       x = "Tiempo (días)",
       y = "Altura promedio (cm)") +
  theme_minimal()


# Ajustar el modelo lineal: Altura ~ Tiempo
modelo <- lm(Altura ~ Tiempo, data = datos)

# Ver los resultados del modelo
summary(modelo)

Call:
lm(formula = Altura ~ Tiempo, data = datos)

Residuals:
     Min       1Q   Median       3Q 
-1.22667 -0.59024  0.04583  0.68690 
     Max 
 0.86440 

Coefficients:
            Estimate Std. Error t value
(Intercept)  2.05417    0.36116   5.688
Tiempo       1.09089    0.02195  49.694
            Pr(>|t|)    
(Intercept) 7.44e-05 ***
Tiempo      3.25e-16 ***
---
Signif. codes:  
  0 ‘***’ 0.001 ‘**’ 0.01 ‘*’ 0.05 ‘.’
  0.1 ‘ ’ 1

Residual standard error: 0.7347 on 13 degrees of freedom
Multiple R-squared:  0.9948,    Adjusted R-squared:  0.9944 
F-statistic:  2469 on 1 and 13 DF,  p-value: 3.247e-16
# Crear un data.frame con los días a predecir
nuevos_dias <- data.frame(Tiempo = c(40, 52))

# Predecir la altura
prediccion <- predict(modelo, newdata = nuevos_dias)

# Ver el resultado
prediccion
       1        2 
45.68988 58.78060 

Problema 2

La lapa roja o guacamaya roja (Ara macao) fue casi eliminada de buena parte del Pacífico de Costa Rica por la pérdida de bosque y la captura de polluelos. Gracias a programas de conservación y reintroducción, algunas poblaciones se han recuperado.

Imaginen que un programa de conservación liberó un grupo pequeño de lapas rojas en un bosque protegido del Pacífico central y las censó cada año durante 20 años. Ustedes deben ajustar un modelo logístico a los datos y estimar los parámetros que describen el crecimiento de esta población. Como tomadores de decisión, especifiquen cuándo deberá de terminar el monitoreo ecológico, según el comportamiento poblacional.

Respuesta

# Crear la base de datos directamente en R
datos <- data.frame(
  Muestreo = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9,
               10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20),
  Individuos = c(12, 15, 24, 29, 43, 50, 69, 79, 101, 109,
                 131, 136, 152, 154, 166, 165, 174, 171, 179, 174, 181)
)

head(datos)
summary(datos)
    Muestreo    Individuos   
 Min.   : 0   Min.   : 12.0  
 1st Qu.: 5   1st Qu.: 50.0  
 Median :10   Median :131.0  
 Mean   :10   Mean   :110.2  
 3rd Qu.:15   3rd Qu.:166.0  
 Max.   :20   Max.   :181.0  
ggplot(datos, aes(x = Muestreo, y = Individuos)) +
  geom_point(size = 3, color = "pink") +
  labs(title = "Crecimiento poblacional de la lapa roja",
       x = "Año de muestreo",
       y = "Número de individuos") +
  theme_minimal()


# Ajustar el modelo logístico con los parámetros dados
modelo <- nls(Individuos ~ 550 / (1 + ((550 - N0) / N0) * exp(-(-0.3) * Muestreo)),
              data = datos,
              start = list(N0 = 480))

summary(modelo)

Formula: Individuos ~ 550/(1 + ((550 - N0)/N0) * exp(-(-0.3) * Muestreo))

Parameters:
   Estimate Std. Error t value Pr(>|t|)
N0    67.22      79.81   0.842     0.41

Residual standard error: 126.8 on 20 degrees of freedom

Number of iterations to convergence: 8 
Achieved convergence tolerance: 2.927e-06
# Parámetros dados
K <- 550
mu_max <- -0.3
N0 <- 482   # población inicial del censo

# Función logística
N <- function(t) {
  K / (1 + ((K - N0) / N0) * exp(-mu_max * t))
}

# Secuencia de años (hasta cuando la población llegue a 0)
años <- seq(0, 30, length.out = 300)
pred <- N(años)
curva <- data.frame(Muestreo = años, Individuos = pred)

ggplot(datos, aes(x = Muestreo, y = Individuos)) +
  geom_point(size = 3, color = "purple") +
  geom_line(data = curva, color = "blue", linewidth = 1) +
  labs(title = "Modelo logístico del declive del anfibio",
       x = "Año de muestreo",
       y = "Número de individuos") +
  theme_minimal()

# Probar varios años y ver cuándo llega a menos de 1
for (t in 0:40) {
  cat("Año", t, ":", round(N(t), 2), "individuos\n")
}
Año 0 : 482 individuos
Año 1 : 462.02 individuos
Año 2 : 437.53 individuos
Año 3 : 408.32 individuos
Año 4 : 374.56 individuos
Año 5 : 336.95 individuos
Año 6 : 296.74 individuos
Año 7 : 255.57 individuos
Año 8 : 215.25 individuos
Año 9 : 177.46 individuos
Año 10 : 143.47 individuos
Año 11 : 113.99 individuos
Año 12 : 89.24 individuos
Año 13 : 69.01 individuos
Año 14 : 52.84 individuos
Año 15 : 40.15 individuos
Año 16 : 30.32 individuos
Año 17 : 22.78 individuos
Año 18 : 17.06 individuos
Año 19 : 12.74 individuos
Año 20 : 9.5 individuos
Año 21 : 7.07 individuos
Año 22 : 5.25 individuos
Año 23 : 3.9 individuos
Año 24 : 2.9 individuos
Año 25 : 2.15 individuos
Año 26 : 1.59 individuos
Año 27 : 1.18 individuos
Año 28 : 0.88 individuos
Año 29 : 0.65 individuos
Año 30 : 0.48 individuos
Año 31 : 0.36 individuos
Año 32 : 0.26 individuos
Año 33 : 0.2 individuos
Año 34 : 0.14 individuos
Año 35 : 0.11 individuos
Año 36 : 0.08 individuos
Año 37 : 0.06 individuos
Año 38 : 0.04 individuos
Año 39 : 0.03 individuos
Año 40 : 0.02 individuos

Problema 3

En los bosques nubosos de la cordillera de Tilarán, un anfibio endémico (especie ficticia, inspirada en lo ocurrido con el sapo dorado de Monteverde) mantenía una población estable de unos 500 individuos. A partir de cierto momento, la llegada de un hongo patógeno (quitridiomicosis) y el aumento de la temperatura hicieron que las muertes superaran a los nacimientos. Un equipo de biólogos censó la población cada año durante 12 años. (mumax = -0.3, K = 550)

Ustedes deben ajustar un modelo logístico con tasa de crecimiento y usarlo para predecir cuándo desaparecerá la población.


## Para predecir:

ajuste <- fit_growthmodel(
  FUN   = grow_logistic,
  p     = c(y0 = , mumax = , K = ),   # valores iniciales
  time  = tiempo,
  y     = individuos,
  lower = c(y0 = 1,    mumax = -3, K = 1),
  upper = c(y0 = 2000, mumax = 0,  K = 5000)
)

summary(ajuste)
coef(ajuste)


## Predicción de cuál será el número de individuos en un tiempo determinado

p <- coef(ajuste)
t_pred <- c(20,40,50)
N_pred <- grow_logistic(t_pred, p)[, "y"]

## Predicción de en qué momento la población va a ser 0

t_alcanza <- function(N, p) {
  with(as.list(p), log(N * (K - y0) / (y0 * (K - N))) / mumax)
}
t_alcanza(0.1, p)    # K/2 y 90 % de K

Respuesta

datos <- data.frame(
  Muestreo = c(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12),
  Individuos = c(482, 466, 456, 427, 404, 351, 314, 249, 203, 143, 109, 70, 51)
)

ggplot(datos, aes(x = Muestreo, y = Individuos)) +
  geom_point(size = 3, color = "purple") +
  labs(title = "Declive poblacional del anfibio endémico",
       x = "Año de muestreo",
       y = "Número de individuos") +
  theme_minimal()


# Parámetros dados
K <- 550
mu_max <- -0.3
N0 <- 482

# Función logística
N <- function(t) {
  K / (1 + ((K - N0) / N0) * exp(-mu_max * t))
}

años <- seq(0, 30, length.out = 300)
curva <- data.frame(Muestreo = años, Individuos = N(años))

ggplot(datos, aes(x = Muestreo, y = Individuos)) +
  geom_point(size = 3, color = "purple") +
  geom_line(data = curva, color = "blue", linewidth = 1) +
  labs(title = "Modelo logístico del declive del anfibio",
       x = "Año de muestreo",
       y = "Número de individuos") +
  theme_minimal()


# Ver la población año por año hasta que baje de 1 individuo
for (t in 0:40) {
  cat("Año", t, ":", round(N(t), 2), "individuos\n")
}
Año 0 : 482 individuos
Año 1 : 462.02 individuos
Año 2 : 437.53 individuos
Año 3 : 408.32 individuos
Año 4 : 374.56 individuos
Año 5 : 336.95 individuos
Año 6 : 296.74 individuos
Año 7 : 255.57 individuos
Año 8 : 215.25 individuos
Año 9 : 177.46 individuos
Año 10 : 143.47 individuos
Año 11 : 113.99 individuos
Año 12 : 89.24 individuos
Año 13 : 69.01 individuos
Año 14 : 52.84 individuos
Año 15 : 40.15 individuos
Año 16 : 30.32 individuos
Año 17 : 22.78 individuos
Año 18 : 17.06 individuos
Año 19 : 12.74 individuos
Año 20 : 9.5 individuos
Año 21 : 7.07 individuos
Año 22 : 5.25 individuos
Año 23 : 3.9 individuos
Año 24 : 2.9 individuos
Año 25 : 2.15 individuos
Año 26 : 1.59 individuos
Año 27 : 1.18 individuos
Año 28 : 0.88 individuos
Año 29 : 0.65 individuos
Año 30 : 0.48 individuos
Año 31 : 0.36 individuos
Año 32 : 0.26 individuos
Año 33 : 0.2 individuos
Año 34 : 0.14 individuos
Año 35 : 0.11 individuos
Año 36 : 0.08 individuos
Año 37 : 0.06 individuos
Año 38 : 0.04 individuos
Año 39 : 0.03 individuos
Año 40 : 0.02 individuos

Decisión: El monitoreo debe continuar hasta que la población llegue a cero (≈ año 20) para documentar la extinción. Después, enfocar esfuerzos en conservación ex situ (criaderos, biobancos) y mitigación de la quitridiomicosis y el cambio climático, ya que el modelo confirma que la población no se recuperará por sí sola.

LS0tCnRpdGxlOiAiUiBOb3RlYm9vayIKb3V0cHV0OgogIGh0bWxfbm90ZWJvb2s6CiAgICB0b2M6IHRydWUKICAgIHRoZW1lOiB1bml0ZWQKICBodG1sX2RvY3VtZW50OgogICAgdG9jOiB0cnVlCiAgICBkZl9wcmludDogcGFnZWQKLS0tCgpSZXN1ZWx2YSBsYXMgc2l0dWFpY29uZXMgcXVlIHNlIGxlIHByZXNlbnRhbiBhIGNvbnRpbnVhY2nDs24uIFBhcmEgY2FkYSB1bmEgZGUgbGFzIHNpdHVhY2lvbmVzIGRlYmVyw6FuIGdlbmVyYXIgdW4gZ3LDoWZpY28gZW4gZ2dwbG90IHF1ZSBhY29tcGHDsWUgYSBsYSByZXNvbHVjacOzbi4KCiMgUHJvYmxlbWEgMQoKRW4gdW4gbGFib3JhdG9yaW8gZGUgYm90w6FuaWNhIHNlIHNlbWJyYXJvbiBwbMOhbnR1bGFzIGRlIGZyaWpvbCAoKlBoYXNlb2x1cyB2dWxnYXJpcyopIGJham8gY29uZGljaW9uZXMgY29udHJvbGFkYXM6IGx1eiBjb25zdGFudGUsIHRlbXBlcmF0dXJhIGRlIDI1IMKwQyB5IHJpZWdvIHJlZ3VsYXIuIENhZGEgMiBkw61hcyBzZSBtaWRpw7MgbGEgYWx0dXJhIGRlIDEwIHBsw6FudHVsYXMgeSBzZSByZWdpc3Ryw7MgZWwgcHJvbWVkaW8uIFN1IGdydXBvIGRlYmUgZXN0aW1hciBsYcKgKip0YXNhIGRlIGNyZWNpbWllbnRvKirCoGRlIGxhcyBwbMOhbnR1bGFzIGNvbiB1biBtb2RlbG8gbGluZWFsLiBTaSB1c3RlZGVzIHR1dmllcmFuIGEgY2FyZ28gZGUgbGFib3JhdG9yaW8sIHF1w6kgZGVjaXNpb25lcyB0b21hcsOtYW4gcGFyYSBxdWUgZWwgY3JlY2ltaWVudG8gc2VhIG1heW9yLgoKQWhvcmEsIGNvbiBlc2UgbW9kZWxvLCBoYWdhIHVuYSBwcmVkaWNjacOzbiBkZSBjdcOhbCBzZXLDoSBlbCB0YW1hw7FhbyBkZSBsYXMgcGxhbnRhcyBlbiBsb3MgZMOtYXMgNDAgeSA1Mi4KCmBgYHtyfQoKIyBudWV2b3NfZGF0b3MgPC0gZGF0YS5mcmFtZShUaWVtcG89IGMoNDAsNTIpKQoKIyBwcmVkaWN0KG1vZGVsbywgbnVldm9zX2RhdG9zKQpgYGAKCiMjIFJlc3B1ZXN0YQoKYGBge3J9CmxpYnJhcnkoZ2dwbG90MikKbGlicmFyeSh0aWR5dmVyc2UpCgpkYXRvcyA8LSBkYXRhLmZyYW1lKAogIFRpZW1wbyA9IGMoMCwgMiwgNCwgNiwgOCwgMTAsIDEyLCAxNCwgMTYsIDE4LCAyMCwgMjIsIDI0LCAyNiwgMjgpLAogIEFsdHVyYSA9IGMoMi4xLCA0LCA2LjksIDguMiwgMTEuNSwgMTIuNCwgMTUuOCwgMTYuMSwgMjAuMywgMjAuOSwKICAgICAgICAgICAgIDI0LjYsIDI1LjIsIDI5LjEsIDI5LjgsIDMzKQopCgojIFZlciBsYXMgcHJpbWVyYXMgZmlsYXMKaGVhZChkYXRvcykKCiMgUmVzdW1lbiBlc3RhZMOtc3RpY28Kc3VtbWFyeShkYXRvcykKCiMgR3LDoWZpY2EgZGUgZGlzcGVyc2nDs24gY29uIGzDrW5lYSBkZSB0ZW5kZW5jaWEKZ2dwbG90KGRhdG9zLCBhZXMoeCA9IFRpZW1wbywgeSA9IEFsdHVyYSkpICsKICBnZW9tX3BvaW50KHNpemUgPSAzLCBjb2xvciA9ICJwdXJwbGUiKSArICAgICAgICAgICMgcHVudG9zCiAgZ2VvbV9zbW9vdGgobWV0aG9kID0gImxtIiwgc2UgPSBUUlVFLCBjb2xvciA9ICJ2aW9sZXQiKSArICMgbMOtbmVhIGRlIHJlZ3Jlc2nDs24KICBsYWJzKHRpdGxlID0gIkNyZWNpbWllbnRvIGRlIHBsw6FudHVsYXMgZGUgZnJpam9sIiwKICAgICAgIHggPSAiVGllbXBvIChkw61hcykiLAogICAgICAgeSA9ICJBbHR1cmEgcHJvbWVkaW8gKGNtKSIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgQWp1c3RhciBlbCBtb2RlbG8gbGluZWFsOiBBbHR1cmEgfiBUaWVtcG8KbW9kZWxvIDwtIGxtKEFsdHVyYSB+IFRpZW1wbywgZGF0YSA9IGRhdG9zKQoKIyBWZXIgbG9zIHJlc3VsdGFkb3MgZGVsIG1vZGVsbwpzdW1tYXJ5KG1vZGVsbykKCiMgQ3JlYXIgdW4gZGF0YS5mcmFtZSBjb24gbG9zIGTDrWFzIGEgcHJlZGVjaXIKbnVldm9zX2RpYXMgPC0gZGF0YS5mcmFtZShUaWVtcG8gPSBjKDQwLCA1MikpCgojIFByZWRlY2lyIGxhIGFsdHVyYQpwcmVkaWNjaW9uIDwtIHByZWRpY3QobW9kZWxvLCBuZXdkYXRhID0gbnVldm9zX2RpYXMpCgojIFZlciBlbCByZXN1bHRhZG8KcHJlZGljY2lvbgoKRGVjaXNpb25lcyBwYXJhIGF1bWVudGFyIGVsIGNyZWNpbWllbnRvIChyZXNwdWVzdGEgY29uY2VwdHVhbCk6CgpPcHRpbWl6YXIgbGEgaW50ZW5zaWRhZCB5IGR1cmFjacOzbiBkZSBsYSBsdXogKGZvdG9zw61udGVzaXMpLiBBanVzdGFyIGxhIHRlbXBlcmF0dXJhICgyNSDCsEMgZXMgYnVlbm8sIHBlcm8gcHJvYmFyIHJhbmdvcykuIE1lam9yYXIgZWwgcmllZ28geSBudXRyaWVudGVzIChmZXJ0aWxpemFudGUgYmFsYW5jZWFkbywgcEggZGVsIHN1ZWxvKS4gUmVkdWNpciBlbCBlc3Ryw6lzIChldml0YXIgY2FtYmlvcyBicnVzY29zLCBjb21wZXRlbmNpYSBlbnRyZSBwbMOhbnR1bGFzKS4KYGBgCgojIFByb2JsZW1hIDIKCkxhIGxhcGEgcm9qYSBvIGd1YWNhbWF5YSByb2phICgqQXJhIG1hY2FvKikgZnVlIGNhc2kgZWxpbWluYWRhIGRlIGJ1ZW5hIHBhcnRlIGRlbCBQYWPDrWZpY28gZGUgQ29zdGEgUmljYSBwb3IgbGEgcMOpcmRpZGEgZGUgYm9zcXVlIHkgbGEgY2FwdHVyYSBkZSBwb2xsdWVsb3MuIEdyYWNpYXMgYSBwcm9ncmFtYXMgZGUgY29uc2VydmFjacOzbiB5IHJlaW50cm9kdWNjacOzbiwgYWxndW5hcyBwb2JsYWNpb25lcyBzZSBoYW4gcmVjdXBlcmFkby4KCkltYWdpbmVuIHF1ZSB1biBwcm9ncmFtYSBkZSBjb25zZXJ2YWNpw7NuIGxpYmVyw7MgdW4gZ3J1cG8gcGVxdWXDsW8gZGUgbGFwYXMgcm9qYXMgZW4gdW4gYm9zcXVlIHByb3RlZ2lkbyBkZWwgUGFjw61maWNvIGNlbnRyYWwgeSBsYXMgY2Vuc8OzwqAqKmNhZGEgYcOxbyBkdXJhbnRlIDIwIGHDsW9zKiouIFVzdGVkZXMgZGViZW4gYWp1c3RhciB1bsKgKiptb2RlbG8gbG9nw61zdGljbyoqwqBhIGxvcyBkYXRvcyB5IGVzdGltYXIgbG9zIHBhcsOhbWV0cm9zIHF1ZSBkZXNjcmliZW4gZWwgY3JlY2ltaWVudG8gZGUgZXN0YSBwb2JsYWNpw7NuLiBDb21vIHRvbWFkb3JlcyBkZSBkZWNpc2nDs24sIGVzcGVjaWZpcXVlbiBjdcOhbmRvIGRlYmVyw6EgZGUgdGVybWluYXIgZWwgbW9uaXRvcmVvIGVjb2zDs2dpY28sIHNlZ8O6biBlbCBjb21wb3J0YW1pZW50byBwb2JsYWNpb25hbC4KCiMjIFJlc3B1ZXN0YQoKYGBge3J9CiMgQ3JlYXIgbGEgYmFzZSBkZSBkYXRvcyBkaXJlY3RhbWVudGUgZW4gUgpkYXRvcyA8LSBkYXRhLmZyYW1lKAogIE11ZXN0cmVvID0gYygwLCAxLCAyLCAzLCA0LCA1LCA2LCA3LCA4LCA5LAogICAgICAgICAgICAgICAxMCwgMTEsIDEyLCAxMywgMTQsIDE1LCAxNiwgMTcsIDE4LCAxOSwgMjApLAogIEluZGl2aWR1b3MgPSBjKDEyLCAxNSwgMjQsIDI5LCA0MywgNTAsIDY5LCA3OSwgMTAxLCAxMDksCiAgICAgICAgICAgICAgICAgMTMxLCAxMzYsIDE1MiwgMTU0LCAxNjYsIDE2NSwgMTc0LCAxNzEsIDE3OSwgMTc0LCAxODEpCikKCmhlYWQoZGF0b3MpCnN1bW1hcnkoZGF0b3MpCgpnZ3Bsb3QoZGF0b3MsIGFlcyh4ID0gTXVlc3RyZW8sIHkgPSBJbmRpdmlkdW9zKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsIGNvbG9yID0gInBpbmsiKSArCiAgbGFicyh0aXRsZSA9ICJDcmVjaW1pZW50byBwb2JsYWNpb25hbCBkZSBsYSBsYXBhIHJvamEiLAogICAgICAgeCA9ICJBw7FvIGRlIG11ZXN0cmVvIiwKICAgICAgIHkgPSAiTsO6bWVybyBkZSBpbmRpdmlkdW9zIikgKwogIHRoZW1lX21pbmltYWwoKQoKIyBBanVzdGFyIGVsIG1vZGVsbyBsb2fDrXN0aWNvIGNvbiBsb3MgcGFyw6FtZXRyb3MgZGFkb3MKbW9kZWxvIDwtIG5scyhJbmRpdmlkdW9zIH4gNTUwIC8gKDEgKyAoKDU1MCAtIE4wKSAvIE4wKSAqIGV4cCgtKC0wLjMpICogTXVlc3RyZW8pKSwKICAgICAgICAgICAgICBkYXRhID0gZGF0b3MsCiAgICAgICAgICAgICAgc3RhcnQgPSBsaXN0KE4wID0gNDgwKSkKCnN1bW1hcnkobW9kZWxvKQoKIyBQYXLDoW1ldHJvcyBkYWRvcwpLIDwtIDU1MAptdV9tYXggPC0gLTAuMwpOMCA8LSA0ODIgICAjIHBvYmxhY2nDs24gaW5pY2lhbCBkZWwgY2Vuc28KCiMgRnVuY2nDs24gbG9nw61zdGljYQpOIDwtIGZ1bmN0aW9uKHQpIHsKICBLIC8gKDEgKyAoKEsgLSBOMCkgLyBOMCkgKiBleHAoLW11X21heCAqIHQpKQp9CgojIFNlY3VlbmNpYSBkZSBhw7FvcyAoaGFzdGEgY3VhbmRvIGxhIHBvYmxhY2nDs24gbGxlZ3VlIGEgMCkKYcOxb3MgPC0gc2VxKDAsIDMwLCBsZW5ndGgub3V0ID0gMzAwKQpwcmVkIDwtIE4oYcOxb3MpCmN1cnZhIDwtIGRhdGEuZnJhbWUoTXVlc3RyZW8gPSBhw7FvcywgSW5kaXZpZHVvcyA9IHByZWQpCgpnZ3Bsb3QoZGF0b3MsIGFlcyh4ID0gTXVlc3RyZW8sIHkgPSBJbmRpdmlkdW9zKSkgKwogIGdlb21fcG9pbnQoc2l6ZSA9IDMsIGNvbG9yID0gInB1cnBsZSIpICsKICBnZW9tX2xpbmUoZGF0YSA9IGN1cnZhLCBjb2xvciA9ICJibHVlIiwgbGluZXdpZHRoID0gMSkgKwogIGxhYnModGl0bGUgPSAiTW9kZWxvIGxvZ8Otc3RpY28gZGVsIGRlY2xpdmUgZGVsIGFuZmliaW8iLAogICAgICAgeCA9ICJBw7FvIGRlIG11ZXN0cmVvIiwKICAgICAgIHkgPSAiTsO6bWVybyBkZSBpbmRpdmlkdW9zIikgKwogIHRoZW1lX21pbmltYWwoKQojIFByb2JhciB2YXJpb3MgYcOxb3MgeSB2ZXIgY3XDoW5kbyBsbGVnYSBhIG1lbm9zIGRlIDEKZm9yICh0IGluIDA6NDApIHsKICBjYXQoIkHDsW8iLCB0LCAiOiIsIHJvdW5kKE4odCksIDIpLCAiaW5kaXZpZHVvc1xuIikKfQoKRGVjaXNpw7NuIGRlIG1vbml0b3JlbzogRWwgbW9uaXRvcmVvIGVjb2zDs2dpY28gZGViZXLDrWEgY29udGludWFyIGhhc3RhIHF1ZSBsYSBwb2JsYWNpw7NuIGRlc2NpZW5kYSBhIGNlcm8gKGHDsW8gMjApIHBhcmEgZG9jdW1lbnRhciBsYSBleHRpbmNpw7NuLCB5IGRlc3B1w6lzIGVuZm9jYXJzZSBlbiBlc3RyYXRlZ2lhcyBkZSBjb25zZXJ2YWNpw7NuIGV4IHNpdHUgKGNyaWFkZXJvcywgYmlvYmFuY29zKSB5IG1pdGlnYWNpw7NuIGRlIGxhIHF1aXRyaWRpb21pY29zaXMgeSBlbCBjYW1iaW8gY2xpbcOhdGljbywgeWEgcXVlIGVsIG1vZGVsbyBjb25maXJtYSBxdWUgbGEgcG9ibGFjacOzbiBubyBzZSByZWN1cGVyYXLDoSBwb3Igc8OtIHNvbGEuCmBgYAoKIyBQcm9ibGVtYSAzCgpFbiBsb3MgYm9zcXVlcyBudWJvc29zIGRlIGxhIGNvcmRpbGxlcmEgZGUgVGlsYXLDoW4sIHVuIGFuZmliaW8gZW5kw6ltaWNvIChlc3BlY2llIGZpY3RpY2lhLCBpbnNwaXJhZGEgZW4gbG8gb2N1cnJpZG8gY29uIGVsIHNhcG8gZG9yYWRvIGRlIE1vbnRldmVyZGUpIG1hbnRlbsOtYSB1bmEgcG9ibGFjacOzbiBlc3RhYmxlIGRlIHVub3MgNTAwIGluZGl2aWR1b3MuIEEgcGFydGlyIGRlIGNpZXJ0byBtb21lbnRvLCBsYSBsbGVnYWRhIGRlIHVuIGhvbmdvIHBhdMOzZ2VubyAocXVpdHJpZGlvbWljb3NpcykgeSBlbCBhdW1lbnRvIGRlIGxhIHRlbXBlcmF0dXJhIGhpY2llcm9uIHF1ZSBsYXMgbXVlcnRlcyBzdXBlcmFyYW4gYSBsb3MgbmFjaW1pZW50b3MuIFVuIGVxdWlwbyBkZSBiacOzbG9nb3MgY2Vuc8OzIGxhIHBvYmxhY2nDs27CoCoqY2FkYSBhw7FvIGR1cmFudGUgMTIgYcOxb3MqKi4gKG11bWF4ID0gLTAuMywgSyA9IDU1MCkKClVzdGVkZXMgZGViZW4gYWp1c3RhciB1bsKgKiptb2RlbG8gbG9nw61zdGljbyBjb24gdGFzYSBkZSBjcmVjaW1pZW50byoqwqB5IHVzYXJsbyBwYXJhIHByZWRlY2lywqAqKmN1w6FuZG8gZGVzYXBhcmVjZXLDoSBsYSBwb2JsYWNpw7NuKiouCgpgYGB7cn0KCiMjIFBhcmEgcHJlZGVjaXI6CgphanVzdGUgPC0gZml0X2dyb3d0aG1vZGVsKAogIEZVTiAgID0gZ3Jvd19sb2dpc3RpYywKICBwICAgICA9IGMoeTAgPSAsIG11bWF4ID0gLCBLID0gKSwgICAjIHZhbG9yZXMgaW5pY2lhbGVzCiAgdGltZSAgPSB0aWVtcG8sCiAgeSAgICAgPSBpbmRpdmlkdW9zLAogIGxvd2VyID0gYyh5MCA9IDEsICAgIG11bWF4ID0gLTMsIEsgPSAxKSwKICB1cHBlciA9IGMoeTAgPSAyMDAwLCBtdW1heCA9IDAsICBLID0gNTAwMCkKKQoKc3VtbWFyeShhanVzdGUpCmNvZWYoYWp1c3RlKQoKCiMjIFByZWRpY2Npw7NuIGRlIGN1w6FsIHNlcsOhIGVsIG7Dum1lcm8gZGUgaW5kaXZpZHVvcyBlbiB1biB0aWVtcG8gZGV0ZXJtaW5hZG8KCnAgPC0gY29lZihhanVzdGUpCnRfcHJlZCA8LSBjKDIwLDQwLDUwKQpOX3ByZWQgPC0gZ3Jvd19sb2dpc3RpYyh0X3ByZWQsIHApWywgInkiXQoKIyMgUHJlZGljY2nDs24gZGUgZW4gcXXDqSBtb21lbnRvIGxhIHBvYmxhY2nDs24gdmEgYSBzZXIgMAoKdF9hbGNhbnphIDwtIGZ1bmN0aW9uKE4sIHApIHsKICB3aXRoKGFzLmxpc3QocCksIGxvZyhOICogKEsgLSB5MCkgLyAoeTAgKiAoSyAtIE4pKSkgLyBtdW1heCkKfQp0X2FsY2FuemEoMC4xLCBwKSAgICAjIEsvMiB5IDkwICUgZGUgSwoKCgpgYGAKCiMjIFJlc3B1ZXN0YQoKYGBge3J9CmRhdG9zIDwtIGRhdGEuZnJhbWUoCiAgTXVlc3RyZW8gPSBjKDAsIDEsIDIsIDMsIDQsIDUsIDYsIDcsIDgsIDksIDEwLCAxMSwgMTIpLAogIEluZGl2aWR1b3MgPSBjKDQ4MiwgNDY2LCA0NTYsIDQyNywgNDA0LCAzNTEsIDMxNCwgMjQ5LCAyMDMsIDE0MywgMTA5LCA3MCwgNTEpCikKCmdncGxvdChkYXRvcywgYWVzKHggPSBNdWVzdHJlbywgeSA9IEluZGl2aWR1b3MpKSArCiAgZ2VvbV9wb2ludChzaXplID0gMywgY29sb3IgPSAicHVycGxlIikgKwogIGxhYnModGl0bGUgPSAiRGVjbGl2ZSBwb2JsYWNpb25hbCBkZWwgYW5maWJpbyBlbmTDqW1pY28iLAogICAgICAgeCA9ICJBw7FvIGRlIG11ZXN0cmVvIiwKICAgICAgIHkgPSAiTsO6bWVybyBkZSBpbmRpdmlkdW9zIikgKwogIHRoZW1lX21pbmltYWwoKQoKIyBQYXLDoW1ldHJvcyBkYWRvcwpLIDwtIDU1MAptdV9tYXggPC0gLTAuMwpOMCA8LSA0ODIKCiMgRnVuY2nDs24gbG9nw61zdGljYQpOIDwtIGZ1bmN0aW9uKHQpIHsKICBLIC8gKDEgKyAoKEsgLSBOMCkgLyBOMCkgKiBleHAoLW11X21heCAqIHQpKQp9Cgphw7FvcyA8LSBzZXEoMCwgMzAsIGxlbmd0aC5vdXQgPSAzMDApCmN1cnZhIDwtIGRhdGEuZnJhbWUoTXVlc3RyZW8gPSBhw7FvcywgSW5kaXZpZHVvcyA9IE4oYcOxb3MpKQoKZ2dwbG90KGRhdG9zLCBhZXMoeCA9IE11ZXN0cmVvLCB5ID0gSW5kaXZpZHVvcykpICsKICBnZW9tX3BvaW50KHNpemUgPSAzLCBjb2xvciA9ICJwdXJwbGUiKSArCiAgZ2VvbV9saW5lKGRhdGEgPSBjdXJ2YSwgY29sb3IgPSAiYmx1ZSIsIGxpbmV3aWR0aCA9IDEpICsKICBsYWJzKHRpdGxlID0gIk1vZGVsbyBsb2fDrXN0aWNvIGRlbCBkZWNsaXZlIGRlbCBhbmZpYmlvIiwKICAgICAgIHggPSAiQcOxbyBkZSBtdWVzdHJlbyIsCiAgICAgICB5ID0gIk7Dum1lcm8gZGUgaW5kaXZpZHVvcyIpICsKICB0aGVtZV9taW5pbWFsKCkKCiMgVmVyIGxhIHBvYmxhY2nDs24gYcOxbyBwb3IgYcOxbyBoYXN0YSBxdWUgYmFqZSBkZSAxIGluZGl2aWR1bwpmb3IgKHQgaW4gMDo0MCkgewogIGNhdCgiQcOxbyIsIHQsICI6Iiwgcm91bmQoTih0KSwgMiksICJpbmRpdmlkdW9zXG4iKQp9CgoKYGBgCkRlY2lzacOzbjogRWwgbW9uaXRvcmVvIGRlYmUgY29udGludWFyIGhhc3RhIHF1ZSBsYSBwb2JsYWNpw7NuIGxsZWd1ZSBhIGNlcm8gKOKJiCBhw7FvIDIwKSBwYXJhIGRvY3VtZW50YXIgbGEgZXh0aW5jacOzbi4gRGVzcHXDqXMsIGVuZm9jYXIgZXNmdWVyem9zIGVuIGNvbnNlcnZhY2nDs24gZXggc2l0dSAoY3JpYWRlcm9zLCBiaW9iYW5jb3MpIHkgbWl0aWdhY2nDs24gZGUgbGEgcXVpdHJpZGlvbWljb3NpcyB5IGVsIGNhbWJpbyBjbGltw6F0aWNvLCB5YSBxdWUgZWwgbW9kZWxvIGNvbmZpcm1hIHF1ZSBsYSBwb2JsYWNpw7NuIG5vIHNlIHJlY3VwZXJhcsOhIHBvciBzw60gc29sYS4K