{-# LANGUAGE MultiWayIf, BangPatterns #-}
import Data. Word
data Tape = Tape { negatives :: [ Word8] , currentTape :: ! Word8, positives :: [ Word8] }
shiftLeft ( Tape ( x:left) curr right) = Tape left x ( curr:right)
shiftRight ( Tape left curr ( x:right) ) = Tape ( curr:left) x right
modifyTape f ( Tape left curr right) = Tape left ( f curr) right
newtype Stack a = Stack [ a]
push x ( Stack s) = Stack ( x:s)
pop ( Stack ( s:ss) ) = Stack ss
evalReal program = eval 0 ( Stack [ 0 ] ) mkTape
where eval ! curr ! loops ! tape = if
| command == '[' -> ( if
| skip || currentTape tape == 0 -> eval ( curr + 1 ) ( push ( - 1 ) loops) tape
| otherwise -> eval
( curr
+ 1 ) ( push curr loops
) tape
) | command == ']' -> ( if
| skip || currentTape tape == 0 -> eval ( curr + 1 ) ( pop loops) tape
| otherwise -> eval
( top loops
+ 1 ) loops tape
) | skip -> nextCommand tape
| command == '+' -> nextCommand ( modifyTape ( + 1 ) tape)
| command
== '-' -> nextCommand
( modifyTape
( subtract 1 ) tape
) | command == '>' -> nextCommand ( shiftRight tape)
| command == '<' -> nextCommand ( shiftLeft tape)
where nextCommand = eval ( curr + 1 ) loops
skip = top loops == ( - 1 )
command = program !! curr
main = evalReal "->+>+++>>+>++>+>+++>>+>++>>>+>+>+>++>+>>>>+++>+>>++>+>+++>>++>++>>+>>+>++>++>+>>>>+++>+>>>>++>++>>>>+>>++>+>+++>>>++>>++++++>>+>>++>+>>>>+++>>+++++>>+>+++>>>++>>++>>+>>++>+>+++>>>++>>+++++++++++++>>+>>++>+>+++>+>+++>>>++>>++++>>+>>++>+>>>>+++>>+++++>>>>++>>>>+>+>++>>+++>+>>>>+++>+>>>>+++>+>>>>+++>>++>++>+>+++>+>++>++>>>>>>++>+>+++>>>>>+++>>>++>+>+++>+>+>++>>>>>>++>>>+>>>++>+>>>>+++>+>>>+>>++>+>++++++++++++++++++>>>>+>+>>>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>>>+++>>++++++>>>+>++>>+++>+>+>++>+>+++>>>>>+++>>>+>+>>++>+>+++>>>++>>++++++++>>+>>++>+>>>>+++>>++++>>+>+++>>>>>>++>+>+++>>+>++>>>>+>+>++>+>>>>+++>>+++>>>+[[->>+<<]<+]+++++[->+++++++++<]>.[+]>>[<<+++++++[->+++++++++<]>-.------------------->-[-<.<+>>]<[+]<+>>>]<<<[-[-[-[>>+<++++++[->+++++<]]>++++++++++++++<]>+++<]++++++[->+++++++<]>+<<<-[->>>++<<<]>[->>.<<]<<]"
ey0jIExBTkdVQUdFIE11bHRpV2F5SWYsIEJhbmdQYXR0ZXJucyAjLX0KCmltcG9ydCBEYXRhLldvcmQKaW1wb3J0IERhdGEuQ2hhcgoKZGF0YSBUYXBlID0gVGFwZSB7IG5lZ2F0aXZlcyA6OiBbV29yZDhdLCBjdXJyZW50VGFwZSA6OiAhV29yZDgsIHBvc2l0aXZlcyA6OiBbV29yZDhdIH0KCm1rVGFwZSA9IFRhcGUgKHJlcGVhdCAwKSAwIChyZXBlYXQgMCkKc2hpZnRMZWZ0ICAoVGFwZSAoeDpsZWZ0KSBjdXJyIHJpZ2h0KSA9IFRhcGUgbGVmdCB4IChjdXJyOnJpZ2h0KQpzaGlmdFJpZ2h0IChUYXBlIGxlZnQgY3VyciAoeDpyaWdodCkpID0gVGFwZSAoY3VycjpsZWZ0KSB4IHJpZ2h0Cm1vZGlmeVRhcGUgZiAoVGFwZSBsZWZ0IGN1cnIgcmlnaHQpID0gVGFwZSBsZWZ0IChmIGN1cnIpIHJpZ2h0CgpuZXd0eXBlIFN0YWNrIGEgPSBTdGFjayBbYV0KCnB1c2ggeCAoU3RhY2sgcykgPSBTdGFjayAoeDpzKQp0b3AgKFN0YWNrIHMpID0gaGVhZCBzCnBvcCAoU3RhY2sgKHM6c3MpKSA9IFN0YWNrIHNzCgpldmFsUmVhbCBwcm9ncmFtID0gZXZhbCAwIChTdGFjayBbMF0pIG1rVGFwZQogIHdoZXJlIGV2YWwgIWN1cnIgIWxvb3BzICF0YXBlID0gaWYKICAgICAgICAgIHwgbGVuZ3RoIHByb2dyYW0gPT0gY3VyciAtPiByZXR1cm4gKCkKICAgICAgICAgIHwgY29tbWFuZCA9PSAnWycgLT4gKGlmCiAgICAgICAgICAgIHwgc2tpcCB8fCBjdXJyZW50VGFwZSB0YXBlID09IDAgLT4gZXZhbCAoY3VyciArIDEpIChwdXNoICgtMSkgbG9vcHMpIHRhcGUKICAgICAgICAgICAgfCBvdGhlcndpc2UgICAgICAgICAgICAgICAgICAgICAtPiBldmFsIChjdXJyICsgMSkgKHB1c2ggY3VyciBsb29wcykgdGFwZSkKICAgICAgICAgIHwgY29tbWFuZCA9PSAnXScgLT4gKGlmCiAgICAgICAgICAgIHwgc2tpcCB8fCBjdXJyZW50VGFwZSB0YXBlID09IDAgLT4gZXZhbCAoY3VyciArIDEpIChwb3AgbG9vcHMpIHRhcGUKICAgICAgICAgICAgfCBvdGhlcndpc2UgICAgICAgICAgICAgICAgICAgICAtPiBldmFsICh0b3AgbG9vcHMgKyAxKSBsb29wcyB0YXBlKQogICAgICAgICAgfCBza2lwIC0+IG5leHRDb21tYW5kIHRhcGUKICAgICAgICAgIHwgY29tbWFuZCA9PSAnKycgLT4gbmV4dENvbW1hbmQgKG1vZGlmeVRhcGUgKCsxKSB0YXBlKQogICAgICAgICAgfCBjb21tYW5kID09ICctJyAtPiBuZXh0Q29tbWFuZCAobW9kaWZ5VGFwZSAoc3VidHJhY3QgMSkgdGFwZSkKICAgICAgICAgIHwgY29tbWFuZCA9PSAnPicgLT4gbmV4dENvbW1hbmQgKHNoaWZ0UmlnaHQgdGFwZSkKICAgICAgICAgIHwgY29tbWFuZCA9PSAnPCcgLT4gbmV4dENvbW1hbmQgKHNoaWZ0TGVmdCB0YXBlKQogICAgICAgICAgfCBjb21tYW5kID09ICcuJyAtPiBwdXRDaGFyIChjaHIgJCBmcm9tSW50ZWdyYWwgJCBjdXJyZW50VGFwZSB0YXBlKSA+PiBuZXh0Q29tbWFuZCB0YXBlCiAgICAgICAgICB8IGNvbW1hbmQgPT0gJywnIC0+IGdldENoYXIgPj49IFx4IC0+IHJldHVybiAodGFwZSB7Y3VycmVudFRhcGUgPSAoZnJvbUludGVncmFsICQgb3JkIHgpfSkgPj4gbmV4dENvbW1hbmQgdGFwZQogICAgICAgICAgfCBvdGhlcndpc2UgLT4gbmV4dENvbW1hbmQgdGFwZQogICAgICAgICAgd2hlcmUgbmV4dENvbW1hbmQgPSBldmFsIChjdXJyICsgMSkgbG9vcHMKICAgICAgICAgICAgICAgIHNraXAgPSB0b3AgbG9vcHMgPT0gKC0xKQogICAgICAgICAgICAgICAgY29tbWFuZCA9IHByb2dyYW0gISEgY3VycgoKbWFpbiA9IGV2YWxSZWFsICItPis+KysrPj4rPisrPis+KysrPj4rPisrPj4+Kz4rPis+Kys+Kz4+Pj4rKys+Kz4+Kys+Kz4rKys+PisrPisrPj4rPj4rPisrPisrPis+Pj4+KysrPis+Pj4+Kys+Kys+Pj4+Kz4+Kys+Kz4rKys+Pj4rKz4+KysrKysrPj4rPj4rKz4rPj4+PisrKz4+KysrKys+Pis+KysrPj4+Kys+PisrPj4rPj4rKz4rPisrKz4+PisrPj4rKysrKysrKysrKysrPj4rPj4rKz4rPisrKz4rPisrKz4+PisrPj4rKysrPj4rPj4rKz4rPj4+PisrKz4+KysrKys+Pj4+Kys+Pj4+Kz4rPisrPj4rKys+Kz4+Pj4rKys+Kz4+Pj4rKys+Kz4+Pj4rKys+PisrPisrPis+KysrPis+Kys+Kys+Pj4+Pj4rKz4rPisrKz4+Pj4+KysrPj4+Kys+Kz4rKys+Kz4rPisrPj4+Pj4+Kys+Pj4rPj4+Kys+Kz4+Pj4rKys+Kz4+Pis+PisrPis+KysrKysrKysrKysrKysrKysrPj4+Pis+Kz4+Pis+PisrPis+KysrPj4+Kys+PisrKysrKysrPj4rPj4rKz4rPj4+PisrKz4+KysrKysrPj4+Kz4rKz4+KysrPis+Kz4rKz4rPisrKz4+Pj4+KysrPj4+Kz4rPj4rKz4rPisrKz4+PisrPj4rKysrKysrKz4+Kz4+Kys+Kz4+Pj4rKys+PisrKys+Pis+KysrPj4+Pj4+Kys+Kz4rKys+Pis+Kys+Pj4+Kz4rPisrPis+Pj4+KysrPj4rKys+Pj4rW1stPj4rPDxdPCtdKysrKytbLT4rKysrKysrKys8XT4uWytdPj5bPDwrKysrKysrWy0+KysrKysrKysrPF0+LS4tLS0tLS0tLS0tLS0tLS0tLS0tPi1bLTwuPCs+Pl08WytdPCs+Pj5dPDw8Wy1bLVstWz4+KzwrKysrKytbLT4rKysrKzxdXT4rKysrKysrKysrKysrKzxdPisrKzxdKysrKysrWy0+KysrKysrKzxdPis8PDwtWy0+Pj4rKzw8PF0+Wy0+Pi48PF08PF0i