title: An ogl-edocf challenge

text:
# Question
Title: An ogl-edocf challenge
## Input

A non-empty shuffled string consisting of ASCII characters in the range \\$\[32..126\]\\$.

## Output

The output is obtained by applying successive rotations to the input string.

For each letter (`[a-zA-Z]`) in the input string, going from left to right:

* if the letter is in upper case, rotate all characters before it by one position to the left
* if the letter is in lower case, rotate all characters before it by one position to the right

## Example

**Input: "Cb-Ad"**

* The first letter is a "**C**". We should do a rotation to the left, but there's no character before this "**C**". So, there's nothing to rotate.
* The next letter is a "**b**". We rotate "**C**" to the right. Because it's a single character, it is left unchanged.
* The character "**-**" does not trigger any rotation, as it's not a letter.
* The next letter is a "**A**". We rotate "**Cb-**" to the left, which gives "**b-C**Ad"
* The fourth and last letter is a "**d**". We rotate "**b-CA**" to the right, which gives "**Ab-C**d"

Therefore, the expected output is "**Ab-Cd**".

## Rules

* You may take input as a string or as an array of characters -- which may or may not be the same thing, depending on your language.
* You may also output an array of characters instead of a string.
* This is

## Test cases

```
"cbad" -> "abcd"
"ACBD" -> "ABCD"
"Cb-Ad" -> "Ab-Cd"
"caeBDF" -> "aBcDeF"
"aEcbDF" -> "abcDEF"
"ogl-edocf" -> "code-golf"
"W o,ollelrHd!" -> "Hello, World!"
"ti HIs SSta ET!" -> "tHis IS a tEST!"

```

# Answer
# Pyth, ~~21~~ 20 bytes

```
VQ=k+.>k-}NG}Nr1GN)k

```

Try it here

### Explanation

```
VQ=k+.>k-}NG}Nr1GN)k
VQ                )      For each N in the input...
     .>k                 ... rotate k (initially '')...
        -}NG}Nr1G        ... by (N is lowercase) - (N is uppercase)...
    +            N       ... then append N...
  =k                     ... and update k.
                   k     Output the result.

```
> 5 votes

# Answer
# Python 2, ~~100~~ ~~98~~ 95 bytes

```
f=lambda s,p='':s and f(s[1:],[p[x:]+p[:x]+s[0]for x in[s[0].isupper()-s[0].islower()]][0])or p

```

Try it online!
> 4 votes

# Answer
# \>\<\>, ~~45~~ 43 bytes

```
ii:2+7$.::&"`{"@)@(*?}"@["&::&@)@(*?{&!
ror

```

Try it online!

The fact that \>\<\> has stack rotation helps, but having to check the case of the letter doesn't.

### Explanation:

```
i    Get first inputted character
 i   Get second. This is to prevent errors from rotating an empty stack
  :2+7$.      Jump to the second line if that was EOF
        ::&   Create copies of the input and store one in the register
           "`{"@)@(*     Check if the char is lower case
                    ?}   If so rotate the stack
                      "@["&::&@)@(*?{   Rotate the other way if uppercase
                                     &  Push the new char
                                      ! Skip the first i instruction
Skip to the second line on EOF
ro      Reverse the stack and output
r r     Cancel out the first reverse
 o      Output the rest of the stack

```
> 3 votes

# Answer
# 05AB1E, ~~18~~ ~~17~~ ~~16~~ 14 bytes

```
õsvy.uy.l-._y«

```

Try it online or verify all test cases.

**Explanation:**

```
õ            # Start with an empty string
 sv          # Loop over the characters `y` of the input
   y.u       #  Check if `y` is an uppercase letter (1 if truthy; 0 if falsey)
   y.l       #  Check if `y` is a lowercase letter (1 if truthy; 0 if falsey)
      -      #  Subtract them from each other
       ._    #  Rotate the string that many times (-1, 0, or 1) toward the left
   y«        #  Append the current character `y` to the string
             # (And implicitly output the string after the loop)

```
> 3 votes

# Answer
# Jelly, 14 bytes

```
ØẠŒHċ€ḅ-N⁸ṙ;ð/

```

A monadic link accepting a list of characters which yields a list of characters.

**Try it online!** Or see the test-suite.

### How?

```
ØẠŒHċ€ḅ-N⁸ṙ;ð/ - Link - list of characters
             / - reduce by:
            ð  -   a dyadic chain:  1st call is f(L=1stCharacter, R=2ndCharacter)
               -                    ...then calls are f(L=previousResult, R=nextCharacter)
ØẠ             -     alphabet characters = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz"
  ŒH           -     split in half = ["ABCDEFGHIJKLMNOPQRSTUVWXYZ","abcdefghijklmnopqrstuvwxyz"]
     €         -     for each:
    ċ          -       count occurrences (of R)
               -                          e.g.: 'W' -> [1,0]; 'c' -> [0,1]; '@' -> [0,0]
      ḅ-       -     convert from base -1             -1             1             0
        N      -     negate                            1            -1             0
         ⁸     -     chain's left argument (i.e. L)
          ṙ    -     rotate left by (the negate result)
           ;   -     concatenate R

```
> 3 votes

# Answer
# K4, ~~43~~ 33 bytes

**Solution:**

```
""{.q.rotate[-/y in'.Q`A`a;x],y}/

```

**Examples:**

```
q)k)""{.q.rotate[-/y in'.Q`A`a;x],y}/"Cb-Ad"
"Ab-Cd"
q)k)""{.q.rotate[-/y in'.Q`A`a;x],y}/"ogl-edocf"
"code-golf"
q)k)""{.q.rotate[-/y in'.Q`A`a;x],y}/"ti HIs SSta ET!"
"tHis IS a tEST!"

```

**Explanation:**

Iterate over the input string, rotating the previous output by 1, -1 or 0 depending upon it's position in the list "a-zA-Z".

```
""{.q.rotate[-/y in'.Q`A`a;x],y}/ / the solution
""{                            }/ / iterate (/) over, starting x as ""
                             ,y   / append y to
   .q.rotate[             ;x]     / rotate x by ...
                    .Q`A`a        / the lists "a..z" and "A..Z"
               y in'              / y in each (') alphabet?
             -/                   / subtract (-) over (/)

```

**Notes:**

* -10 bytes with inspiration from the 05AB1E solution
> 3 votes

# Answer
# JavaScript (Node.js), ~~116~~ 102 bytes

```
f=(s,i=1)=>s[i]?f(s.replace(RegExp(`^(.)(.{${i}})(?=[A-Z])|^(.{${i}})(.)(?=[a-z])`),"$4$3$2$1"),i+1):s

```

Try it online!

## Original (~~116~~ ~~111~~ 106B)

~~`s=>Buffer(s).map((x,i)=>s=(t=s[S="slice"](i),i<2)?s:x>64&x<91?s[S](1,i)+s[0]+t:x>96&x<123?s[i-1]+s[S](0,i-1)+t:s)&&s`~~

~~`s=>Buffer(s).map((x,i)=>i<2|--x%32>25|x<64?s:s=[s[S="slice"](1,i)+s[0],s[i-1]+s[S](0,i-1)][+(x>95)]+s[S](i))&&s`~~

`s=>Buffer(s).map((x,i)=>!i|--x%32>25|x<64?s:s=(w=x>95,t=s.slice(1-w,i-w),w?s[i-1]+t:t+s[0])+s.slice(i))&&s`
> 2 votes

# Answer
# Haskell, 122 92 bytes

Thanks to BWO for the suggestions! I also saved a lot by taking a slightly different approach than my original answer.

```
l@(a:b)!c|'`'<c,c<'{'=last l:init l++[c]|'@'<c,c<'['=b++[a,c]|0<1=l++[c]
f(c:s)=foldl(!)[c]s

```

Try it online!
> 2 votes

# Answer
# Haskell, ~~101~~ 91 bytes

<sup>-10 bytes inspired by Curtis Bechtel's answer (use `'@'<c,c<'['` over `elem c['A'..'Z']` and the according range for lower-cased letters).</sup>

```
g(x:y)=foldl((<>pure).(!))[x]y
x@(a:b)!c|'`'<c,c<'{'=last x:init x|'@'<c,c<'['=b++[a]|0<1=x

```

Try it online!

## Explanation / Ungolfed

The operator `(!)` takes a non-empty string `x` on which we can pattern-match and a character:

```
x@(a:b) ! c
  | '`' < c, c < '{' = last x : init x  -- rotate x to the right by one
  | '@' < c, c < '[' = b ++ [a]         -- rotate x to the left by one
  | otherwise = x                       -- keep x as is

```

Now we can reduce the input's tail from the left to the right, starting with the first character of the input using:

```
\b a -> b!a ++ [a]

```
> 2 votes

# Answer
# Ruby, 51 bytes

```
->s{w=[];s.map{|x|w.rotate!(x=~/\W/||?_<=>x)<<x};w}

```

Try it online!

Input and output are arrays of characters

### The trick:

The code is pretty straightforward, except perhaps the rotation part:

```
(x=~/\W/||?_<=>x)

```

x is a single character, which could be a letter, the first expression `x=~/\W/` returns `nil` if it's a letter, and 0 otherwise. If it's 0, we're done, if not, the logical `or` checks the second expression: `?_<=>x` returns -1 for upper case and 1 for lower case. So the rotation is:

* -1 (1 to the left) for upper case
* +1 (1 to the right) for lower case
* 0 (no rotation) if it's not a letter
> 2 votes

# Answer
# Red, 110 bytes

```
func[s][p: s forall s[if all[(a: first s)>#"@"a < #"["][move p back s]if all[a >#"`"a <#"{"][move back s p]]p]

```

Try it online!

## Explanation:

```
f: func [ s ] [
    p: s                                ; store the starting position of the string in p
    forall s [                          ; iterate through the entire string
        a: first s                      ; store the current character in a
        if all [ a > #"@" a < #"[" ] [  ; if `a` is a uppercase letter
            move p back s               ; move the starting char to the position before current
        ]
        if all [ a > #"`" a < #"{" ] [  ; if `a` is a lowercase letter
            move back s p               ; move the character before the current one to the start
        ]
    ]
    p                                   ; return the string
]

```
> 2 votes

# Answer
# Japt, ~~17~~ ~~16~~ 14 bytes

Takes input as an array of characters, outputs a string

```
;rÏiXéCøY -BøY

```

Try it

---

## Explanation

```
 rÏ                :Reduce by passing the current result (X) & the current element (Y) through a function
   i               :  Prepend to Y
    Xé             :  X rotated right by
;     B            :    Uppercase alphabet
       øY          :    Contains Y?
          -        :    Subtract
;          C       :    Lowercase alphabet
            øY     :    Contains Y?

```
> 2 votes

# Answer
# Perl 6, 47 bytes

```
*.reduce:{|@$^a.rotate($^b~~/\w/&&'_'leg$b),$b}

```

Try it online!

Works on an array of chars.
> 2 votes

# Answer
# Jelly, 19 bytes

```
W€ḷṙ01ŒlƑ?-ŒuƑ?};ʋ/

```

Try it online!
> 1 votes

# Answer
# , ~~107~~ ~~102~~ 100 bytes

Massive because R's string manip is bulky. Can anyone get it under 100?

-5 bytes using the "set loop variables to F to avoid initializing" trick.

-2 bytes by assuming all characters are printable and using `2*!k%%97>25` rather than `2*k%in%97:122` for testing lower case, using operator precedence.

```
function(x){for(k in u<-utf8ToInt(x))u[1:F-1]=u[(1:(F=F+1)+k%in%65:90-2*!k%%97>25)%%F];intToUtf8(u)}

```

Try it online!
> 1 votes

# Answer
# Java 10, ~~149~~ 119 bytes

```
s->{for(int i=1;i<s.length();)s=s.replaceAll("^(.)(.{"+i+"})(?=[A-Z])|^(.{"+i+++"})(.)(?=[a-z])","$4$3$2$1");return s;}

```

Port of *@ShieruAsakoto* JavaScript answer, so make sure to upvote him.

Try it online.

**Explanation:**

```
s->{                          // Method with String as both parameter and return-type
  for(int i=1;i<s.length();)  //  Loop `i` in the range [1, length)
    s=s.replaceAll("^(.)(.{"+i+"})(?=[A-Z])|^(.{"+i+++"})(.)(?=[a-z])","$4$3$2$1");
                              //   Rotate the substring of [0, i] either left or right
  return s;}                  //  Return the modified input-String as result

```
> 1 votes

# Answer
# Japt, ~~25~~ 23 bytes

*I give up, Can't make it shorter*

-2 bytes from @ETHproductions

```
£=¯Y éXè\a -Xè\A)+UsYÃU

```

---

```
£=¯Y éXè\a -Xè\A)+UsYÃU     Full program. Implicit input U
£                           map each char
 =                          set U equal to:
  ¯Y                        U sliced to current mapped value
    éXè\a -Xè\A)            and rotated left or right 1 char
                +UsY        append the non-sliced U value
                      ÃU    Output U

```

Try it online!
> 1 votes

# Answer
# Stax, 32 bytes

```
éG7[Æ┐äZ▬Θε♫∙~╞ÉH╔u╬←J╛ü╢(┼▒uX)Ü

```

Run and debug it

```
B]s{c97 123:bsaa|)sc65 91:bsaa|(s+c}fd  #Full program, unpacked, implicit input
B]s                                     #Unons-left, singleton, swap top 2 of stack
   {c                                   #Copy iterative letter
     97 123                             #Put 97 and 123 on stack(lower case)
           :bsaa                        #Check if iterative letter is between range, swap orientation back to proper order
                |)                      #Rotate if the letter is within range
                  sc                    #Swap top 2 and copy top
                    65 91               #Put 65 and 91 on stack (Capitals)
                         :bsaa          #Check if iterative letter is between range, swap orientation back to proper order
                              |(        #Rotate if the letter is within range
                                s+c     #swap, concat and copy
                                   }fd  #remove duplicate of original answer after loop and implicitly print

```

A lot of stack swapping which is probably unnecessary. I really would like to get this down more, but I was strugging with the ordering of the stack. Maybe somebody can figure it out if they are bored. Will keep working on it.
> 1 votes

# Answer
# Attache, 69 bytes

```
~Fold[{s'r.=_'sp;Rotate[s,&`-!Has&r[0]=>ALPHA'alpha]+r}@SplitAt]#Iota

```

Try it online!

## Explanation

### General shape

The function looks generally like this:

```
~Fold[{...}]#Iota

```

Which folds `{...}` over each member in the range from `0` to `#input - 1` (`Iota`), starting with the input as a seed.

### The inner function

The following function is called as `f[building, index]` and is called with each index from `0` to `#input` exclusive. `@SplitAt` calls `SplitAt` on these arguments, splitting the input string on `index`.

```
{s'r.=_'sp;Rotate[s,&`-!Has&r[0]=>ALPHA'alpha]+r}
{                                               }    anonymous function taking the split string
                                                     e.g.: ["cd-", "Adf!"]
      _'sp                                           concat the input with a space
                                                     e.g.: ["cd-", "Adf!", " "]
                                                     (this is to handle index = 0)
 s'r.=                                               `s` is the first member, and `r` is the second
           Rotate[s,                         ]       rotate `s` by:
                                  ALPHA'alpha          over uppercase and lowercase alphabets:
                        Has&r[0]=>                       test if r[0] is in each alphabet
                                                       e.g.: [true, false]
                    &`-!                               subtract the second from the first
                                                       e.g.: (true - false) = 1 - 0 = 1
                                                     s is rotated according to the following map:
                                                       uppercase =>  1
                                                       symbol    =>  0
                                                       lowercase => -1
                                              +r     append the right portion of the string

```

Essentially, this function rotates the left portion of the string according to the first character of the right portion.
> 1 votes

# Answer
# Charcoal, 20 bytes

```
ＦＳ≔⁺⭆ω§ω⁻⁺λ№αι№βιιωω

```

Try it online! Link is to verbose version of code. Explanation:

```
ＦＳ

```

Loop over the input characters.

```
≔⁺⭆ω§ω⁻⁺λ№αι№βιιω

```

Map over the string of collected characters so far, cyclically indexing into the collected characters so far with the index incremented or decremented if the current character is upper or lower case respectively. This completes the rotation. The next character is then concatenated, and the result assigned back to the string.

```
ω

```

Print the result.
> 1 votes

# Answer
# MATL, 20 bytes

```
ttYo-ZS"X@q:&)w@YSwh

```

Try it online!

-4 bytes thanks to Luis Mendo.

Converts uppercase/lowercase/non-letter to \[-1,0,1\] (first half of the program). Applies circshift consecutively (second half). I'm wrecking my brain if there's a better way to map uppercase/lowercase to \[-1,0,1\] (see the second version), and perhaps a way to reverse the string right away so as to get rid of the two `w`'s needed for the `&)`.
> 1 votes

# Answer
# Retina, ~~67~~ ~~64~~ 58 bytes

```
^
¶
+`(.*)(.)¶([a-z])|(.)(.*)¶([A-Z])|¶(.)
$2$1$3$5$4$6$7¶

```

-9 bytes thanks to @Neil removing the three unnecessary `?` I had added, as well as the unnecessary `(.*)` in the else-case.

Try it online or verify all test cases. (NOTE: Outputs with a trailing newline. The header in the test suite is to test each input-line as a separate test case, and the footer is to remove that trailing newline for a more compact output.)

**Explanation:**

Prepend a newline before the input:

```
^
¶

```

Continue replacing as long as we can find a match:

```
+`

```

Everything else is three different checks merged together:

If the character right after the newline is lowercase letter: rotate everything before the newline once towards the right, and then append that character and the newline:

```
(.*)(.)¶([a-z])
$2$1$3¶

```

If the character right after the newline is an uppercase letter: rotate everything before the newline once towards the left, and then append that character and the newline:

```
(.)(.*)¶([A-Z])
$2$1$3¶

```

Else (neither a lowercase nor uppercase letter): simply shift the newline once towards the right for the next 'iteration':

```
¶(.)
$1¶

```

These three checks above are merged with regex OR statements (`|`) and larger group-replacements to make it act like an `if(lowercase) ... elseif(uppercase) ... else ...`:
> 1 votes

# Answer
# C (clang), ~~168~~ ~~159~~ ~~153~~ 119 bytes

```
g,i,j;f(char*a){for(i=0;a[j=i++];islower(a[i])?g=a[j],bcopy(a,a+1,j),*a=g:isupper(a[i])?g=*a,bcopy(a+1,a,j),a[j]=g:0);}

```

-26 thanks to @ceilingcat

Try it online!
> 1 votes

# Answer
# Pyth, 16 bytes

```
em=+.>k-F}RGrBd2

```

Try it here!

Explanation:

```
em=+.>k-F}RGrBd2dQ    Autofill variables
 m               Q    for each d in Q (the input):
            rBd2       Take [d, swapcase(d)]
         }RG           Figure out which are in the lowercase alphabet (returns [1,0] for lowercase, [0,1] for uppercase, [0,0] for non-letters)
       -F              Fold on subtraction (1 for lowercase, -1 for uppercase, 0 for non-letter)
    .>k                Cycle the processed part (k) of the input right by ^ steps
   +            d      Add in the new character at the end
  =   k                Store new process step back into k (k starts as an empty string)
e                     Get the (e)nd step's output.

```
> 0 votes

---
Tags: code-golf, string
---


title: Programmable Bots

text:
# Question
Title: Programmable Bots
# Game

In this challenge you will play a made-up turn-based game. The game is made up of the following elements:

* A 8x8 grid with each spot containing nothing (space), a robot (`*`), a wall (`#`), or HP (`@`)
* A public stack

---

# Robots

In this challenge, you will be playing as a robot. Each robot has health (starts at 10HP and cannot exceed it), and a register called `D` for data storage purposes, and `C` for execution (both initially 0). Each robot also has a program attached to it and a program can contain the following instructions (case-insensitive):

* `P`: Pushes the character in memory lying at position `D` (where `D` is the D register value) onto the public stack (All robots share the same stack, hence "public").
* `G`: Pops 2 values from the stack, modulo the ASCII codes by 2, NANDs them, pushes the result
* `D`: Sets the `D` register (NOT the value in memory residing at `D`) to a popped value from the public stack
* `M`: Sets the character in memory lying at position `D` to a popped value's ASCII
* `K`: Sets `C` to `D`, and `D` to 0
* `Y`: Performs a "physical" action with the robot according to:

+ `V = 32` move right on grid unless blocked by wall
    + `V = 33` move up on grid unless blocked by wall
    + `V = 34` move left on grid unless blocked by wall
    + `V = 35` move down on grid unless blocked by wall
    + `V = 36` damage all robots next to you (horizontally or vertically or diagonally or on the same grid spot) by 1HP, killing them if their HP reaches 0, but sacrifice 1HP of your own (this may kill your robot)
    + `V = 37` heal yourself by 1HP for each robot next to you, but also heal them by 2HP
    + `V = 38` break any walls around you but get damaged 1HP for each wall
    + Anything else: Your robot dies.

Where `V` = the ASCII code of the value at memory position `D`
* `I`: Pop 2 values, x and y, from the stack, and push whatever is on the grid at the x and y coordinates (pushes the character as specified at the top of this post)
* `S`: Starts a code block
* `E`: Ends a code block and pushes a special "code" value onto the stack. Any robot to try to pop this value will end up executing the code in the block, and the value will be removed from the stack.
* Anything else: Your robot dies.

Memory is initialized at the beginning of the game and the code is inserted at the beginning. Code and data share the same memory. If a robot dies, it's grid spot is replaced with HP which can be picked up by moving over it and heals you 4HP

---

## Execution

Each time it is your turn, the instruction at the position of memory `C` is executed according to the table above before incrementing register `C`.

---

# Submission

Please use this template when posting:

```
#<name of bot>
…
<your bot code>
…

```

Standard loopholes apply, and the last robot standing wins!

# Answer
# Gun Factory

Why don't you go shoot yourself in the foot?

```
S0EK

```

Constantly pushes a special execution character containing `0`, which isn't executable, thus (hopefully) making bots kill themselves.
> 3 votes

# Answer
# Priest

Let's heal up!

```
PDYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYS%EYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYYY

```

Self-explanatory. It will heal itself constantly for over 40 thousand turns. Avoids the public stack like the plague it is because of the Gun Factory.
> 1 votes

# Answer
# Virus

Spreads code which spreads code which spreads code which spreads code which kills

```
SSSSSSSSSSSSSSSSS0EGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEGKEK

```

Gun Factory is immune though. And it takes a long time to start up obviously.
> 1 votes

# Answer
# K

```
K

```

Bot does nothing but sit there and lets everyone else kill themselves (k? k.)

As it never interacts with the public stack it is never in danger of executing arbitrary code (and everyone knows how dangerous arbitrary code execution is). Could still be damaged by other bots getting close and executing `Y(36)`, but that command uses the stack, so it will be unreliable.
> 1 votes

# Answer
# FreeKills

Damages without getting damaged! (but takes a long time..)

```
S$EPPPGGDYPDS00000000000000000000000%EYPPGDK

```
> 0 votes

# Answer
# Stack Simplification Unit

Collapse the stack, two pops and one push at a time.

```
GK

```

Probably dies to the pesky Gun Factory quite quickly, unfortunately.
> 0 votes

# Answer
# Duplicity

Take from some, give to others.

```
S EPPGPGDYYYPDYYYPDYYYPDYYYPPGDK$0%0"1

```

Attacks bots to the right, heals bots to the left. Very vulnerable to stack pollution, which is rampant.

Code explanation:

```
S E                                    - define (32, move right) at 1
   PPGPGD                              - set reg D to 1
         YYY                           - go right thrice
                                $      - define (36, attack) at 32
            PD                         - set reg D to 32
              YYY                      - attack thrice
                                    "  - define (34, move left) at 36
                 PD                    - set reg D to 36
                   YYY                 - move left thrice
                                  %    - define (37, heal) at 34
                      PD               - set reg D to 34
                        YYY            - heal thrice
                                     1 - define (49) at 37
                           PPGD        - set reg D to 0
                               K       - set reg C to 0

```
> 0 votes

---
Tags: king-of-the-hill
---


title: No trailing but(t)s please!

text:
# Question
Title: No trailing but(t)s please!
This challenge was inspired by Yeah But No But Yeah.

---

maxb´s colleague recently sent him the following piece of JavaScript as a joke:

```
let butScript = (nrOfButs) => {
    for(var i = 0; i < nrOfButs; i++){
        if(i % 3 == 0){
            console.log("Yeah")
        }
        if(i % 2 == 0){
            console.log("But")
        }
        if(i % 3 == 1){
            console.log("No")
        }
    }
}

```

Since the code is not only overly long but also incorrect, I´ll suggest to maxb´s boss to fire that guy and hire one of you folks instead.

I can´t guarantee anything; but I reckon there´ll be a decent wage, health insurance and possibly a company car in it. All You have to do is A) correct the code, so the Number of Buts printed is the same as asked in the parameter B) correct the grammar. (see below) C) make it as short as possible.

He might as well block my calls after that because he doesn´t like pennypickers; but who knows.

## Input

a non-negative integer, in any convenient way

## Output

`Yeah` and `No`, mostly separated by `But`s. The code above and the examples below should clarify the pattern.
Output should never end in a `But`. And a sentence should always end with a stop (`.`) or exclamation mark; i.e. put one after every `No` that is directly followed by a `Yeah` (without a `But`) and one at the end of the output.
A single trailing "Yeah." may be printed (if you want to think positive), but that´s not a must.

You may print the output or return a list of strings.
Trailing blanks are acceptable, as well as a single leading **or** trailing newline.

## examples (input =\> possible output)

```
input 0:

Yeah.

input 1:

Yeah
But
No.

input 2:

Yeah
But
No
But
Yeah.

input 3:

Yeah
But
No
But
Yeah
But
No.
Yeah!       <optional>

...

input 5:

Yeah
But
No
But
Yeah
But
No.
Yeah
But
No
But
Yeah.

```

# Answer
# JavaScript (Node.js), 80 bytes

```
a=>{s='';for(i=0;i<a+1;i++)s+=(i%2==0?'yeah':'no')+(i<a?'\nbut\n':'.');return s}

```

Try it online!
> 5 votes

# Answer
# Python 2, ~~105~~ 81 bytes

```
f=lambda n,s=1:(n|s)*' 'and'\nBut\n'.join((['Yeah','No']*2)[:n+1])+'.\n'+f(n-3,0)

```

Try it online!

\- 24 bytes, thanks to ovs
> 4 votes

# Answer
# Retina, ~~48~~ 47 bytes

```
.+
*
L$`__?_?|^
Yeah$&.
__
_¶But¶Yeah
_
¶But¶No

```

Try it online! Explanation:

```
.+
*

```

Convert to unary.

```
L$`__?_?|^
Yeah$&.

```

Match up to three `_`s at a time. Also handle the zero edge case as a match. Each match results in at least a `Yeah` with a trailing `.`.

```
__
_¶But¶Yeah

```

A match of 2 or 3 `_`s results in a `But` `Yeah` in the second position.

```
_
¶But¶No

```

The other `_`s turn into `But` `No`.

52 bytes in Retina 0.8.2:

```
.+
$*
M!`11?1?
%`^.*
Yeah$&.
11
1¶But¶Yeah
1
¶But¶No

```

Try it online! Explanation:

```
.+
$*

```

Convert to unary.

```
M!`11?1?

```

Match up to three `1`s at a time.

```
%`^.*
Yeah$&.

```

Add a leading `Yeah` and trailing `.` for each match. The `^.*` allows it to work for the zero case too.

```
11
1¶But¶Yeah
1
¶But¶No

```

Add in the `But` `Yeah` and/or `No` as above.
> 2 votes

# Answer
# 05AB1E,  ~~44~~  ~~42~~ ~~34~~ 31 bytes

Crossed out  44  is no longer regular 44 :)

```
[Ðd_#3‚ßÝ„¥æ€¸#sè'€³¶.øý'.«™,3-

```

Also prints the optional `Yeah.`.

Try it online or verify all test cases.

**Explanation:**

```
[               # Loop indefinitely:
 Ð              #  Triplicate the top value
                #  (which is the implicit input `n` in the first iteration)
  d_            #  Pop one copy, and if it's negative:
    #           #   Stop the infinite loop
  3‚ß           #  Take the max `m` of another copy of `n` and 3
     Ý„¥æ€¸#sè  #  Create an alternating list of "yeah" and "no" of size `m`
  '€³¶.ø       '#  Push "\nbut\n"
        ý       #  Join the alternating list with this as delimiter
  '.«          '#  Append a trailing "."
     ™          #  Titlecase each word in this string
      ,         #  Pop and print it with trailing newline
  3-            #  Decrease `n` by 3 for the next iteration

```

See this 05AB1E tips of mine (section *How to use the dictionary?*) to understand why `„¥æ€¸` is "yeah no" and `'€³` is "but".
> 2 votes

# Answer
# JavaScript (Node.js), 82 bytes

```
_=>_>3?f(3)+f(_-3):[...Array(_+1)].map((a,i)=>i%2?'No':'Yeah').join`\nBut\n`+'.\n'

```

Try it online!
> 1 votes

# Answer
# C (clang), ~~80~~ 74 bytes

```
f(a,i){for(i=0;-i>~a;)printf("%s%s\n","YeahNo"+i%2*5,i++<a?"\nBut":".");}

```

-6 bytes thanks to @Jonathan Frech

Try it online!
> 0 votes

---
Tags: code-golf, string
---


# Question
Title: Build a 4-vertex Connectedness Tester using NAND gates
A connected graph is a graph that contains a path between any two vertices.

### Challenge

Build a \[2-input NAND-gate\] circuit that determines whether a 4-vertex graph is connected.
(A gate's 2 inputs *can* be the same input bit or other gate.)
Output True if the graph is connected, and False otherwise.

### Input

The six possible edges of a simple graph with 4 vertices:

\[ 0e1 , 0e2 , 1e2 , 0e3 , 1e3 , 2e3 \]

where aeb represents whether there is an edge between vertices ***a*** and ***b***

Connectedness is equivalent to the following conditions:

* If less than 3 inputs are True then output False.
* If more than 3 inputs are True then output True.
* If exactly 3 inputs are True and they form a triangle then output False.
* Otherwise, output True.

The answer that uses the fewest gates wins.  Ties will be broken by
the lowest circuit depth (length of longest path(s) from input to output).

# Answer
> 5 votes
# 30 NANDS

Instead of asking when do we get a 1, I asked the question when do we get a 0. It's better to ask it this way round because there are less 0's than 1's.

Here's the distribution according to number of edges (6th row of pascal's triangle)

```
Edges     0  1  2  3  4  5  6
Frequency 1  6 15 20 15  6  1 (total 64)
Output    0  0  0  *  1  1  1
* = 0 if triangle (4 possibilities) 1 if claw (4 possibilities)
1 if two opposite edges and one other (12 possibilities)

```

Asking the question this way round, we get the following diagram and expression

```
 ___D___
|\     /|
| E   F |
|  \ /  |
A   X   C
|  / \  |
| /   \ |
|/__B__\|

(A|C|D|B)&(A|D|E)&(D|B|E|F)&(C|B|E)&(A|C|E|F)&(D|F|C)&(A|F|B)

```

We assume the output will default to 1, but will change to 0 under any of the following conditions

1.A 0 for three adjacent edges (test 3 inputs)

2.A 0 for two opposing pairs of edges (test 4 inputs)

The terms above are already ordered in the manner that will enable them to be grouped as below. (Incidentally, this version of the expression is rotationally symmetrical abouth the AFB vertex.)

```
((A|D)|((C|B)&E))&((B|E)|((D|F)&C))&((C|F)|((A|E)&D))&(A|F|B)    =6 inverters
   1      1  1       1      1  1       1      1  1      1        =10 (7 OR with both inputs inverted, 3 NAND)
      2                 2                 2               2      =8  (4 OR with one input inverted)
                 2                 2                 2           =6  (3 AND)
                                                        Total    =30

```

The score for each `&` or `|` is placed below the symbol and justified as follows:

Level 0: We invest in an inverter for each input: 6 NANDS

Level 1: We can build an OR from a NAND gate by putting an inverter at the input (total 3 NANDS) but as we already invested in 6 NANDS in the previous step we can make 7 OR gates from 7 NAND gates. We also need 3 AND gates. For these, we will just use NANDs and leave the output inverted. 10 NANDS

Level 2: Again we build 4 OR gates from NAND gates. In each case we have 1 input from an OR gate, so we have to invert that. But the other input is already inverted (coming from one of the NANDs in the previous step that corresponds to a `&` symbol in three cases, and from an inverter in the last one) so we only need 2 gates for each OR functionality. 4 * 2 =8

Level 3: We now need to AND the four outputs together. This requires 3 AND gates, each built from 2 NANDs, 3 * 2 = 6

That's a total of 30 NAND gates, with a max depth of 2+2+4=8 NANDs for branches with an `|` at level 1 or 3+1+4=8 NANDs for branches with an `&` at level 1.

The following Ruby script confirms visually that the above expression is valid.

```
64.times{|i|
  a=i%2
  b=i/2%2
  c=i/4%2
  d=i/8%2
  e=i/16%2
  f=i/32%2

puts i, ((a|d)|((c|b)&e))&((b|e)|((d|f)&c))&((c|f)|((a|e)&d))&(a|f|b)

puts " ___#{d}___
|\\     /|
| #{e}   #{f} |
|  \\ /  |
#{a}   X   #{c}
|  / \\  |
| /   \\ |
|/__#{b}__\\|

"
}

```

# Answer
> 8 votes
# 19 NANDs

There is no simpler circuit than this.

There is code for testing it below the picture. As for understanding it, that's difficult. There are a couple of IF gates there, and the inputs are kinda grouped into a triangle with the free corner lines added for analysis one by one, but not in a simple way. If anyone manages to understand it, I will be impressed.

Verilog code with testing:

```
// 4-vertex Connectedness Tester
// Minimal at 19 NANDs
//
// By Kim Øyhus 2018 (c) into (CC BY-SA 3.0)
// This work is licensed under the Creative Commons Attribution 3.0
// Unported License. To view a copy of this license, visit
// https://creativecommons.org/licenses/by-sa/3.0/
//
// This is my entry to win this Programming Puzzle & Code Golf
// at Stack Exchange:
// https://codegolf.stackexchange.com/questions/69912/build-a-4-vertex-connectedness-tester-using-nand-gates/
//
// I am sure there are no simpler solutions to this problem.
// It has a logical depth of 11, which is deeper than
// circuits using a few more NANDs.

module counting6 ( in_000, in_001, in_002, in_003, in_004, in_005, in_006, out000 );
  input  in_000, in_001, in_002, in_003, in_004, in_005, in_006;
  output out000;
  wire   wir000, wir001, wir002, wir003, wir004, wir005, wir006, wir007, wir008, wir009, wir010, wir011, wir012, wir013, wir014, wir015, wir016, wir017;

  nand gate000 ( wir000, in_000, in_000 );
  nand gate001 ( wir001, in_001, in_003 );
  nand gate002 ( wir002, wir001, wir000 );
  nand gate003 ( wir003, in_002, wir002 );
  nand gate004 ( wir004, wir002, wir002 );
  nand gate005 ( wir005, wir004, in_002 );
  nand gate006 ( wir006, wir005, wir004 );
  nand gate007 ( wir007, in_005, wir006 );
  nand gate008 ( wir008, in_003, wir006 );
  nand gate009 ( wir009, in_004, wir003 );
  nand gate010 ( wir010, wir003, wir009 );
  nand gate011 ( wir011, wir009, wir000 );
  nand gate012 ( wir012, wir011, in_001 );
  nand gate013 ( wir013, wir008, wir012 );
  nand gate014 ( wir014, wir013, in_005 );
  nand gate015 ( wir015, wir006, wir013 );
  nand gate016 ( wir016, wir015, wir007 );
  nand gate017 ( wir017, wir016, wir010 );
  nand gate018 ( out000, wir014, wir017 );
endmodule

module connecting6_test;
   reg [5:0] X;
   wire a;

  counting6 U1 (
  .in_000 (X[0]),
  .in_001 (X[1]),
  .in_002 (X[2]),
  .in_003 (X[3]),
  .in_004 (X[4]),
  .in_005 (X[5]),
  .in_006 (X[6]),
  .out000 (a )
  );

  initial begin
    X = 0;
  end

  always
    #10  X = X+1;

 initial  begin
    $display("\t\t     \t_");
    $display("\t\ttime,\t \\db/_,\tconnected");
    $monitor("%d,\t%b,\t%d",$time, X, a );
  end

  initial
   #630  $finish;

endmodule

// iverilog -o hello hello.v
// vvp hello

```

Kim Øyhus

# Answer
> 1 votes
# Mathematica, 17 gates

We simply enumerate all of the rules, construct the boolean function, and minimize it in `NAND` form.

```
#->If[Total@#<3||
       MemberQ[{{1,1,1,0,0,0},{1,0,0,1,1,0},{0,1,0,1,0,1},{0,0,1,0,1,1}},#]
       ,0,1] /.{1->True,0->False}& /@
     Tuples[{0,1},6];
BooleanMinimize[BooleanFunction[rule], "NAND"]

```

---

**Result**:

```
(#1⊼#2⊼#4)⊼(#1⊼#2⊼#5)⊼(#1⊼#2⊼#6)⊼(#1⊼#3⊼#4)⊼ \
(#1⊼#3⊼#5)⊼(#1⊼#3⊼#6)⊼(#1⊼#4⊼#6)⊼(#1⊼#5⊼#6)⊼ \
(#2⊼#3⊼#4)⊼(#2⊼#3⊼#5)⊼(#2⊼#3⊼#6)⊼(#2⊼#4⊼#5)⊼ \
(#2⊼#5⊼#6)⊼(#3⊼#4⊼#5)⊼(#3⊼#4⊼#6)⊼(#4⊼#5⊼#6)&

```

, where `#1...#6` are 6 slots for arguments.

---

**Test cases**:

```
f=%; (* assign the function to symbol f *)

f[True, True, True, True, False, False]
(* True *)

f[True, True, False, True, False, False]
(* True *) (*, three Trues do not form a triangle *)

f[True, True, True, False, False, False]
(* False *) (*, three Trues form a triangle *)

```

# Answer
> 1 votes
# 64 NANDs

The six edges can be split up into three pairs of opposite edges. For a graph to be connected, there must either be two opposite edges as well as a third edge, or three edges connected to the same vertex.

```
       •
       U

   Z   •   Y
    V     W
 •     X     •

```

The opposite pairs are UX, VY, WZ, so:

```
A = U+V   ;3 gates
B = W+X
C = Y+Z

D = UV(B+C)  ;2+2+3=7 gates
E = WX(A+C)
F = YZ(C+A)

Result = D+E+F+UVW+UYZ+XVZ+XWY ; 18 + 16 = 34 gates

```

Building AND and OR gates in the usual way, the total number of gates used is `3*3+7*3+34` = 64.

---
Tags: decision-problem, graph-theory, atomic-code-golf, logic-gates
---


title: Output an upside-down tent

text:
# Question
Title: Output an upside-down tent
Given an integer, output an upside-down tent.

The input determines both the size of the tent (absolute value) and whether the entrance is on the left side (negative numbers) or the right side (positive numbers).

```
If input = -1:
____
\/_/

If input = -2:
________
\  /   /
 \/___/

If input = -3:
____________
\    /     /
 \  /     /
  \/_____/

If input = 1:
____
\_\/

If input = 2:
________
\   \  /
 \___\/

If input = 3:
____________
\     \    /
 \     \  /
  \_____\/

et cetera

```

Note that the top of the tent (i.e. the last line) has `2 * abs(input) - 1` underscores.

There can be *no* leading spaces, such that the first line directly starts with an underscore.

Assume that the input will never be `0`.

Your code should be as short as possible.

*This challenge is based on a chat mini challenge by Helka Homba, which is allowed to be used in real challenges under the conditions of Calvin's Hobbies Public License*.

# Answer
# MATL, ~~55~~ ~~53~~ ~~52~~ 51 bytes

```
|95cy4*Y"DXytPEt0*yvG0>?P_]!'\/ 'w)95JG|G0<yEq:++&(

```

Try it online!

### Explanation

Let `N` denote the input. The code proceeds in three steps.

**First**, the first line of `4*N` underscores is built as a string and is displayed (which removes it from the stack).

**Second**, the "frame" of the tent is built using the two types of slashes. To do this, a numerical 2D array is created which contains `1` and `2` corresponding to the two types of slashes, and `0` for space.

This is done concatenating four matrices:

1. An identity matrix of size `abs (N)`;
2. A matrix of the same size containing `2` in the antidiagonal;
3. A null matrix of the same size;
4. A copy of matrix 2.

Concatenating these four matrices vertically gives, using `N=3` as an example, the following `4*N × N` matrix:

```
1 0 0
0 1 0
0 0 1
0 0 2
0 2 0
2 0 0
0 0 0
0 0 0
0 0 0
0 0 2
0 2 0
2 0 0

```

(which, transposed, begins to look like the tent).

We now take care of the sign of the input. If it is positive we simply transpose the above matrix and index into the string `'\/ '`. Indexing is 1-based and modular, so `1` becomes `'\'`, `2` becomes `'/'` and `0` becomes `' '`, producing the 2D char array

```
\    /     /
 \  /     /
  \/     /

```

On the other hand, if the input is negative we vertically flip and arithmetically negate the `4*N × N` matrix, producing

```
-2  0  0
 0 -2  0
 0  0 -2
 0  0  0
 0  0  0
 0  0  0
-2  0  0
 0 -2  0
 0  0 -2
 0  0 -1
 0 -1  0
-1  0  0

```

Index `-1` now refers to `'/'` and `-2` to `'\'`. That is, the two types of slashes have been interchanged, as required. Again transposing and indexing into the string `'\/ '` thus gives the reversed tent:

```
\     \    /
 \     \  /
  \     \/

```

**Third**, underscores need to be filled into part of the last row of the 2D char array. The horizontal position of this line depends on the sign of the input, and its lenght is `abs(N)`.

Once the corresponding spaces have been replaced by underscores, the result is implicitly displayed, below the initial line of underscores that was already displayed in the first step.
> 11 votes

# Answer
## Javascript (ES6), 139 bytes

Builds the tent recursively:

```
f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`
`+r(n)+(N<0?a+b+'/':'\\'+b+a):r(i*2,1)

```

### Ungolfed and commented

```
f = (
  N,                                  // N is the original parameter (remains unchanged)
  n = N > 0 ? N : -N,                 // n is initialized to abs(N)
  i = 0,                              // i is the row counter (*2)
  r = (j, i) => ' _'[i||0].repeat(j), // helper function to repeat ' ' or '_' j times
  a = `\\${r(i)}/`,                   // a = '\ /' pattern
  b = r(n*2+i-1, +!i)                 // b = padding pattern filled with ' ' or '_'
) =>
  n-- ?                               // if we haven't made it yet to the top row:
    f(N, n, i+2) + `\n` +             //   - compute next row(s) / append line break
    r(n) +                            //   - append leading spaces
    (N < 0 ? a+b+'/' : '\\'+b+a)      //   - append a/b patterns according to N sign
  :                                   // else:
    r(i*2, 1)                         //   - return top row, made of '_' characters

```

### Examples

```
var f=(N,n=N>0?N:-N,i=0,r=(j,i)=>' _'[i||0].repeat(j),a=`\\${r(i)}/`,b=r(n*2+i-1,+!i))=>n--?f(N,n,i+2)+`
`+r(n)+(N<0?a+b+'/':'\\'+b+a):r(i*2,1)

console.log(f(3));
console.log(f(-4));
```
> 9 votes

# Answer
# Python 2, ~~143 141 139 138~~ 137 bytes

-2 bytes thanks to @Sp3000 (no need to parenthesise exec in Python 2)
-1 byte thanks to @Sp3000 (use `cmp`)

```
def f(n):d=cmp(n,0);a,b='\/'[::-d];s=n*d;x=2*s-1;y=4*s;print'_'*y;i=0;exec"print' '*i+(b+' '*(y-3-x-i-i)+a+'_ '[s-i>1]*x+a)[::d];i+=1;"*s

```

Test it at **ideone**

First we see if `n` is negative and make `d` `+1` if it is and `-1` if not.
Then we select the two slashes, `a` and `b`, using `d` such that `a='\', b='/'` when `n` is positive and `a='/', b='\'` when `n` is negative.
Next we set `s=abs(n)` which may be achieved by `s=n*d`.
Then we calculate the number of `_` at the top (bottom of the picture), which is also the number of  in the side of the tent as `x=2*s-1`.
Then we calculate the number of `_` at the base of the tent (top of the picture), and store it as `y=4*s` since it will be used in the loop to create the rest of the tent.
Now we print the base of the tent using `print'_'*y`.
Then we print the rest of the tent by executing `s` print statements with a looping variable `i` initialised to `0` which increments by `1` for each print statement.
The rest of the tent then has `y-3-x-i-i` spaces in the door and `x` spaces in the body until the top is reached, when `s-i>1` evaluates to False, picking the `_` from `'_ '`.
For a positive, left-door, tent the whole of the tent, excluding the leading spaces is back-to-front, so it is reversed while the positive, 'right-door', tent is not with `[::d]`.
> 6 votes

# Answer
## Python 2, 121 bytes

```
def f(n):i=k=abs(n);print'_'*k*4;exec"print' '*(k-i)+r'\\\%%s%\*%c%%*sc/'[n<0::2]%(' _'[i<2]*(2*k-1))%(2*i-1,47);i-=1;"*k

```

Just a lot of string formatting.
> 5 votes

# Answer
# C#, ~~215~~ 214 bytes

```
string t(int N){var n=N<0;N=n?-N:N;var t=new string('_',4*N);for(int i=0;i<N;){string f=new string(i<N-1?' ':'_',2*N-1),p=new string(' ',2*N-2*i-2);t+='\n'+new string(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

```

There's a possibility to save a few bytes when using `using s=string;` beforehand.

```
s t(int N){var n=N<0;N=n?-N:N;var t=new s('_',4*N);for(int i=0;i<N;){s f=new s(i<N-1?' ':'_',2*N-1),p=new s(' ',2*N-2*i-2);t+='\n'+new s(' ',i++)+'\\'+(n?p+'/'+f:f+'\\'+p)+'/';}return t;}

```

which would be 15 (using) + 184 (method) = 199 bytes.
> 5 votes

# Answer
## PowerShell v2+, ~~217~~ ~~205~~ ~~190~~ ~~187~~ 184 bytes

```
param($b)"_"*(($a=[math]::Abs($b))*4);$z,$y='/\'[($b=$b-lt0),!$b]
((($x=1..$a|%{($w=" "*($_-1))+$z+" "*(2*($a-$_))+$y+(' ','_')[$_-eq$a]*($a*2-1)+$y+$w})|%{-join$_[($a*4)..0]}),$x)[$b]

```

Takes input `$b` as an integer. Note that if `$b` is negative, you need to explicitly surround it with parens to cast it appropriately (see examples), else PowerShell will think it's a string.

Regardless of which direction the tent is facing, the first line is the same, a bunch of underscores; exactly `4*abs(input)` many of them, actually. That number is also stored into `$a` for use later. Additionally, now that we have the absolute value of `$b` stored into `$a`, we turn `$b` into a Boolean for its sign, and choose our slashes stored into `$y` and `$z`.

The next line is constructing and formulating the output, and it's a doozy, so let's break it down.

We're essentially indexing into an array of two elements, `(big long calculations saved into $x)` or `$x`, based on `$b`.

The calculations are where the tent body is constructed. We loop from `1..$a|%{...}`. Each iteration we're constructing a line of the tent body. We start with a number of spaces equal to the line # we're on `-1`, so that it's appropriately left-aligned. That's stored into `$w` for later, and concatenated with the appropriate slash ($z, based on `$b`), then the doorframe number of spaces, then the other slash `$y`, then either underscores or spaces depending upon if we're on the bottom line or not, then another slash `$y`, and finally the appropriate number of trailing spaces (`$w`) to construct a rectangular string. That resulting array of strings is stored into `$x`.

If the left half of the array is selected (i.e., `$b` is `False` since the input was positive), then we need to loop through `$x` and reverse each line item -- this is where the trailing spaces come into play; it allows us to simply reverse the lines rather than re-calculate distances.

If `$b` is `True`, then the right half of the array `$x` is selected instead.

In either case, the pipeline now contains an array of strings. Implicit output via `Write-Output` happens at program completion, with default newline between elements.

### Examples

```
PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (-5)
____________________
\        /         /
 \      /         /
  \    /         /
   \  /         /
    \/_________/

PS C:\Tools\Scripts\golfing> .\print-upside-down-tent.ps1 (4)
________________
\       \      /
 \       \    /
  \       \  /
   \_______\/

```
> 4 votes

# Answer
# TSQL, 195 bytes

**Golfed:**

```
DECLARE @ INT=-2
DECLARE @b INT=ABS(@),@i INT=0PRINT REPLICATE('_',4*@b)z:SET @i+=1PRINT SPACE(@i-1)+'\'+STUFF(REPLICATE(IIF(@i<@b,' ','_'),4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))+'/'IF @i<@b GOTO z

```

**Ungolfed:**

```
DECLARE @ INT=-2

DECLARE @b INT=ABS(@),@i INT=0

PRINT REPLICATE('_',4*@b)
z:
  SET @i+=1
  PRINT
    SPACE(@i-1)+'\'
    +STUFF(REPLICATE(IIF(@i<@b,' ','_'),
      4*@b-2*@i),@b*2-IIF(@<0,@i*2-1,0),1,IIF(@<0,'/','\'))
    +'/'
IF @i<@b GOTO z

```

**Fiddle**
> 4 votes

# Answer
# , 66 bytes

```
é /ä
"aDoÀñá_>ñ^hr\A\/ò^hÄX$2é_Ó_/ òÄÒ_ñ/-
ddÍÜ¨[ _]*©Ü¨ *©/Ü²¯±

```

Try it online!

This is a pretty naive approach, so I'll try to golf it down further later today. This solution contains unprintable characters, so here is a hexdump:

```
0000000: e920 2fe4 0a22 6144 6f1b c0f1 e15f 3ef1  . /.."aDo...._>.
0000010: 5e68 725c 415c 2f1b f25e 68c4 5824 32e9  ^hr\A\/..^h.X$2.
0000020: 5fd3 5f2f 20f2 c4d2 5ff1 2f2d 0a64 64cd  _._/ ..._./-.dd.
0000030: dca8 5b20 5f5d 2aa9 dca8 202a a92f dcb2  ..[ _]*... *./..
0000040: afb1                                     ..

```
> 4 votes

# Answer
# 05AB1E, 52 bytes

```
Ä©'_4®*×,FNð×'\®·<N>®Qi'_ëð}×®N>-·ð×®¹Qi'\ës'/}s'/J,

```

**Explanation**

```
                                                     # implicit input, call this A
Ä©                                                   # store abs(A) in register for later use
  '_4®*×,                                            # print 4*A underscores (tent floor)
         F                                           # for each non-floor section in range(N)
          Nð×'\                                      # push N spaces at the beginning of the
                                                     # row followed by a backslash
                  N>®Qi'_ëð}                         # if we're on the last row push an
                                                     # underscore, else a space
               ®·<          ×                        # repeat that char abs(A)*2-1 times
                             ®N>-·ð×                 # push 2*(abs(A)-(N+1)) spaces
                                    ®¹Qi'\ës'/}      # if input is positive push backslash
                                                     # else push a slash
                                               s'/   # move that char between the 2 sections
                                                     # of spaces
                                                  J, # join the row and print

```

Try it online!
> 4 votes

# Answer
# Haskell, ~~187~~ ~~184~~ 183 bytes

```
f x=unlines$[(n*4)%'_']++((' '#)<$>[0..n-2])++['_'#(n-1)]where m#i=i%' '++'\\':m!i++"/";m!i|x>0=(2*n-1)%m++'\\':(2*(n-i-1))%' '|q<-2*(n-i-1)=q%' '++'/':(2*n-1)%m;n=abs x;m%c=c<$[1..m]

```

I feel like this is not a great score for Haskell, so any ideas for improvement are welcome.

**Ungolfed**

```
tent :: Int -> String
tent x = unlines $ [replicate (n*4) '_'] ++ (row ' '<$>[0..n-2]) ++ [row '_' (n-1)]
    where row m i = replicate i ' ' ++ "\\" ++ dir m i ++ "/"
          -- direction selector
          dir m i | x > 0 = side m ++ "\\" ++ entrance i ' '
                  | 1 > 0 = entrance i ' ' ++ "/" ++ side m
          side = replicate (2*n-1)
          entrance i = replicate (2*(n-i-1))
          n = abs x

```
> 3 votes

# Answer
# C, ~~240~~ ~~207~~ 193 Bytes

```
#define P putchar
a,j,l,m;g(x,y,z){for(m=y+z+1;m--;P(m^z?l?32:95:x));}f(n){g(32,(a=abs(n))*4,0);for(P(10),j=2*(l=a)-1;l--;){for(m=a;--m>l;P(32));P(92);m=n>0?g(92,j,l*2):g(47,l*2,j);puts("/");}}

```

This time I optimized the function g(...) to use a single for loop.

```
#define P putchar
a,j,l,m;g(x,y,z){for(;y--;P(l?32:95));for(P(x);z--;P(l?32:95));}f(n){g(32,(a=abs(n))*4,0);l=a;j=2*a-1;P(10);for(;l--;){for(m=a;--m>l;P(32));P(92);m=n>0?g(92,j,l*2):g(47,l*2,j);puts("/");}}

```

This time macro X is better off as a function g(...) and since y and z are parameters in a new scope I can just decrement them in the scope of g.

```
#define P putchar
#define X(x,y,z){for(k=0;k++<y;P(l?32:95));P(x);for(k=0;k++<z;P(l?32:95));}
a,i,j,k,l,m;f(n){for(l=a=abs(n);i++<a*4;P(95));j=2*a-1;P(10);while(l--){for(m=a;--m>l;P(32));P(92);if(n>0)X(92,j,l*2)else X(47,l*2,j)puts("/");}}

```

Test with this main function; This should golf down much smaller.

```
main(c,v)char**v;
{
    f(atoi(v[1]));
}

```
> 2 votes

# Answer
# C# 241 231 Bytes

Saved 10 bytes thanks to @Kevin Cruijssen

```
using s=System.String;s f(int N){var f=N<0;N=N>0?N:-N;var o=new s('_',N*4);for(int j=0,z;j<N;){z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new s(' ',j)+'\\'+new s(' ',z)+(f?'/':O)+new s(O,j++*2)+(f?O:'\\')+new s(' ',z)+'/';}return o;}

```

Old version:

```
string f(int N){var f=N<0;N=N>0?N:-N;var o=new string('_',N*4);for(int j=0;j<N;){int z=-2*j+2*N-2;var O=j>N-2?'_':' ';o+='\n'+new string(' ',j)+'\\'+new string(' ',z)+(f?'/':O)+new string(O,j++*2)+(f?O:'\\')+new string(' ',z)+'/';}return o;}

```

Originally had the `new string(...)` as a `Func<char,int,string>` but saved one byte using the constructor. I wish `int`-\>`char` was implicit

Pretty sure my math can be fixed somehow too, but I can't see it
> 2 votes

# Answer
# Swift 2.2 421 bytes

Well... This was an attempt.

Golfed:

```
let t={(s:String,n:Int)->String in return String(count:n,repeatedValue:Character(s))};let e={(n:Int)in var w=[String]();w.append(t("_",abs(n)*4));let c = abs(n);let d = n>0 ? "/": "\\";let f = n>0 ? "\\": "/";for var i in 0...abs(n)-1 {w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));};w=n<0 ?w:w.map(){String($0.characters.reverse())};print(w.joinWithSeparator("\n"))}

```

UnGolfed:

```
let t={(s:String,n:Int) -> String in
    return String(count:n,repeatedValue:Character(s))
};
let e={(n:Int) in
    var w=[String]();
    w.append(t("_",abs(n)*4));
    let c = abs(n);
    let d = n>0 ? "/": "\\";
    let f = n>0 ? "\\": "/";
    for var i in 0...abs(n)-1 {
        w.append(t(" ",i)+d+t(" ",c*2-2-(2*i))+f+(i<c-1 ?t(" ",2*c-1)+f:t("_",2*c-1)+f)+(n>0 ?t(" ",i):""));
    };
    w=n<0 ?w:w.map(){String($0.characters.reverse())};
    print(w.joinWithSeparator("\n"))
}

```
> 1 votes

# Answer
# PHP, 143 bytes

```
$t=str_repeat;echo$t(_,4*$s=$k=abs($n=$argv[1]));for(;$k--;$p.=" "){$f=$t("  ",$k);$r=$t($k?" ":_,2*$s-1);echo"
$p\\",$n<0?"$f/$r/":"$r\\$f/";}

```

run with `php -r '<code>' <parameter>`

**breakdown**

```
$t=str_repeat;  // function name to variable saves 10-1 bytes
echo$t(_,4*$s=$k=abs($n=$argv[1])); // print bottom
for(
    ;
    $k--;   // $k from abs($n-1) to 0
    $p.=" "                 // create padding
)
{
    $f=$t("  ",$k);         // create front
    $r=$t($k?" ":_,2*$s-1); // create side/roof
    echo"\n$p\\",$n<0
        ?"$f/$r/"   // print, entrance left
        :"$r\\$f/"  // print, entrance right
    ;
}

```
> 1 votes

# Answer
## Batch, 289 bytes

```
@echo off
set/pn=
set u=
for /l %%i in (2,1,%n:-=%)do call set u=_%%u%%_
echo _%u%__%u%_
set l=
set m=%u%/_%u%
if %n% gtr 0 set m=%u%_\%u%
set m=%m:_= %
for /l %%i in (2,1,%n:-=%)do call:l
set m=%m: =_%
:l
echo %l%\%m%/
set l= %l%
if %n% gtr 0 set m=  %m:~0,-2%
set m=%m:~2%

```

Takes input on STDIN. Starts by creating a string of `2*(abs(n)-1)` underscores. This is then repeated plus an additional 4 underscores for the base of the tent. The rest of the tent then consists of an indent (which increases by 1 on each line), a `\`, the middle of the tent, and a `/`. The middle of the tent starts as `2*(abs(n)-1)` spaces, plus either `\` or `/` plus a space (which I can't represent in Markdown), plus another `2*(abs(n)-1)` spaces. I reuse the underscore string and change them to spaces for convenience, but then change the spaces back to underscores for the last line. Each line removes two spaces from one side of the middle of the tent, although it's slightly golfier to move the two spaces to the start of the string first if necessary.
> 1 votes

# Answer
# Canvas, 25 bytes

```
⤢＼║ｌ╵：╷：«_×╋ｌ／＋Ｌ_×；∔⁸０＞？↔

```

Try it here!
> 1 votes

---
Tags: code-golf, ascii-art, number
---